* @author Sam Wilson * * @noinspection PhpUnused, * PhpMissingParamTypeInspection, PhpMissingReturnTypeInspection */ // must be run within Dokuwiki use dokuwiki\File\PageResolver; if(!defined('DOKU_INC')) die(); class syntax_plugin_addnewpage extends DokuWiki_Syntax_Plugin { /** * Syntax Type */ public function getType() { return 'substition'; } /** * Paragraph Type */ public function getPType() { return 'block'; } /** * @return int */ public function getSort() { return 199; } /** * @param string $mode */ public function connectTo($mode) { $this->Lexer->addSpecialPattern('\{\{NEWPAGE[^\}]*\}\}', $mode, 'plugin_addnewpage'); } /** * Handler to prepare matched data for the rendering process * * Handled syntax options: * {{NEWPAGE}} * {{NEWPAGE>your:namespace}} * {{NEWPAGE#newtpl1,newtpl2}} * {{NEWPAGE#newtpl1|Title1,newtpl2|Title1}} * {{NEWPAGE>your:namespace#newtpl1|Title1,newtpl2|Title1}} * {{NEWPAGE>your:namespace#newtpl1|Title1,newtpl2|Title1#@HI@,Howdy}} * * @param string $match The text matched by the patterns * @param int $state The lexer state for the match * @param int $pos The character position of the matched text * @param Doku_Handler $handler The Doku_Handler object * @return array Return an array with all data you want to use in render * @codingStandardsIgnoreStart */ public function handle($match, $state, $pos, Doku_Handler $handler) { /* @codingStandardsIgnoreEnd */ $options = substr($match, 9, -2); // strip markup $options = explode('#', $options, 3); $namespace = trim(ltrim($options[0], '>')); $templates = explode(',', $options[1] ?? ''); $templates = array_map('trim', $templates); $newpagevars = trim($options[2] ?? ''); return array( 'namespace' => $namespace, 'newpagetemplates' => $templates, 'newpagevars' => $newpagevars ); } /** * Create the new-page form. * * @param $format string output format being rendered * @param $renderer Doku_Renderer the current renderer object * @param $data array data created by handler() * @return boolean rendered correctly? */ public function render($format, Doku_Renderer $renderer, $data) { global $lang; if($format == 'xhtml') { $disablecache = false; $namespaceinput = $this->_htmlNamespaceInput($data['namespace'], $disablecache); if($namespaceinput === false) { if($this->getConf('addpage_hideACL')) { $renderer->doc .= ''; } else { $renderer->doc .= $this->getLang('nooption'); } return true; } if($disablecache) $renderer->info['cache'] = false; $newpagetemplateinput = $this->_htmlTemplateInput($data['newpagetemplates']); $form = '

' . '

' . $namespaceinput . '' . $newpagetemplateinput . '' . '' . '' . '' . '
' . '

'; $renderer->doc .= $form; return true; } return false; } /** * Parse namespace request * * @author Samuele Tognini * @author Michael Braun */ protected function _parseNS($ns) { $ID=getID(); if(strpos($ns, '@PAGE@') !== false) { return cleanID(str_replace('@PAGE@', $ID, $ns)); } if($ns == "@NS@") return getNS($ID); $ns = preg_replace("/^\.(:|$)/", dirname(str_replace(':', '/', $ID)) . "$1", $ns); $ns = str_replace("/", ":", $ns); return cleanID($ns); } /** * Create the HTML Select element for namespace selection. * * @param string|false $dest_ns The destination namespace, or false if none provided. * @param bool $disablecache reference indicates if caching need to be disabled * @global string $ID The page ID * @return string Select element with appropriate NS selected. */ protected function _htmlNamespaceInput($dest_ns, &$disablecache) { global $ID; $disablecache = false; // If a NS has been provided: // Whether to hide the NS selection (otherwise, show only subnamespaces). $hide = $this->getConf('addpage_hide'); $parsed_dest_ns = $this->_parseNS($dest_ns); // Whether the user can create pages in the provided NS (or root, if no // destination NS has been set. $can_create = (auth_quickaclcheck($parsed_dest_ns . ":") >= AUTH_CREATE); //namespace given, but hidden if($hide && !empty($dest_ns)) { if($can_create) { return ''; } else { return false; } } //show select of given namespace $currentns = getNS($ID); $ret = ''; if($someopt) { return $ret; } else { return false; } } /** * Get a list of namespaces below the given namespace. * Recursively fetches subnamespaces. * * @param string $topns The top namespace * @return array Multi-dimensional array of all namespaces below $tns */ protected function _getNamespaceList($topns = '') { global $conf; $topns = utf8_encodeFN(str_replace(':', '/', $topns)); $excludes = $this->getConf('addpage_exclude'); if($excludes == "") { $excludes = array(); } else { $excludes = @explode(';', strtolower($excludes)); } $searchdata = array(); search($searchdata, $conf['datadir'], 'search_namespaces', array(), $topns); $namespaces = array(); foreach($searchdata as $ns) { foreach($excludes as $exclude) { if( ! empty($exclude) && strpos($ns['id'], $exclude) === 0) { continue 2; } } $namespaces[] = $ns['id']; } return $namespaces; } /** * Create html for selection of namespace templates * * @param array $newpagetemplates array of namespace templates * @return string html of select or hidden input */ public function _htmlTemplateInput($newpagetemplates) { $cnt = count($newpagetemplates); if($cnt < 1 || $cnt == 1 && $newpagetemplates[0] == '') { $input = ''; } else { if($cnt == 1) { list($template, ) = $this->_parseNSTemplatePage($newpagetemplates[0]); $input = ''; } else { $first = true; $input = ''; } $input = DOKU_TAB . DOKU_TAB . $input . DOKU_LF; } return $input; } /** * Parses and resolves the namespace template page * * @param $nstemplate * @return array */ protected function _parseNSTemplatePage($nstemplate) { global $ID; @list($template, $name) = explode('|', $nstemplate, 2); $template = (new PageResolver($ID))->resolveId($template); if (is_null($name)) $name = $template; return array($template, $name); } }