15ad1ba23SRobert McLeod<?php 2c2f9de42SSam Wilson 3c2f9de42SSam Wilson// must be run within Dokuwiki 4c2f9de42SSam Wilsonif (!defined('DOKU_INC')) die(); 5c2f9de42SSam Wilson 6c2f9de42SSam Wilson/** 7c2f9de42SSam Wilson * Add-New-Page Plugin: a simple form for adding new pages. 8c2f9de42SSam Wilson * 9c2f9de42SSam Wilson * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 10c2f9de42SSam Wilson * @author iDO <ido@idotech.info> 11c2f9de42SSam Wilson * @author Sam Wilson <sam@samwilson.id.au> 12c2f9de42SSam Wilson */ 135ad1ba23SRobert McLeodclass syntax_plugin_addnewpage extends DokuWiki_Syntax_Plugin { 14c2f9de42SSam Wilson 15c2f9de42SSam Wilson /** 16*d49bfc3cSGerrit Uitslag * Syntax Type 17c2f9de42SSam Wilson */ 18c2f9de42SSam Wilson function getType() { return 'substition'; } 195ad1ba23SRobert McLeod 20*d49bfc3cSGerrit Uitslag /** 21*d49bfc3cSGerrit Uitslag * Paragraph Type 22*d49bfc3cSGerrit Uitslag */ 23c2f9de42SSam Wilson function getPType() { return 'block'; } 245ad1ba23SRobert McLeod 25*d49bfc3cSGerrit Uitslag /** 26*d49bfc3cSGerrit Uitslag * @return int 27*d49bfc3cSGerrit Uitslag */ 28c2f9de42SSam Wilson function getSort() { return 199; } 295ad1ba23SRobert McLeod 30*d49bfc3cSGerrit Uitslag /** 31*d49bfc3cSGerrit Uitslag * @param string $mode 32*d49bfc3cSGerrit Uitslag */ 335ad1ba23SRobert McLeod function connectTo($mode) { 345ad1ba23SRobert McLeod $this->Lexer->addSpecialPattern('\{\{NEWPAGE[^\}]*\}\}', $mode, 'plugin_addnewpage'); 355ad1ba23SRobert McLeod } 365ad1ba23SRobert McLeod 37*d49bfc3cSGerrit Uitslag /** 38*d49bfc3cSGerrit Uitslag * Handler to prepare matched data for the rendering process 39*d49bfc3cSGerrit Uitslag * 40*d49bfc3cSGerrit Uitslag * @param string $match The text matched by the patterns 41*d49bfc3cSGerrit Uitslag * @param int $state The lexer state for the match 42*d49bfc3cSGerrit Uitslag * @param int $pos The character position of the matched text 43*d49bfc3cSGerrit Uitslag * @param Doku_Handler $handler The Doku_Handler object 44*d49bfc3cSGerrit Uitslag * @return array Return an array with all data you want to use in render 45*d49bfc3cSGerrit Uitslag */ 46*d49bfc3cSGerrit Uitslag function handle($match, $state, $pos, Doku_Handler $handler) { 475ad1ba23SRobert McLeod $ns = substr($match, 10, -2); // strip markup 48b15dc815SSam Wilson return array($ns); 495ad1ba23SRobert McLeod } 505ad1ba23SRobert McLeod 51c2f9de42SSam Wilson /** 52c2f9de42SSam Wilson * Create the new-page form. 53c2f9de42SSam Wilson * 54*d49bfc3cSGerrit Uitslag * @param $mode string output format being rendered 55*d49bfc3cSGerrit Uitslag * @param $renderer Doku_Renderer the current renderer object 56*d49bfc3cSGerrit Uitslag * @param $data array data created by handler() 57*d49bfc3cSGerrit Uitslag * @return boolean rendered correctly? 58c2f9de42SSam Wilson */ 59*d49bfc3cSGerrit Uitslag function render($mode, Doku_Renderer $renderer, $data) { 605ad1ba23SRobert McLeod global $lang; 615ad1ba23SRobert McLeod $renderer->info['cache'] = false; 625ad1ba23SRobert McLeod $data = $data[0]; // get data back from the array 635ad1ba23SRobert McLeod 645ad1ba23SRobert McLeod if ($mode == 'xhtml') { 65c2f9de42SSam Wilson $ns_select = $this->_makecombo($data); 66c2f9de42SSam Wilson if ($ns_select == $this->getLang('nooption')) { 67c2f9de42SSam Wilson $renderer->doc .= (!$this->getConf('addpage_hideACL')) ? $ns_select : ''; 685ad1ba23SRobert McLeod return true; 695ad1ba23SRobert McLeod } 705ad1ba23SRobert McLeod 71c2f9de42SSam Wilson $button_val = ((@$this->getLang('okbutton')) ? $this->getLang('okbutton') : 'ok'); 72c2f9de42SSam Wilson $form = '<div class="addnewpage">'.DOKU_LF 73447a4886SSam Wilson .DOKU_TAB.'<form name="addnewpage" method="get" action="'.DOKU_BASE.DOKU_SCRIPT.'" accept-charset="'.$lang['encoding'].'">'.DOKU_LF 74c2f9de42SSam Wilson .DOKU_TAB.DOKU_TAB.$ns_select.DOKU_LF 75c2f9de42SSam Wilson .DOKU_TAB.DOKU_TAB.'<input class="edit" type="text" name="title" size="20" maxlength="255" tabindex="2" />'.DOKU_LF 76447a4886SSam Wilson .DOKU_TAB.DOKU_TAB.'<input type="hidden" name="do" value="edit" />'.DOKU_LF 77447a4886SSam Wilson .DOKU_TAB.DOKU_TAB.'<input type="hidden" name="id" />'.DOKU_LF 78c2f9de42SSam Wilson .DOKU_TAB.DOKU_TAB.'<input class="button" type="submit" value="'.$button_val.'" tabindex="3" />'.DOKU_LF 79c2f9de42SSam Wilson .DOKU_TAB.'</form>'.DOKU_LF 80c2f9de42SSam Wilson .'</div>'; 81c2f9de42SSam Wilson $renderer->doc .= $form; 825ad1ba23SRobert McLeod 835ad1ba23SRobert McLeod return true; 845ad1ba23SRobert McLeod } 855ad1ba23SRobert McLeod return false; 865ad1ba23SRobert McLeod } 87c2f9de42SSam Wilson 885ad1ba23SRobert McLeod /** 895ad1ba23SRobert McLeod * Parse namespace request 905ad1ba23SRobert McLeod * 915ad1ba23SRobert McLeod * @author Samuele Tognini <samuele@cli.di.unipi.it> 92a98ad79cSSam Wilson * @author Michael Braun <michael-dev@fami-braun.de> 935ad1ba23SRobert McLeod */ 945ad1ba23SRobert McLeod function _parse_ns($ns) { 955ad1ba23SRobert McLeod global $ID; 9605e1bc90SMichael Braun if ($ns == "@PAGE@") return $ID; 9705e1bc90SMichael Braun if ($ns == "@NS@") return getNS($ID); 985ad1ba23SRobert McLeod $ns = preg_replace("/^\.(:|$)/", dirname(str_replace(':', '/', $ID)) . "$1", $ns); 995ad1ba23SRobert McLeod $ns = str_replace("/", ":", $ns); 1005ad1ba23SRobert McLeod $ns = cleanID($ns); 1015ad1ba23SRobert McLeod return $ns; 1025ad1ba23SRobert McLeod } 103c2f9de42SSam Wilson 104c2f9de42SSam Wilson /** 105c2f9de42SSam Wilson * Create the HTML Select element for namespace selection. 106c2f9de42SSam Wilson * 107c2f9de42SSam Wilson * @global string $ID The page ID 1088fad05fbSSam Wilson * @param string|false $dest_ns The destination namespace, or false if none provided. 109c2f9de42SSam Wilson * @return string Select element with appropriate NS selected. 110c2f9de42SSam Wilson */ 111d36b62c6SSam Wilson function _makecombo($dest_ns) { 1125ad1ba23SRobert McLeod global $ID; 1135ad1ba23SRobert McLeod 1148fad05fbSSam Wilson // If a NS has been provided: 1158fad05fbSSam Wilson // Whether to hide the NS selection (otherwise, show only subnamespaces). 1165ad1ba23SRobert McLeod $hide = $this->getConf('addpage_hide'); 1175ad1ba23SRobert McLeod 1188fad05fbSSam Wilson // Whether the user can create pages in the provided NS (or root, if no 1198fad05fbSSam Wilson // destination NS has been set. 1208fad05fbSSam Wilson $can_create = (auth_quickaclcheck($dest_ns.":") >= AUTH_CREATE); 1218fad05fbSSam Wilson 1228fad05fbSSam Wilson if (!empty($dest_ns) && $hide) { 1238fad05fbSSam Wilson if ($can_create) { 1248fad05fbSSam Wilson return '<input type="hidden" name="np_cat" id="np_cat" value="'.$this->_parse_ns($dest_ns).'"/>'; 1258fad05fbSSam Wilson } else { 1268fad05fbSSam Wilson return $this->getLang('nooption'); 1278fad05fbSSam Wilson } 128c2f9de42SSam Wilson } 1295ad1ba23SRobert McLeod 1305ad1ba23SRobert McLeod $ns = explode(':', $ID); 1315ad1ba23SRobert McLeod array_pop($ns); 1325ad1ba23SRobert McLeod $ns = implode(':', $ns); 1335ad1ba23SRobert McLeod 134*d49bfc3cSGerrit Uitslag $subnamespaces = $this->_getnslist(""); 1355ad1ba23SRobert McLeod $ret = '<select class="edit" id="np_cat" name="np_cat" tabindex="1">'; 1365ad1ba23SRobert McLeod 1378fad05fbSSam Wilson // Whether the NS select element has any options 1385ad1ba23SRobert McLeod $someopt=false; 1395ad1ba23SRobert McLeod 1408fad05fbSSam Wilson // Show root namespace if requested and allowed 1418fad05fbSSam Wilson if ($this->getConf('addpage_showroot') && $can_create) { 1428fad05fbSSam Wilson if (empty($dest_ns)) { 1438fad05fbSSam Wilson // If no namespace has been provided, add an option for the root NS. 1448fad05fbSSam Wilson $option_text = ((@$this->getLang('namespaceRoot'))?$this->getLang('namespaceRoot'):'top'); 1458fad05fbSSam Wilson $ret.='<option '.(($ns=='')?'selected ':'').'value="">'.$option_text.'</option>'; 1465ad1ba23SRobert McLeod $someopt=true; 1475ad1ba23SRobert McLeod } else { 1488fad05fbSSam Wilson // If a namespace has been provided, add an option for it. 1498fad05fbSSam Wilson $ret.='<option '.(($ns==$dest_ns)?'selected ':'').'value="'.$dest_ns.'">'.$dest_ns.'</option>'; 1505ad1ba23SRobert McLeod $someopt=true; 1515ad1ba23SRobert McLeod } 152c2f9de42SSam Wilson } 1535ad1ba23SRobert McLeod 154*d49bfc3cSGerrit Uitslag foreach ($subnamespaces as $v) { 155*d49bfc3cSGerrit Uitslag if ($dest_ns != '') { 156*d49bfc3cSGerrit Uitslag if (strpos(":" . $v, ":" . $dest_ns . ":") === false) { 157c2f9de42SSam Wilson continue; 158c2f9de42SSam Wilson } 159c2f9de42SSam Wilson } 1605ad1ba23SRobert McLeod if (auth_quickaclcheck($v . ":") < AUTH_CREATE) continue; 1615ad1ba23SRobert McLeod $vv = explode(':', $v); 1625ad1ba23SRobert McLeod $vv = str_repeat(' ', substr_count($v, ':')) . $vv[count($vv) - 1]; 163e815d9c2SSam Wilson $ret.='<option '.(($ns == $v) ? 'selected ' : '').'value="'.$v.'">'.$vv.'</option>'; 1645ad1ba23SRobert McLeod $someopt = true; 1655ad1ba23SRobert McLeod } 1665ad1ba23SRobert McLeod $ret.='</select>'; 1675ad1ba23SRobert McLeod if (!$someopt) $ret = $this->getLang('nooption'); 1685ad1ba23SRobert McLeod 1695ad1ba23SRobert McLeod return $ret; 1705ad1ba23SRobert McLeod } 171c2f9de42SSam Wilson 172f9dafbcdSSam Wilson /** 173f9dafbcdSSam Wilson * Get a list of namespaces below the given namespace. 174f9dafbcdSSam Wilson * Recursively fetches subnamespaces. 175f9dafbcdSSam Wilson * 176f9dafbcdSSam Wilson * @param string $tns The top namespace 177f9dafbcdSSam Wilson * @return array Multi-dimensional array of all namespaces below $tns 178f9dafbcdSSam Wilson */ 1795ad1ba23SRobert McLeod function _getnslist($tns = '') { 1805ad1ba23SRobert McLeod global $conf; 181*d49bfc3cSGerrit Uitslag 182c2f9de42SSam Wilson if ($tns == '') $tns = $conf['datadir']; 183f9dafbcdSSam Wilson if (!is_dir($tns)) $tns = utf8_encodeFN(str_replace(':', '/', $tns)); 1845ad1ba23SRobert McLeod $data = array(); 1855ad1ba23SRobert McLeod $exclude = $this->getConf('addpage_exclude'); 1865ad1ba23SRobert McLeod 187c2f9de42SSam Wilson if ($exclude == "") $exclude = array(); 188c2f9de42SSam Wilson else $exclude = @explode(';', strtolower($exclude)); 1895ad1ba23SRobert McLeod 1905ad1ba23SRobert McLeod search($data, $tns, 'search_index', array('ns' => '')); 1915ad1ba23SRobert McLeod 1925ad1ba23SRobert McLeod $data2 = array(); 193*d49bfc3cSGerrit Uitslag foreach ($data as $v) { 1945ad1ba23SRobert McLeod if ($v['type'] == 'd') { 1955ad1ba23SRobert McLeod if (!in_array(strtolower($v['id']), $exclude)) { 1965ad1ba23SRobert McLeod array_push($data2, $v['id']); 1975ad1ba23SRobert McLeod $r = $this->_getnslist($tns . '/' . $v['id']); 1985ad1ba23SRobert McLeod foreach ($r as $vv) { 199c2f9de42SSam Wilson if (!in_array(strtolower($vv), $exclude)) { 2005ad1ba23SRobert McLeod array_push($data2, $v['id'] . ':' . $vv); 2015ad1ba23SRobert McLeod } 2025ad1ba23SRobert McLeod } 2035ad1ba23SRobert McLeod } 2045ad1ba23SRobert McLeod } 205c2f9de42SSam Wilson } 2065ad1ba23SRobert McLeod return $data2; 2075ad1ba23SRobert McLeod } 208c2f9de42SSam Wilson 2095ad1ba23SRobert McLeod} 210