1<?php 2 3// must be run within Dokuwiki 4if(!defined('DOKU_INC')) die(); 5 6/** 7 * Add-New-Page Plugin: a simple form for adding new pages. 8 * 9 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 10 * @author iDO <ido@idotech.info> 11 * @author Sam Wilson <sam@samwilson.id.au> 12 */ 13class syntax_plugin_addnewpage extends DokuWiki_Syntax_Plugin { 14 15 /** 16 * Syntax Type 17 */ 18 function getType() { 19 return 'substition'; 20 } 21 22 /** 23 * Paragraph Type 24 */ 25 function getPType() { 26 return 'block'; 27 } 28 29 /** 30 * @return int 31 */ 32 function getSort() { 33 return 199; 34 } 35 36 /** 37 * @param string $mode 38 */ 39 function connectTo($mode) { 40 $this->Lexer->addSpecialPattern('\{\{NEWPAGE[^\}]*\}\}', $mode, 'plugin_addnewpage'); 41 } 42 43 /** 44 * Handler to prepare matched data for the rendering process 45 * 46 * @param string $match The text matched by the patterns 47 * @param int $state The lexer state for the match 48 * @param int $pos The character position of the matched text 49 * @param Doku_Handler $handler The Doku_Handler object 50 * @return array Return an array with all data you want to use in render 51 */ 52 function handle($match, $state, $pos, Doku_Handler $handler) { 53 $ns = substr($match, 10, -2); // strip markup 54 return array($ns); 55 } 56 57 /** 58 * Create the new-page form. 59 * 60 * @param $mode string output format being rendered 61 * @param $renderer Doku_Renderer the current renderer object 62 * @param $data array data created by handler() 63 * @return boolean rendered correctly? 64 */ 65 function render($mode, Doku_Renderer $renderer, $data) { 66 global $lang; 67 $renderer->info['cache'] = false; 68 $data = $data[0]; // get data back from the array 69 70 if($mode == 'xhtml') { 71 $ns_select = $this->_makecombo($data); 72 if($ns_select == $this->getLang('nooption')) { 73 $renderer->doc .= (!$this->getConf('addpage_hideACL')) ? $ns_select : ''; 74 return true; 75 } 76 77 $button_val = ((@$this->getLang('okbutton')) ? $this->getLang('okbutton') : 'ok'); 78 $form = '<div class="addnewpage">' . DOKU_LF 79 . DOKU_TAB . '<form name="addnewpage" method="get" action="' . DOKU_BASE . DOKU_SCRIPT . '" accept-charset="' . $lang['encoding'] . '">' . DOKU_LF 80 . DOKU_TAB . DOKU_TAB . $ns_select . DOKU_LF 81 . DOKU_TAB . DOKU_TAB . '<input class="edit" type="text" name="title" size="20" maxlength="255" tabindex="2" />' . DOKU_LF 82 . DOKU_TAB . DOKU_TAB . '<input type="hidden" name="do" value="edit" />' . DOKU_LF 83 . DOKU_TAB . DOKU_TAB . '<input type="hidden" name="id" />' . DOKU_LF 84 . DOKU_TAB . DOKU_TAB . '<input class="button" type="submit" value="' . $button_val . '" tabindex="3" />' . DOKU_LF 85 . DOKU_TAB . '</form>' . DOKU_LF 86 . '</div>'; 87 $renderer->doc .= $form; 88 89 return true; 90 } 91 return false; 92 } 93 94 /** 95 * Parse namespace request 96 * 97 * @author Samuele Tognini <samuele@cli.di.unipi.it> 98 * @author Michael Braun <michael-dev@fami-braun.de> 99 */ 100 function _parse_ns($ns) { 101 global $ID; 102 if($ns == "@PAGE@") return $ID; 103 if($ns == "@NS@") return getNS($ID); 104 $ns = preg_replace("/^\.(:|$)/", dirname(str_replace(':', '/', $ID)) . "$1", $ns); 105 $ns = str_replace("/", ":", $ns); 106 $ns = cleanID($ns); 107 return $ns; 108 } 109 110 /** 111 * Create the HTML Select element for namespace selection. 112 * 113 * @global string $ID The page ID 114 * @param string|false $dest_ns The destination namespace, or false if none provided. 115 * @return string Select element with appropriate NS selected. 116 */ 117 function _makecombo($dest_ns) { 118 global $ID; 119 120 // If a NS has been provided: 121 // Whether to hide the NS selection (otherwise, show only subnamespaces). 122 $hide = $this->getConf('addpage_hide'); 123 124 // Whether the user can create pages in the provided NS (or root, if no 125 // destination NS has been set. 126 $can_create = (auth_quickaclcheck($dest_ns . ":") >= AUTH_CREATE); 127 128 if(!empty($dest_ns) && $hide) { 129 if($can_create) { 130 return '<input type="hidden" name="np_cat" id="np_cat" value="' . $this->_parse_ns($dest_ns) . '"/>'; 131 } else { 132 return $this->getLang('nooption'); 133 } 134 } 135 136 $ns = explode(':', $ID); 137 array_pop($ns); 138 $ns = implode(':', $ns); 139 140 $subnamespaces = $this->_getnslist(""); 141 $ret = '<select class="edit" id="np_cat" name="np_cat" tabindex="1">'; 142 143 // Whether the NS select element has any options 144 $someopt = false; 145 146 // Show root namespace if requested and allowed 147 if($this->getConf('addpage_showroot') && $can_create) { 148 if(empty($dest_ns)) { 149 // If no namespace has been provided, add an option for the root NS. 150 $option_text = ((@$this->getLang('namespaceRoot')) ? $this->getLang('namespaceRoot') : 'top'); 151 $ret .= '<option ' . (($ns == '') ? 'selected ' : '') . 'value="">' . $option_text . '</option>'; 152 $someopt = true; 153 } else { 154 // If a namespace has been provided, add an option for it. 155 $ret .= '<option ' . (($ns == $dest_ns) ? 'selected ' : '') . 'value="' . $dest_ns . '">' . $dest_ns . '</option>'; 156 $someopt = true; 157 } 158 } 159 160 foreach($subnamespaces as $v) { 161 if($dest_ns != '') { 162 if(strpos(":" . $v, ":" . $dest_ns . ":") === false) { 163 continue; 164 } 165 } 166 if(auth_quickaclcheck($v . ":") < AUTH_CREATE) continue; 167 $vv = explode(':', $v); 168 $vv = str_repeat(' ', substr_count($v, ':')) . $vv[count($vv) - 1]; 169 $ret .= '<option ' . (($ns == $v) ? 'selected ' : '') . 'value="' . $v . '">' . $vv . '</option>'; 170 $someopt = true; 171 } 172 $ret .= '</select>'; 173 if(!$someopt) $ret = $this->getLang('nooption'); 174 175 return $ret; 176 } 177 178 /** 179 * Get a list of namespaces below the given namespace. 180 * Recursively fetches subnamespaces. 181 * 182 * @param string $tns The top namespace 183 * @return array Multi-dimensional array of all namespaces below $tns 184 */ 185 function _getnslist($tns = '') { 186 global $conf; 187 188 if($tns == '') $tns = $conf['datadir']; 189 if(!is_dir($tns)) $tns = utf8_encodeFN(str_replace(':', '/', $tns)); 190 $data = array(); 191 $exclude = $this->getConf('addpage_exclude'); 192 193 if($exclude == "") $exclude = array(); 194 else $exclude = @explode(';', strtolower($exclude)); 195 196 search($data, $tns, 'search_index', array('ns' => '')); 197 198 $data2 = array(); 199 foreach($data as $v) { 200 if($v['type'] == 'd') { 201 if(!in_array(strtolower($v['id']), $exclude)) { 202 array_push($data2, $v['id']); 203 $r = $this->_getnslist($tns . '/' . $v['id']); 204 foreach($r as $vv) { 205 if(!in_array(strtolower($vv), $exclude)) { 206 array_push($data2, $v['id'] . ':' . $vv); 207 } 208 } 209 } 210 } 211 } 212 return $data2; 213 } 214 215} 216