xref: /plugin/embeddedphp/syntax/phpinline.php (revision d3666e41f8c4f409eb28c2f6cecc748440f90581)
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	/**
22	 * Return the exit pattern as we need this more than once
23	 *
24	 * @return string
25	 */
26	protected function GetExitPattern(): string
27	{
28		return '</'.$this->GetTag().'>';
29	}
30
31	/** @inheritDoc */
32	public function getType()
33	{
34		return 'protected';
35	}
36
37	/** @inheritDoc */
38	public function getSort()
39	{
40		// The default <php>/<PHP> handler up to "Igor" has priority 180. By setting a
41		// lower priority we override the built-in functionality.
42		return 179;
43	}
44
45
46	/*
47	 * Return the plugin Lexer mode
48	 * This works fine for most trivial cases. But some plugins
49	 * may need to override this method.
50	 *
51	 * @return string
52	 */
53	protected function getPluginModeName(): string
54	{
55		$x = ['plugin',
56			  $this->getPluginName(),
57			  $this->getPluginComponent()];	//	If component is empty it will be filtered later.
58
59		return implode('_', array_filter($x));
60	}
61
62	/** @inheritDoc */
63	public function connectTo($mode)
64	{
65		$p = '<'.$this->GetTag().'\b>(?=.*?'.$this->GetExitPattern().')';
66		$m = $this->getPluginModeName();
67		$this->Lexer->addEntryPattern($p, $mode, $m);
68	}
69
70	/** @inheritDoc */
71	public function postConnect()
72	{
73		$m = $this->getPluginModeName();
74		$this->Lexer->addExitPattern('.*?'.$this->GetExitPattern(), $m);
75	}
76
77	/** @inheritDoc */
78	public function handle($match, $state, $pos, Doku_Handler $handler)
79	{
80		global $INPUT;
81
82		// If we are parsing a submitted comment. Executing embedded PHP in comments is
83		// not a good idea!
84		if ($INPUT->has('comment')) {
85			return false;
86		}
87
88		switch($state) {
89			case DOKU_LEXER_EXIT:
90				return [$state, substr($match, 0, -strlen($this->GetExitPattern()))];
91		}
92
93		return false;
94	}
95
96	/** @inheritDoc */
97	public function render($mode, Doku_Renderer $renderer, $data)
98	{
99		if ($mode === 'xhtml') {
100			if (is_array($data)) {
101				@[$state, $phpsource] = $data;
102				switch($state) {
103					case DOKU_LEXER_EXIT:
104						$this->php($phpsource, $renderer);
105
106						return true;
107				}
108			}
109		}
110
111		return false;
112	}
113
114	/**
115	 * Determine whether embedding PHP code is allowed
116	 *
117	 * @return	bool	true if executing embedded PHP code is allowed
118	 */
119	protected function allowEmbedding(): bool
120	{
121		$allow = ($this->getConf('embedphpok') == 1) &&
122				 ($this->getConf('privatewiki') == 1);
123
124		return $allow;
125	}
126
127	/**
128	 * Execute PHP code if allowed
129	 *
130	 * @param  string $phpsource		 PHP code that is either executed or printed
131	 * @param  Doku_Renderer $renderer	 Renderer used for output
132	 */
133	protected function php($phpsource, Doku_Renderer $renderer): void
134	{
135		if ($this->allowEmbedding()) {
136			ob_start();
137			eval($phpsource);
138			$o = ob_get_contents();
139			if (!empty($o)) {
140				if ($this->isBlockElement()) {
141					$renderer->doc .= '<div class="embeddedphp">'.$o.'</div>';
142				} else {
143					$renderer->doc .= '<span class="embeddedphp">'.$o.'</span>';
144				}
145			}
146			ob_end_clean();
147		} else {
148			$wrapper = $this->isBlockElement() ? 'pre' : 'code';
149			$renderer->doc .= /*'###.get_class($this)'.*/p_xhtml_cached_geshi($phpsource, 'php', $wrapper);
150		}
151	}
152
153	/**
154	 * Generic test to differentiate between inline and block modes
155	 *
156	 * @return bool true if this generates a block element, false otherwise.
157	 */
158	protected function isBlockElement(): bool
159	{
160		return false;
161	}
162}
163
164