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