xref: /plugin/embeddedphp/syntax/phpinline.php (revision 144f9a0a16c6cda2669a4c3bf22f24e08599dc0f) !
1<?php
2/**
3 * DokuWiki Plugin embeddedphp (Syntax Component)
4 *
5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6 * @author	fiwswe <dwplugin@fwml.de>
7 */
8
9class syntax_plugin_embeddedphp_phpinline extends \dokuwiki\Extension\SyntaxPlugin
10{
11	/**
12	 * Return the tag this plugin instance reacts to
13	 *
14	 * @return string
15	 */
16	protected function GetTag(): string
17	{
18		return 'php';
19	}
20
21	/** @inheritDoc */
22	public function getType()
23	{
24		return 'protected';
25	}
26
27	/** @inheritDoc */
28	public function getSort()
29	{
30		// The default <php>/<PHP> handler up to "Igor" has priority 180. By setting a
31		// lower priority we override the built-in functionality.
32		return 179;
33	}
34
35
36	/*
37	 * Return the plugin Lexer mode
38	 * This works fine for most trivial cases. But some plugins
39	 * may need to override this method.
40	 *
41	 * @return string
42	 */
43	protected function getPluginModeName(): string
44	{
45		$x = ['plugin',
46			  $this->getPluginName(),
47			  $this->getPluginComponent()];	//	If component is empty it will be filtered later.
48
49		return implode('_', array_filter($x));
50	}
51
52	/** @inheritDoc */
53	public function connectTo($mode)
54	{
55		$p = '<'.$this->GetTag().'\b>(?=.*?</'.$this->GetTag().'>)';
56		$m = $this->getPluginModeName();
57		$this->Lexer->addEntryPattern($p, $mode, $m);
58	}
59
60	/** @inheritDoc */
61	public function postConnect()
62	{
63		$p = '</'.$this->GetTag().'>';
64		$m = $this->getPluginModeName();
65		$this->Lexer->addExitPattern($p, $m);
66	}
67
68	/** @inheritDoc */
69	public function handle($match, $state, $pos, Doku_Handler $handler)
70	{
71		global $INPUT;
72
73		// If we are parsing a submitted comment. Executing embedded PHP in comments is
74		// not a good idea!
75		if ($INPUT->has('comment')) {
76			return false;
77		}
78
79		switch($state) {
80			case DOKU_LEXER_UNMATCHED :
81				// Return the data needed in $this->render() as an array:
82				return [$state, $match];
83		}
84
85		return false;
86	}
87
88	/** @inheritDoc */
89	public function render($mode, Doku_Renderer $renderer, $data)
90	{
91		if ($mode === 'xhtml') {
92			if (is_array($data) && (count($data) > 1)) {
93				$this->php($data[1], $renderer);
94
95				return true;
96			}
97		}
98
99		return false;
100	}
101
102	/**
103	 * Determine whether embedding PHP code is allowed
104	 *
105	 * @return	bool	true if executing embedded PHP code is allowed
106	 */
107	protected function allowEmbedding(): bool
108	{
109		$allow = ($this->getConf('embedphpok') == 1) &&
110				 ($this->getConf('privatewiki') == 1);
111
112		return $allow;
113	}
114
115	/**
116	 * Execute PHP code if allowed
117	 *
118	 * @param  string $text				 PHP code that is either executed or printed
119	 * @param  Doku_Renderer $renderer	 Renderer used for output
120	 */
121	protected function php($text, Doku_Renderer $renderer): void
122	{
123		if ($this->allowEmbedding()) {
124			ob_start();
125			eval($text);
126			$o = ob_get_contents();
127			if (!empty($o)) {
128				if ($this->isBlockElement()) {
129					$renderer->doc .= '<div class="embeddedphp">'.$o.'</div>';
130				} else {
131					$renderer->doc .= '<span class="embeddedphp">'.$o.'</span>';
132				}
133			}
134			ob_end_clean();
135		} else {
136			$wrapper = $this->isBlockElement() ? 'pre' : 'code';
137			$renderer->doc .= /*'###.get_class($this)'.*/p_xhtml_cached_geshi($text, 'php', $wrapper);
138		}
139	}
140
141	/**
142	 * Generic test to differentiate between inline and block modes
143	 *
144	 * @return bool true if this generates a block element, false otherwise.
145	 */
146	protected function isBlockElement(): bool
147	{
148		return false;
149	}
150}
151
152