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