====== DokuWiki Plugin: phpinc ====== ---- plugin ---- description: This plugin allows you to include a PHP/HTML file into your wikipage. author : Markus Frosch email : markus@lazyfrosch.de type : syntax lastupdate : 2006-05-11 compatible : depends : conflicts : similar : incl_form tags : php, html ---- ===== The idea ===== Instead of writing PHP code directly into the wikipage, which is very insecure in my opinion, you can include a PHP file in a special directory in the installation directory of DokuWiki. So the serveradmin can define which dynamic content can be loaded! Only files in /phpincludes in your DokuWiki installation can be included! The included scripts are given the $_GET, $_POST, and $_REQUEST superglobals to play with, plus access to the [[devel:Common Plugin Functions]]. What they output via $stdout is passed unmangled to the end user. ===== Requirements ===== I've developed the plugin under 2006-03-09 and it should work in any future release! ===== Download / Installation ===== Here you can download phpinc: [[http://devel.lazyfrosch.de/dokuwiki/dokuwiki-phpinc-20060703.tar.gz]] I didn't test the installation via the plugin manager, but it should work! Installation is very simple: * Create the directory "phpinc" in the plugin directory * Create the file "syntax.php" and paste the source code in * Create the directory "phpincludes" in the root directory of your DokuWiki Installation ===== Syntax ===== The Syntax is very simple:\\ ===== Sourcecode ===== Here is the sourcecode. Feel free to improve it, but please inform me! :-) * Release 20060511 - initial release * Release 20060703 - ability to use sub-directories in the includes directory (see also comment below) * * The syntax includes the PHP file per include an puts the result into * the wiki page. * * @license GNU_GPL_v2 * @author Markus Frosch */ if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); require_once(DOKU_PLUGIN.'syntax.php'); class syntax_plugin_phpinc extends DokuWiki_Syntax_Plugin { function getInfo(){ return array( 'author' => 'Markus Frosch', 'email' => 'markus@lazyfrosch.de', 'date' => '2006-05-11', 'name' => 'PHP Include', 'desc' => 'Allows you to make an include of an PHP File on Server', 'url' => 'http://www.dokuwiki.org/plugin:phpinc', ); } function getType(){ return 'container'; } function getPType(){ return 'normal'; } function getAllowedTypes() { return array('substition','protected','disabled'); } function getSort(){ return 195; } function connectTo($mode) { $this->Lexer->addSpecialPattern('',$mode,'plugin_phpinc'); } function handle($match, $state, $pos, &$handler){ switch ($state) { case DOKU_LEXER_SPECIAL : return array($state, $match); default: return array($state); } } function render($mode, &$renderer, $indata) { if($mode == 'xhtml'){ list($state, $data) = $indata; switch ($state) { case DOKU_LEXER_SPECIAL : preg_match("#^$#", $data, $matches); $file = $matches[1]; if(preg_match("#^[a-z0-9\-_ \./]+$#i", $file) and strstr("..", $file) == false and file_exists(DOKU_INC."phpincludes/".$file)) { $renderer->info['cache'] = FALSE; ob_start(); include(DOKU_INC."phpincludes/".$file); $content = ob_get_contents(); ob_end_clean(); $renderer->doc .= $content; } else $renderer->doc .= $renderer->_xmlEntities($data); break; } return true; } // unsupported $mode return false; } } ?> ===== Credits ===== The plugin was developed by Markus Frosch [[markus@lazyfrosch.de]] for the internal DokuWiki of the [[http://www.ip-exchange.de|IP-Exchange GmbH]]. Many thanks to the developers of DokuWiki! It's a great software! And also many thanks to the developers of the [[plugin:note|note plugin]] your plugin helped me on the first steps to build this plugin! ===== Comments ===== Feel free to add your comments and suggestions here! ---- You did a good work! I had similar code prepared ;-) -- some difference: I look for the included files in data/media/phpincludes, so that they can be uploaded like any media file. And I expect a function doOutput() in the included file, so you have less restrictions than I have :-) Maybe you could give a hint what the included files should look like. As far as I see, the included file does its output via echo or sprintf() or whatever ;-), this output is captured and merged into the XHTML code of the page. You do not call a function inside the file, but you let the file be parsed by DokuWiki's PHP abilities, so that one may use the built-in variables of DokuWiki. Is this correct? -- [[w.flamme@web.de|Werner]] 2006-05-12 ---- Thank you! My idea was to forbid custom PHP code for the users, so only the sysadmin is able to insert scripts. Because when a user can upload scripts this will be very similar to the syntax. The files should be standard PHP scripts with echo output, the output should be normal XHTML code, you are right. Yeah you can use DokuWiki's internal variables. The plugin is not made to protect DokuWiki, it's only made for the sysadmins. :-) My company uses this plugin for inserting special data into the wikipages. The user can edit pages, but he's not able to use custom PHP code. --- //[[markus@lazyfrosch.de|Markus Frosch]] 2006-05-14 17:47// ---- A user contacted me via mail and told me he extended the Regular Expression for the filename with a "/", so subdirectories can be used in the phpincludes directory. I've agreed with that and updated my script, but I also made an improvement to the idea. I added a protection, that no ".." can be used in the file name, so no file outside the phpincludes directory can be accessed. --- //[[markus@lazyfrosch.de|Markus Frosch]] 2006-07-03 17:50// ---- Syntax comment: The //tag// syntax '''' is a bit non-conforming to other DokuWiki syntax. All the built in tag constructions (sub, sup, del, nowiki, file, code, html, php) have endtags, i.e. %%...%%. Have you considered using curly brackets, ''{{phpinc>myfile.php}}'' instead? --- //[[viktro@bigfoot.com|Viktor]] 2006-10-15 00:12// I agree, the syntax should be ''{{phpinc>myfile.php}}''. I prefer ''{{include>myfile.php}}'' : more simple and intuitive. Here's the modified version, working with ''{{include>myfile.php}}''. --- //Emmanuel 2007-12-01// * * The syntax includes the PHP file per include an puts the result into * the wiki page. * * @license GNU_GPL_v2 * @author Markus Frosch */ if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); require_once(DOKU_PLUGIN.'syntax.php'); class syntax_plugin_phpinc extends DokuWiki_Syntax_Plugin { function getInfo(){ return array( 'author' => 'Markus Frosch', 'email' => 'markus@lazyfrosch.de', 'date' => '2006-05-11', 'name' => 'PHP Include', 'desc' => 'Allows you to make an include of an PHP File on Server', 'url' => 'http://www.dokuwiki.org/plugin:phpinc', ); } function getType(){ return 'container'; } function getPType(){ return 'normal'; } function getAllowedTypes() { return array('substition','protected','disabled'); } function getSort(){ return 195; } function connectTo($mode) { $this->Lexer->addSpecialPattern('{{include>.*?}}',$mode,'plugin_phpinc'); } function handle($match, $state, $pos, &$handler){ switch ($state) { case DOKU_LEXER_SPECIAL : return array($state, $match); default: return array($state); } } function render($mode, &$renderer, $indata) { if($mode == 'xhtml'){ list($state, $data) = $indata; switch ($state) { case DOKU_LEXER_SPECIAL : preg_match("#^{{include>(.+)}}$#", $data, $matches); $file = $matches[1]; if(preg_match("#^[a-z0-9\-_ \./]+$#i", $file) and strstr("..", $file) == false and file_exists(DOKU_INC."phpincludes/".$file)) { $renderer->info['cache'] = FALSE; ob_start(); include(DOKU_INC."phpincludes/".$file); $content = ob_get_contents(); ob_end_clean(); $renderer->doc .= $content; } else $renderer->doc .= $renderer->_xmlEntities($data); break; } return true; } // unsupported $mode return false; } } ?> ---- General comment: Is there a possibility to parse DokuWiki syntax created by the included PHP file? I read the api doku and found some render, handle and other functions, but couldn't get it working. I want to generate tables or other stuff using the wikisyntax and then call a parser which processes the output. --- //[[petz@boczki.de|Petz]] 2006-11-14 12:56// > You can use normal HTML table tags with the inline class from DokuWiki. > I use following code to print out ORACLE tables in DokuWiki - haedae echo ''; while ($row = oci_fetch_array($s, OCI_RETURN_NULLS)) { echo ''; } echo "
IPAIDTYPETIMESeverityConditionDescription
'.$row[0].' '.$row[1].' '.$row[2].' '.$row[3].' '.$row[4].' '.$row[5].' '.$row[6].'
";
---- If you for some reason don't want people to be able to snoop around in the ''/phpincludes/'' folder and are using Apache with the proper privileges. You can add a ''.htaccess'' file to the folder with the following content: order allow,deny deny from all Keeps people from listing the files of that folder and executing them directly. It might also be worth considering to move the folder out of your web accessible folders. Just remember to edit the plugin so it knows where to look if you do the latter. --- //[[zyberdog@quakenet.org|David Lorentsen]] 2007-01-16 11:36// ---- Can I ask a stupid question ... **where** do I put --- // MD 2007-02-04 05:36// > If I understand it correctly, you can put it everywhere in every wikipage you want. You may put it below a heading to include some scriptings. But it totally depends on your purpose and the included file. --- //[[emodul@gmx.net|eModul]] 2007-04-03 01:03// ---- Excellent plugin, thanks for sharing. I've added a small bit that allows the use of 1 parameter to be passed in the filename.php?var=something manner. I'm more of a PHP-coder than a PHP-programmer so there's probably room for code compaction: * * The syntax includes the PHP file per include an puts the result into * the wiki page. * * @license GNU_GPL_v2 * @author Markus Frosch */ if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); require_once(DOKU_PLUGIN.'syntax.php'); class syntax_plugin_phpinc extends DokuWiki_Syntax_Plugin { function getInfo(){ return array( 'author' => 'Markus Frosch', 'email' => 'markus@lazyfrosch.de', 'date' => '2006-05-11', 'name' => 'PHP Include', 'desc' => 'Allows you to make an include of an PHP File on Server', 'url' => 'http://www.dokuwiki.org/plugin:phpinc', ); } function getType(){ return 'container'; } function getPType(){ return 'normal'; } function getAllowedTypes() { return array('substition','protected','disabled'); } function getSort(){ return 195; } function connectTo($mode) { $this->Lexer->addSpecialPattern('',$mode,'plugin_phpinc'); } function handle($match, $state, $pos, &$handler){ switch ($state) { case DOKU_LEXER_SPECIAL : return array($state, $match); default: return array($state); } } function render($mode, &$renderer, $indata) { if($mode == 'xhtml'){ list($state, $data) = $indata; switch ($state) { case DOKU_LEXER_SPECIAL : preg_match("#^$#", $data, $matches); $file = $matches[1]; $file_ = substr($file,0,stripos($file,'.php')+4); $question = substr($file,stripos($file,'=')+1); // if(preg_match("#^[a-z0-9\-_ \./]+$#i", $file) and strstr("..", $file) == false and file_exists(DOKU_INC."phpincludes/".$file)) { if(preg_match("#^[a-z0-9\-_ \./\?\=]+$#i", $file) and strstr("..", $file) == false and file_exists(DOKU_INC."phpincludes/".$file_)) { $renderer->info['cache'] = FALSE; ob_start(); $_GET['var'] = $question; include(DOKU_INC."phpincludes/".$file_); $content = ob_get_contents(); ob_end_clean(); $renderer->doc .= $content; } else $renderer->doc .= $renderer->_xmlEntities($data); break; } return true; } // unsupported $mode return false; } } ?> --- Hi, please give an example of use for those of us who can't read regular expressions... Thanks for sharing ! > suppose your phpfile is test.php, use this syntax: > > > Whatever you use as postname (in the examples "variable" and "hihi"), it gets transformed to "var", so inside your phpscript you use something like if(isset('var')) $input = $_GET['var']; Here's a little extra on this last modification... forms. If you add this on a page... ... you'll get a text field and button that takes the search as postvariable for the phpincluded php script. \\ Demo: [[http://wiki.terrorchid.org/map:map|terrorchid wiki]]... enter "disa" or "Epipactis" ---- > Here's an idea. wiki editors don't want long repetetive words or words that refer to a programming environment... > so instead of use the expression > you replace "phpinc=" by "do:" and ".php?" by "", they're always the same so why bother typing them in ? > This way you won't give the casual editor the idea he's about to launch a technical thing with scripts > and other stuff he rather has nothing to do with ... we're programmers and have a natural liking and feel for > this stuff, but 99 % of the visitors think twice before typing that in -- Fred ---- > Wollte einfach nur ein Kompliment hinterlassen! -- Bernd ---- . Just got to know DokuWiki and I love it! Looking for plugins to make things perfect I stumbled over PHPinc and it's just the missing link. I like this charming simplicity LOL Though it might be syntactic more right I prefer the sytax (maybe because I'm still new to DokuWiki syntax and this looks more familiar). Inspired by the comments here I added four lines to Markus' original code to "parse" variables to the php. And I'm lazy like Fred. My ''function render()'' looks like this (with my additions marked by +++++) function render($mode, &$renderer, $indata){ if($mode == 'xhtml'){ list($state, $data) = $indata; switch ($state) { case DOKU_LEXER_SPECIAL : preg_match("#^$#", $data, $matches); $file = $matches[1]; +++++ $a = explode('?', $file); +++++ $file = $a[0].'.php'; // here's where the .php extention goes in +++++ if (!empty($a[1])) { parse_str($a[1], $query); } +++++ else { $query = ''; } if(preg_match("#^[a-z0-9\-_\./]+$#i", $file) and strstr("..", $file) == false and file_exists(DOKU_INC."phpincludes/".$file)) { $renderer->info['cache'] = FALSE; ob_start(); include(DOKU_INC."phpincludes/".$file); $content = ob_get_contents(); ob_end_clean(); $renderer->doc .= $content; } else $renderer->doc .= $renderer->_xmlEntities($data); break; } return true; } No further changes in the plugin required. This results in: * no need for ''.php'' extention (only filename will do) * querystring is stored as an array in ''$query'' which is in the scope of the included file Extended syntax: '''' It might be a good idea to start the included php script with checking the vars: if ( count($query) == ## // count for sufficient number of elements && array_key_exists('var1', $query) // check for needed vars && array_key_exists('var2', $query) ) { ..... Cheers and thanks again! //Henk-Sjoerd --- 2008-10-29 --- Running DokuWiki 2008-05-05// ---- For both the monobook and sidebar themes, using phpinc messes up the sidebar column formatting, pushing the content below the main column in monobook and placing the footer on top in the sidebar theme. This is in Forefox 3. Do you have any fixes for this? thanks //skarred --- 2008-10-29// ---