Render a block if a condition is fulfilled, user custom tests can be easily added
Compatible with DokuWiki
No compatibility info given!
This extension has not been updated in over 2 years. It may no longer be maintained or supported and may have compatibility issues.
Security warning (please read plugin security guidelines): Hiding parts of a DokuWiki page is not supported by the core. Most attempts to introduce ACL control for parts of a page will leak information through RSS feed, search or other core functionality.
Similar to ifauth, ifauthex, isauth, nodisp, showif, variants
Replace curly brackets string indices with square brackets in line 84 and 149 of
plugins/condition/syntax.php
if you run your webserver with PHP 8.
The Syntax Plugin allows to parse a content only if a specific condition (or multiple condition) is fulfilled. Some basic tests are provided and users can add new tests just by implementing a file in the template directory.
<if [condition_list]>doku code</if> or <if [condition_list]>doku code<else>doku code</if>
[condition_list]
is a set of [condition]
records separated by logical operators (&&, and, ||, or, ^, xor for now)
, use of parenthesis is allowed, negation is achieved by using heading !
(ex !foo=bar or !(a=b || c<d) )
[condition]
is formed from a [key]
, followed by an [operator]
(optional) and then a [value]
(optional)
[key]
is in the list (defined in base_tester.php as of 2009/09/15):
user
: refers to the user “login” (like in $_SERVER['REMOTE_USER']
)group
: refers to the user group-setnsread
: refers to the ability of the user to read a namespacensedit
: refers to the ability of the user to edit a namespacetime
: refers to the current server timeIP
: refers to the client's IP address
[operator]
signification is [key]
dependent, for example:
=
or ==
: equality, membership, read/edit ability on…!=
: non-equality, non-member, no read/edit ability on…(browse base_tester.php for test_* methods for more information)
[value]
can be a string (whitespace, ) and > free) or a " delimited string (whitespaces, ) and > are then allowed)
DokuWiki code can contain DokuWiki syntax but be careful with high-level syntax (containers, table …) as there may be priority issue, bug reports are welcome…
It is now sure that using the plugin inside a table cell won't work, working on it now, any help is welcome…
Example:
<if user>You are **connected**<else>You must identify yourself to do something</if> <if group!=manager>You are not a manager</if> <if time=31d12m>It's New Year's Eve</if> <if IP~=192.168>You are in a local network</if> <if !(group=admin || group=manager)>not VIP</if> (equivalent of <if !group=admin && !group=manager>not VIP</if>) ...
Search and install the plugin using the Extension Manager. Refer to Plugins on how to install plugins manually.
Attention: there is also a third-party source at GitHub
<?php /** * Condition Plugin: render a block if a condition if fulfilled * * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * @author Etienne Meleard <etienne.meleard@free.fr> * * 2009/06/08 : Creation * 2009/06/09 : Drop of the multi-value tests / creation of tester class system * 2009/06/10 : Added tester class override to allow user to define custom tests * 2009/09/15 : Added better renderer handling with respect of conditions for TOC generation */ 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'); /** * All DokuWiki plugins to extend the parser/rendering mechanism * need to inherit from this class */ class syntax_plugin_condition extends DokuWiki_Syntax_Plugin { // To be used by _processblocks to mix the test results together var $allowedoperators = array('\&\&', '\|\|', '\^', 'and', 'or', 'xor'); // plus '!' specific operator // Allowed test operators, their behavior is defined in the tester class, they are just defined here for recognition during parsing var $allowedtests = array(); // Allowed test keys var $allowedkeys = array(); // To store the tester object private $tester = null; // return some info function getInfo() { return confToHash(dirname(__FILE__).'/INFO'); } /*function accepts($mode) { return true; } function getAllowedTypes() { return array('container', 'baseonly', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs'); // quick hack }*/ function getType() { return 'container';} function getPType() { return 'normal';} function getSort() { return 5; } // condition is top priority // Connect pattern to lexer function connectTo($mode){ $this->Lexer->addEntryPattern('<if(?=.*?</if>)', $mode, 'plugin_condition'); } function postConnect() { $this->Lexer->addExitPattern('</if>', 'plugin_condition'); } // Handle the match function handle($match, $state, $pos, Doku_Handler $handler) { if($state != DOKU_LEXER_UNMATCHED) return false; // Get allowed test operators $this->_loadtester(); if(!$this->tester) return array(array(), ''); $this->allowedtests = $this->tester->getops(); $this->allowedkeys = $this->tester->getkeys(); $blocks = array(); $content = ''; $this->_parse($match, $blocks, $content); return array($blocks, $content); } // extracts condition / content function _parse(&$match, &$b, &$ctn) { $match = preg_replace('`^\s+`', '', $match); // trim heading whitespaces $b = $this->_fetch_block($match, 0); if($match != '') $ctn = preg_replace('`\n+$`', '', preg_replace('`^\n+`', '', preg_replace('`^>`', '', $match))); return true; } // fetch a condition block from buffer function _fetch_block(&$match, $lvl=0) { $match = preg_replace('`^\s+`', '', $match); // trim heading whitespaces $instrs = array(); $continue = true; while(($match{0} != '>') && ($match != '') && (($lvl == 0) || ($match{0} != ')')) && $continue) { $i = array('type' => null, 'key' => '', 'test' => '', 'value' => '', 'next' => ''); if($this->_fetch_op($match, true)) { // ! heading equals block descending for first token $i['type'] = 'nblock'; $match = substr($match, 1); // remove heading ! $i['value'] = $this->_fetch_block($match, $lvl+1); }else if($this->_is_block($match)) { $i['type'] = 'block'; $match = substr($match, 1); // remove heading ( $i['value'] = $this->_fetch_block($match, $lvl+1); }else if($this->_is_key($match, $key)) { $i['type'] = 'test'; $i['key'] = $key; $match = substr($match, strlen($key)); // remove heading key if($this->_is_test($match, $test)) { $i['test'] = $test; $match = substr($match, strlen($test)); // remove heading test if(($v = $this->_fetch_value($match)) !== null) $i['value'] = $v; } }else $match = preg_replace('`^[^>\s\(]+`', '', $match); // here dummy stuff remains if($i['type']) { if(($op = $this->_fetch_op($match, false)) !== null) { $match = substr($match, strlen($op)); // remove heading op $i['next'] = $op; }else $continue = false; $instrs[] = $i; } } return $instrs; } // test if buffer starts with new sub-block function _is_block(&$match) { $match = preg_replace('`^\s+`', '', $match); // trim heading whitespaces return preg_match('`^\(`', $match); } // test if buffer starts with a key ref function _is_key(&$match, &$key) { $match = preg_replace('`^\s+`', '', $match); // trim heading whitespaces if(preg_match('`^([a-zA-Z0-9_-]+)`', $match, $r)) { if(preg_match('`^'.$this->_preg_build_alternative($this->allowedkeys).'$`', $r[1])) { $key = $r[1]; return true; } } return false; } // build a pcre alternative escaped test from array function _preg_build_alternative($choices) { //$choices = array_map(create_function('$e', 'return preg_replace(\'`([^a-zA-Z0-9])`\', \'\\\\\\\\$1\', $e);'), $choices); return '('.implode('|', $choices).')'; } // tells if buffer starts with a test operator function _is_test(&$match, &$test) { $match = preg_replace('`^\s+`', '', $match); // trim heading whitespaces if(preg_match('`^'.$this->_preg_build_alternative($this->allowedtests).'`', $match, $r)) { $test = $r[1]; return true; } return false; } // fetch value from buffer, handles value quoting function _fetch_value(&$match) { $match = preg_replace('`^\s+`', '', $match); // trim heading whitespaces if($match{0} == '"') { $match = substr($match, 1); $value = substr($match, 0, strpos($match, '"')); $match = substr($match, strlen($value) + 1); }else{ $psp = strpos($match, ')'); $wsp = strpos($match, ' '); $esp = strpos($match, '>'); $sp = 0; $bug = false; if(($wsp === false) && ($esp === false) && ($psp === false)) { return null; // BUG }else if(($wsp === false) && ($esp === false)) { $sp = $psp; }else if(($wsp === false) && ($psp === false)) { $sp = $esp; }else if(($psp === false) && ($esp === false)) { $sp = $wsp; }else if($wsp === false) { $sp = min($esp, $psp); }else if($esp === false) { $sp = min($wsp, $psp); }else if($psp === false) { $sp = min($esp, $wsp); }else $sp = min($wsp, $esp, $psp); $value = substr($match, 0, $sp); $match = substr($match, strlen($value)); } return $value; } // fetch a logic operator from buffer function _fetch_op(&$match, $head=false) { $match = preg_replace('`^\s+`', '', $match); // trim heading whitespaces $ops = $this->allowedoperators; if($head) $ops = array('!'); if(preg_match('`^'.$this->_preg_build_alternative($ops).'`', $match, $r)) return $r[1]; return null; } /** * Create output */ function render($mode, Doku_Renderer $renderer, $data) { global $INFO; if(count($data) != 2) return false; if($mode == 'xhtml') { global $ID; // prevent caching to ensure good user data detection for tests $renderer->info['cache'] = false; $blocks = $data[0]; $content = $data[1]; // parsing content for a <else> statement $else = ''; if(strpos($content, '<else>') !== false) { $i = explode('<else>', $content); $content = $i[0]; $else = implode('', array_slice($i, 1)); } // Process condition blocks $bug = false; $this->_loadtester(); $ok = $this->_processblocks($blocks, $bug); // Render content if all went well $toc = $renderer->toc; if(!$bug) { $instr = p_get_instructions($ok ? $content : $else); foreach($instr as $instruction) { call_user_func_array(array(&$renderer, $instruction[0]), $instruction[1]); } } $renderer->toc = array_merge($toc, $renderer->toc); return true; } if($mode == 'metadata') { global $ID; // prevent caching to ensure good user data detection for tests $renderer->info['cache'] = false; $blocks = $data[0]; $content = $data[1]; // parsing content for a <else> statement $else = ''; if(strpos($content, '<else>') !== false) { $i = explode('<else>', $content); $content = $i[0]; $else = implode('', array_slice($i, 1)); } // Process condition blocks $bug = false; $this->_loadtester(); $ok = $this->_processblocks($blocks, $bug); // Render content if all went well $metatoc = $renderer->meta['description']['tableofcontents']; if(!$bug) { $instr = p_get_instructions($ok ? $content : $else); foreach($instr as $instruction) { call_user_func_array(array(&$renderer, $instruction[0]), $instruction[1]); } } $renderer->meta['description']['tableofcontents'] = array_merge($metatoc, $renderer->meta['description']['tableofcontents']); return true; } return false; } // Strips the heading <p> and trailing </p> added by p_render xhtml to acheive inline behavior function _stripp($data) { $data = preg_replace('`^\s*<p[^>]*>\s*`', '', $data); $data = preg_replace('`\s*</p[^>]*>\s*$`', '', $data); return $data; } // evaluates the logical result from a set of blocks function _processblocks($b, &$bug) { for($i=0; $i<count($b); $i++) { if(($b[$i]['type'] == 'block') || ($b[$i]['type'] == 'nblock')) { $b[$i]['r'] = $this->_processblocks($b[$i]['value'], $bug); if($b[$i]['type'] == 'nblock') $b[$i]['r'] = !$b[$i]['r']; }else{ $b[$i]['r'] = $this->_evaluate($b[$i], $bug); } } if(!count($b)) $bug = true; // no condition in block if($bug) return false; // assemble conditions /* CUSTOMISATION : * You can add custom mixing operators here, don't forget to add them to * the "allowedoperators" list at the top of this file */ $r = $b[0]['r']; for($i=1; $i<count($b); $i++) { if($b[$i-1]['next'] == '') { $bug = true; return false; } switch($b[$i-1]['next']) { case '&&' : case 'and' : $r &= $b[$i]['r']; break; case '||' : case 'or' : $r |= $b[$i]['r']; break; case '^' : case 'xor' : $r ^= $b[$i]['r']; break; } } return $r; } // evaluates a single test, loads custom tests if class exists, default test set otherwise function _evaluate($b, &$bug) { if(!$this->tester) { $bug = true; return false; } return $this->tester->run($b, $bug); } // tries to load user defined tester, then base tester if previous failed function _loadtester() { global $conf; $this->tester = null; include_once(DOKU_PLUGIN.'condition/base_tester.php'); if(@file_exists(DOKU_INC.'lib/tpl/'.$conf['template'].'/condition_plugin_custom_tester.php')) { include_once(DOKU_INC.'lib/tpl/'.$conf['template'].'/condition_plugin_custom_tester.php'); if(class_exists('condition_plugin_custom_tester')) { $this->tester = new condition_plugin_custom_tester(); } } if(!$this->tester) { if(class_exists('condition_plugin_base_tester')) { $this->tester = new condition_plugin_base_tester(); } } } } //class ?>
<?php /* * The condition_plugin_custom_tester class defined in <tpl>/condition_plugin_custom_tester.php * MUST implements this class * * To add a custom test in condition_plugin_custom_tester you just have to add a method like : * * function test_dummy($b, &$bug, $lop=false) { if($lop) return array(); return true; } * this test will react to <if dummy></if> of <if dummy=3></if> * * or * * function test_IP($b, &$bug, $lop=false) { * if($lop) return array('\=\=?', 'eq', '\!\=', 'neq?', '\~\='); // pcre regexp list of allowed test operators * $ip = clientIP(true); * if(!$b['test'] || ($b['test'] == '') || !$b['value'] || ($b['value'] == '') || ($ip == '0.0.0.0')) { * $bug = true; * return false; * } * switch($b['test']) { * case '=' : * case 'eq' : * case '==' : * return ($ip == $b['value']); break; * case '!=' : * case 'ne' : * case 'neq' : * return ($ip != $b['value']); break; * case '~=' : // such new test operators must be added in syntax.php * return (strpos($ip, $b['value']) !== false); break; * default: // non allowed operators for the test must lead to a bug flag raise * $bug = true; * return false; * } * } * this test will react to <if IP=127.0.0.1></if> */ class condition_plugin_base_tester { function __construct() {} // Wrapper for all tests function run($b, &$bug) { if(method_exists($this, 'test_'.$b['key'])) { return call_user_func(array($this, 'test_'.$b['key']), $b, $bug); } $bug = true; return false; } // Get allowed keys function getkeys() { $keys = array(); foreach(get_class_methods($this) as $m) { if(preg_match('`^test_(.+)$`', $m, $r)) $keys[] = $r[1]; } return $keys; } // Get test operators function getops() { $ops = array(); foreach($this->getkeys() as $m) $ops = array_merge($ops, call_user_func(array($this, 'test_'.$m), null, $dummy, true)); return array_unique($ops); } // Tests follows // ------------- // user based tests function test_user($b, &$bug, $lop=false) { if($lop) return array('\=\=?', 'eq', '\!\=', 'neq?'); $rh = isset($_SERVER['REMOTE_USER']) ? $_SERVER['REMOTE_USER'] : ''; if(!$b['test'] || ($b['test'] == '')) return ($rh && ($rh != '')); switch($b['test']) { case '=' : case 'eq' : case '==' : return $rh == $b['value']; break; case '!=' : case 'ne' : case 'neq' : return $rh != $b['value']; break; default: $bug = true; return false; } } function test_group($b, &$bug, $lop=false) { if($lop) return array('\=\=?', 'eq', '\!\=', 'neq?'); global $INFO; $grps = isset($INFO['userinfo']) ? $INFO['userinfo']['grps'] : array(); if(!$b['test'] || ($b['test'] == '')) return (count($grps) != 0); switch($b['test']) { case '=' : case 'eq' : case '==' : if(!$b['value'] || ($b['value'] == '')) return (count($grps) == 0); return in_array($b['value'], $grps); break; case '!=' : case 'ne' : case 'neq' : if(!$b['value'] || ($b['value'] == '')) return (count($grps) != 0); return !in_array($b['value'], $grps); break; default: $bug = true; return false; } } // namespace based tests function test_nsread($b, &$bug, $lop=false) { if($lop) return array('\=\=?', 'eq', '\!\=', 'neq?'); if(!$b['test'] || ($b['test'] == '')) { $bug = true; return false; } if(!$b['value'] || ($b['value'] == '')) $b['value'] = '.'; switch($b['test']) { case '=' : case 'eq' : case '==' : return (auth_quickaclcheck($b['value']) >= AUTH_READ); break; case '!=' : case 'ne' : case 'neq' : return (auth_quickaclcheck($b['value']) < AUTH_READ); break; default: $bug = true; return false; } } function test_nsedit($b, &$bug, $lop=false) { if($lop) return array('\=\=?', 'eq', '\!\=', 'neq?'); if(!$b['test'] || ($b['test'] == '')) { $bug = true; return false; } if(!$b['value'] || ($b['value'] == '')) $b['value'] = '.'; switch($b['test']) { case '=' : case 'eq' : case '==' : return (auth_quickaclcheck($b['value']) >= AUTH_EDIT); break; case '!=' : case 'ne' : case 'neq' : return (auth_quickaclcheck($b['value']) < AUTH_EDIT); break; default: $bug = true; return false; } } // time based tests function test_time($b, &$bug, $lop=false) { if($lop) return array('\=\=?', 'eq', '\!\=', 'neq?', '\<\=?', 'lt', '\>\=?', 'gt'); global $INFO; if(!$b['test'] || ($b['test'] == '') || !$b['value'] || ($b['value'] == '')) { $bug = true; return false; } switch($b['test']) { case '=' : case 'eq' : case '==' : return $this->_bt_cmptimeandstr($b['value']); break; case '!=' : case 'ne' : case 'neq' : return !$this->_bt_cmptimeandstr($b['value']); break; case '<' : case 'lt' : $t = time(); return ($t < $this->_bt_strtotime($b['value'], $t)); break; case '>' : case 'gt' : $t = time(); return ($t > $this->_bt_strtotime($b['value'], $t)); break; case '<=' : $t = time(); return ($t <= $this->_bt_strtotime($b['value'], $t)); break; case '>=' : $t = time(); return ($t >= $this->_bt_strtotime($b['value'], $t)); break; default: $bug = true; return false; } } function _bt_strtotime($value, $default) { if(preg_match('`^([0-9]{4})(-|/)([0-9]{2})(-|/)([0-9]{2})(\s+([0-9]{2}):([0-9]{2})(:([0-9]{2}))?)?$`', $value, $reg)) $value = mktime($reg[7], $reg[8], $reg[10], $reg[3], $reg[5], $reg[1]); // YYYY(-|/)MM(-|/)DD (HH:II(:SS)?)? if(preg_match('`^(([0-9]{2}):([0-9]{2})(:([0-9]{2}))?\s+)?([0-9]{4})(-|/)([0-9]{2})(-|/)([0-9]{2})$`', $value, $reg)) $value = mktime($reg[2], $reg[3], $reg[5], $reg[8], $reg[10], $reg[6]); // (HH:II(:SS)?)? YYYY(-|/)MM(-|/)DD if(preg_match('`^([0-9]{2})(-|/)([0-9]{2})(-|/)([0-9]{4})(\s+([0-9]{2}):([0-9]{2})(:([0-9]{2}))?)?$`', $value, $reg)) $value = mktime($reg[7], $reg[8], $reg[10], $reg[3], $reg[1], $reg[5]); // DD(-|/)MM(-|/)YYYY (HH:II(:SS)?)? if(preg_match('`^(([0-9]{2}):([0-9]{2})(:([0-9]{2}))?\s+)?([0-9]{2})(-|/)([0-9]{2})(-|/)([0-9]{4})$`', $value, $reg)) $value = mktime($reg[2], $reg[3], $reg[5], $reg[8], $reg[6], $reg[10]); // (HH:II(:SS)?)? DD(-|/)MM(-|/)YYYY if(!is_numeric($value)) $value = $default; return $value; } function _bt_cmptimeandstr($str) { $matched = false; $t = time(); $time = array('y' => date('Y', $t), 'm' => date('m', $t), 'd' => date('d', $t), 'h' => date('H', $t), 'i' => date('i', $t), 's' => date('s', $t)); $d = array('y' => '', 'm' => '', 'd' => '', 'h' => '', 'i' => '', 's' => ''); // full date y, m and d, time is optionnal if(preg_match('`^([0-9]{4})(-|/)([0-9]{2})(-|/)([0-9]{2})(\s+([0-9]{2}):([0-9]{2})(:([0-9]{2}))?)?$`', $str, $reg)) { $d = array('y' => $reg[1], 'm' => $reg[3], 'd' => $reg[5], 'h' => $reg[7], 'i' => $reg[8], 's' => $reg[10]); // YYYY(-|/)MM(-|/)DD (HH:II(:SS)?)? $matched = true; } if(preg_match('`^(([0-9]{2}):([0-9]{2})(:([0-9]{2}))?\s+)?([0-9]{4})(-|/)([0-9]{2})(-|/)([0-9]{2})$`', $str, $reg)) { $d = array('y' => $reg[6], 'm' => $reg[8], 'd' => $reg[10], 'h' => $reg[2], 'i' => $reg[3], 's' => $reg[5]); // (HH:II(:SS)?)? YYYY(-|/)MM(-|/)DD $matched = true; } if(preg_match('`^([0-9]{2})(-|/)([0-9]{2})(-|/)([0-9]{4})(\s+([0-9]{2}):([0-9]{2})(:([0-9]{2}))?)?$`', $str, $reg)) { $d = array('y' => $reg[5], 'm' => $reg[3], 'd' => $reg[1], 'h' => $reg[7], 'i' => $reg[8], 's' => $reg[10]); // DD(-|/)MM(-|/)YYYY (HH:II(:SS)?)? $matched = true; } if(preg_match('`^(([0-9]{2}):([0-9]{2})(:([0-9]{2}))?\s+)?([0-9]{2})(-|/)([0-9]{2})(-|/)([0-9]{4})$`', $str, $reg)) { $d = array('y' => $reg[10], 'm' => $reg[8], 'd' => $reg[6], 'h' => $reg[2], 'i' => $reg[3], 's' => $reg[5]); // (HH:II(:SS)?)? DD(-|/)MM(-|/)YYYY $matched = true; } // only month and year if(preg_match('`^([0-9]{2})(-|/)([0-9]{4})$`', $str, $reg)) { $d = array('y' => $reg[3], 'm' => $reg[1], 'd' => '', 'h' => '', 'i' => '', 's' => ''); $matched = true; } if(preg_match('`^([0-9]{4})(-|/)([0-9]{2})$`', $str, $reg)) { $d = array('y' => $reg[1], 'm' => $reg[3], 'd' => '', 'h' => '', 'i' => '', 's' => ''); $matched = true; } // only year if(preg_match('`^([0-9]{4})$`', $str, $reg)) { $d = array('y' => $reg[1], 'm' => '', 'd' => '', 'h' => '', 'i' => '', 's' => ''); $matched = true; } // full time hours, minutes (opt) and seconds (opt) // 11 : 11h // 11:30 : 11h30min // 11:30:27 : 11h30min27sec if(preg_match('`^([0-9]{2})(:([0-9]{2})(:([0-9]{2}))?)?$`', $str, $reg)) { $d = array('y' => '', 'm' => '', 'd' => '', 'h' => $reg[7], 'i' => $reg[8], 's' => $reg[10]); // YYYY(-|/)MM(-|/)DD (HH:II(:SS)?)? $matched = true; } // custom datetime format : (XX(XX)?i\s?)+ if(preg_match('`^[0-9]{2}([0-9]{2})?\s?[ymdhis](\s?[0-9]{2}([0-9]{2})?\s?[ymdhis])*$`', $str, $reg)) { while(preg_match('`^(([0-9]{2}([0-9]{2})?)\s?([ymdhis]))`', $str, $reg)) { $v = $reg[2]; $i = $reg[4]; $str = substr($str, strlen($reg[1])); if(($i != 'y') || (strlen($v) == 4)) $d[$i] = $v; } $matched = true; } if(!$matched) return false; $same = true; foreach($time as $k => $v) if(($d[$k] != '') && ($d[$k] != $v)) $same = false; return $same; } // test IP function test_IP($b, &$bug, $lop=false) { if($lop) return array('\=\=?', 'eq', '\!\=', 'neq?', '\~\='); $ip = clientIP(true); if(!$b['test'] || ($b['test'] == '') || !$b['value'] || ($b['value'] == '') || ($ip == '0.0.0.0')) { $bug = true; return false; } switch($b['test']) { case '=' : case 'eq' : case '==' : return ($ip == $b['value']); break; case '!=' : case 'ne' : case 'neq' : return ($ip != $b['value']); break; case '~=' : return (strpos($ip, $b['value']) !== false); break; default: $bug = true; return false; } } } ?>
You must create the condition_plugin_custom_tester.php in your template directory and start with this base:
<?php include_once(DOKU_PLUGIN.'condition/base_tester.php'); class condition_plugin_custom_tester extends condition_plugin_base_tester { // Here the tests methods ... } ?>
To add the test with the key “foo” just add the test method:
function test_foo($b, &$bug, $lop=false) { if($lop) return array('\=\=?', '\!\=', '\:'); // list of accepted test operators, pcre style regexp // Here we accept test operators : =, ==, !=, : switch($b['test']) { case '=' : case '==' : return ($b['value'] == 'bar'); break; case '!=' : return ($b['value'] != 'bar'); break; case ':' : // ... default : $bug = true; return false; } }
So that test can be used as:
<if foo=bar>foo = bar<else>foo != bar</if> <if foo==bar>foo = bar<else>foo != bar</if> <if !foo!=bar>foo = bar<else>foo != bar</if> ...
If your test don't take a parameter you can define it as follows:
function test_foo($b, &$bug, $lop=false) { if($lop) return array(); // no test operators global $ID; return preg_match('`^([^\:]+\:)?bar(\:[^\:]+)?$`', $ID); }
This test is valid if “bar” is a parent namespace of the page:
<if foo>Page is under "bar" namespace</if>
I installed Condition in our production wiki, version 2009-02-14 running on RedHat Enterprise Linux ES 4.0u6 with PHP 4.3.9, and the plugin doesn't seem to work in that environment. Basically, the wiki breaks down immediately after installation and no pages are rendered at all, even before using Condition in any page. Removing the plugin (manually from the file system) restored functionality.
I tested the plugin in a CentOS 5.5/PHP 5.1.6 environment before adding it to our production wiki and it worked without problems.
Is there a known problem with older DokuWiki and/or PHP versions?
Dunno, can you get apache's error log ? There could be some hints about the bug in it.
I get the following warnings on all pages with conditions:
Warning: array_merge() [function.array-merge]: Argument #1 is not an array in /hp/ab/ac/va/www/Wiki/lib/plugins/condition/syntax.php on line 261
Warning: array_merge() [function.array-merge]: Argument #2 is not an array in /hp/ab/ac/va/www/Wiki/lib/plugins/condition/syntax.php on line 261
Warning: Cannot modify header information - headers already sent by (output started at /hp/ab/ac/va/www/Wiki/lib/plugins/condition/syntax.php:261) in /hp/ab/ac/va/www/Wiki/inc/common.php on line 1543
The page is actually saved correctly. It obviously happens when the changed page is to be rendered. Is this a known issue?
2010-10-06 Rainer
This error exists in ~~NOTOC~~ pages.
For fixed: into syntax.php search 261 line and add condition before:
if (is_array( $renderer->meta['description']['tableofcontents']))
2010-11-22 Zefir
I have the same error, but this code doesn´t solve the problem. If I use the condition-plugin some where in the page all headings get lost for the TOC up to the line where you use the condition plugin. The next heading is used as first heading. If no heading is left, filename is used.
2011-07-03 anonymous
The plugin does not work with my installation. I traced the issue in github.
2014-09-23 11:01 cinlloc