xref: /plugin/embeddedphp/syntax/phpinline.php (revision 14c252b2eb544b8e5f0061a31c71b9ac31e21539)
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	 * Return the plugin Lexer mode
37	 *
38	 * @return string
39	 */
40	protected function getPluginModeName(): string
41	{
42		return 'plugin_'.$this->getPluginName().'_'.$this->getPluginComponent();
43	}
44
45	/** @inheritDoc */
46	public function connectTo($mode)
47	{
48		$p = '<'.$this->GetTag().'\b>(?=.*?</'.$this->GetTag().'>)';
49		$m = $this->getPluginModeName();
50		$this->Lexer->addEntryPattern($p, $mode, $m);
51	}
52
53	/** @inheritDoc */
54	public function postConnect()
55	{
56		$p = '</'.$this->GetTag().'>';
57		$m = $this->getPluginModeName();
58		$this->Lexer->addExitPattern($p, $m);
59	}
60
61	/** @inheritDoc */
62	public function handle($match, $state, $pos, Doku_Handler $handler)
63	{
64		global $INPUT;
65
66		// If we are parsing a submitted comment. Executing embedded PHP in comments is
67		// not a good idea!
68		if ($INPUT->has('comment')) {
69			return false;
70		}
71
72		switch($state) {
73			case DOKU_LEXER_UNMATCHED :
74				// Return the data needed in $this->render() as an array:
75				return [$state, $match];
76		}
77
78		return false;
79	}
80
81	/** @inheritDoc */
82	public function render($mode, Doku_Renderer $renderer, $data)
83	{
84		if ($mode === 'xhtml') {
85			if (is_array($data) && (count($data) > 1)) {
86				$this->php($data[1], $renderer);
87
88				return true;
89			}
90		}
91
92		return false;
93	}
94
95	/**
96	 * Determine whether embedding PHP code is allowed
97	 *
98	 * @return	bool	true if executing embedded PHP code is allowed
99	 */
100	protected function allowEmbedding(): bool
101	{
102		$allow = ($this->getConf('embedphpok') == 1) &&
103				 ($this->getConf('privatewiki') == 1);
104
105		return $allow;
106	}
107
108	/**
109	 * Execute PHP code if allowed
110	 *
111	 * @param  string $text				 PHP code that is either executed or printed
112	 * @param  Doku_Renderer $renderer	 Renderer used for output
113	 */
114	protected function php($text, Doku_Renderer $renderer): void
115	{
116		if ($this->allowEmbedding()) {
117			ob_start();
118			eval($text);
119			$o = ob_get_contents();
120			if (!empty($o)) {
121				if ($this->isBlockElement()) {
122					$renderer->doc .= '<div class="embeddedphp">'.$o.'</div>';
123				} else {
124					$renderer->doc .= '<span class="embeddedphp">'.$o.'</span>';
125				}
126			}
127			ob_end_clean();
128		} else {
129			$wrapper = $this->isBlockElement() ? 'pre' : 'code';
130			$renderer->doc .= /*'###.get_class($this)'.*/p_xhtml_cached_geshi($text, 'php', $wrapper);
131		}
132	}
133
134	/**
135	 * Generic test to differentiate between inline and block modes
136	 *
137	 * @return bool true if this generates a block element, false otherwise.
138	 */
139	protected function isBlockElement(): bool
140	{
141		return false;
142	}
143}
144
145