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