/** * Handle the match */ function handle($match, $state, $pos, &$handler) { global $ID; $match = substr($match, 9, -11); // strip markup list($flags, $match) = explode('>', $match, 2); $flags = explode('&', substr($flags, 1)); $items = explode('*', $match); $pages = array(); $c = count($items); for ($i = 0; $i < $c; $i++) { if (!preg_match('/\\[\\[(.+?)\\]\\]/', $items[$i], $match)) { continue; } list($id, $title, $description) = explode('|', $match[1], 3); list($id, $section) = explode('#', $id, 2); if (!$id) { $id = $ID; } resolve_pageid(getNS($ID), $id, $exists); // page has an image title if ($title && preg_match('/\\{\\{(.+?)\\}\\}/', $title, $match)) { list($image, $title) = explode('|', $match[1], 2); list($ext, $mime) = mimetype($image); if (!substr($mime, 0, 5) == 'image') { $image = ''; } $pages[] = array('id' => $id, 'section' => cleanID($section), 'title' => trim($title), 'image' => trim($image), 'description' => trim($description), 'exists' => $exists); // text title (if any) } else { $pages[] = array('id' => $id, 'section' => cleanID($section), 'title' => trim($title), 'description' => trim($description), 'exists' => $exists); } } return array($flags, $pages); }
private function getMainPageId($ns) { $idMainPage = $ns['id'] . ':'; resolve_pageid('', $idMainPage, $exist); //get the id of the main page of the ns return $exist ? $idMainPage : null; }
/** * Table of content-function that will * create a hierarchical TOC for the site (by namespace) * and highlight the current page * The startpage if it exists, will always * be shown first in the menu */ function tpl_processStartPage($ns, $context) { // Check if a start page exists and add it first global $conf; $pageExists = false; $startPageName = $conf['start']; if ($ns == "") { $startPageID = $startPageName; } else { $startPageID = $ns . ":" . $startPageName; } $startPagePath = $startPageID; resolve_pageid($ns, $startPagePath, $pageExists); if ($pageExists) { // Check if page is visible $perm = auth_quickaclcheck($startPageID); if ($perm > 0) { // Determine Page Title from first heading $firstHeading = p_get_first_heading($startPageID); if ($conf['useheading'] && !empty($firstHeading)) { $linkName = $firstHeading; } else { $linkName = $startPageName; } // echo "<b>" . $conf['useheading'] ."</b>"; tpl_pageLinkCreate($startPageID, '<i class="icon-home"></i>' . $linkName, "tpl_processStartPage:{$context}"); } } }
function internallink($id, $name = NULL, $search = NULL, $returnonly = false) { global $ID; // default name is based on $id as given $default = $this->_simpleTitle($id); // now first resolve and clean up the $id resolve_pageid(getNS($ID), $id, $exists); $name = $this->_getLinkTitle($name, $default, $isImage, $id); if (!$isImage) { if ($exists) { $class = 'wikilink1'; } else { $class = 'wikilink2'; } } else { $class = 'media'; } //keep hash anchor list($id, $hash) = split('#', $id, 2); //prepare for formating $link['class'] = $class; $link['url'] = str_replace(':', '-', $id) . $this->ext; $link['name'] = $name; $link['title'] = str_replace(':', '-', $id) . $this->ext; //keep hash if ($hash) { $link['url'] .= '#' . $hash; } $this->doc .= $this->_formatLink($link); }
function normalize($value, $hint) { global $ID; // fragment reference special case if (!empty($hint) && substr($hint, -1) == '#') { $value = $hint . $value; resolve_pageid(getNS($hint), $value, $exists); return $value; } $base = $hint ?: getNS($ID); // check for local link, and prefix full page id // (local links don't get resolved by resolve_pageid) if (preg_match('/^#.+/', $value)) { $value = $ID . $value; } // resolve page id with respect to selected base resolve_pageid($base, $value, $exists); // if the value is empty after resolving, it is a reference to the // root starting page. (We can not put the emtpy string into the // database as a normalized reference -- this will create problems) if ($value == '') { global $conf; $value = $conf['start']; } return $value; }
/** * Autocompletion support for pages * * @return array */ public function handleAjax() { global $INPUT; // check minimum length $lookup = trim($INPUT->str('search')); if (utf8_strlen($lookup) < $this->config['autocomplete']['mininput']) { return array(); } // results wanted? $max = $this->config['autocomplete']['maxresult']; if ($max <= 0) { return array(); } // lookup with namespace and postfix applied $namespace = $this->config['autocomplete']['namespace']; if ($namespace) { // namespace may be relative, resolve in current context $namespace .= ':foo'; // resolve expects pageID resolve_pageid($INPUT->str('ns'), $namespace, $exists); $namespace = getNS($namespace); } $postfix = $this->config['autocomplete']['postfix']; if ($namespace) { $lookup .= ' @' . $namespace; } $data = ft_pageLookup($lookup, true, $this->config['usetitles']); if (!count($data)) { return array(); } // this basically duplicates what we do in ajax_qsearch() $result = array(); $counter = 0; foreach ($data as $id => $title) { if ($this->config['usetitles']) { $name = $title . ' (' . $id . ')'; } else { $ns = getNS($id); if ($ns) { $name = noNS($id) . ' (' . $ns . ')'; } else { $name = $id; } } // check suffix if ($postfix && substr($id, -1 * strlen($postfix)) != $postfix) { continue; // page does not end in postfix, don't suggest it } $result[] = array('label' => $name, 'value' => $id); $counter++; if ($counter > $max) { break; } } return $result; }
/** * Empty page on homepage should resolve to start page */ function test_resolve_pageid_empty_homepage() { global $ID; $ID = ''; global $conf; $conf['start'] = 'someverystrangestartname'; $ns = ''; $page = ''; $exist = true; resolve_pageid($ns, $page, $exist); $this->assertEquals($page, $conf['start']); }
/** * Handler to prepare matched data for the rendering process * * @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 bool|array Return an array with all data you want to use in render, false don't add an instruction */ public function handle($match, $state, $pos, Doku_Handler $handler) { global $ID; $ns = substr($match, 8, strpos($match, '|') - 8); $id = $ns . ':start'; resolve_pageid(getNS($ID), $id, $exists); $ns = getNS($id); $title = substr($match, strpos($match, '|') + 1, -2); $link = '?do=export_pdfns&book_ns=' . $ns . '&book_title=' . $title; $title = substr($title, 0, strpos($title, '&')); return array('link' => $link, 'title' => sprintf($this->getLang('export_ns'), $ns, $title), $state, $pos); }
/** * Handle the user input [required] * * @param helper_plugin_bureaucracy_field[] $fields the list of fields in the form * @param string $thanks the thank you message as defined in the form * or default one. Might be modified by the action * before returned * @param array $argv additional arguments passed to the action * @return bool|string false on error, $thanks on success */ public function run($fields, $thanks, $argv) { global $ID; // prepare replacements $this->prepareNamespacetemplateReplacements(); $this->prepareDateTimereplacements(); $this->prepareLanguagePlaceholder(); $this->prepareNoincludeReplacement(); $this->prepareFieldReplacements($fields); //handle arguments $page_to_modify = array_shift($argv); if ($page_to_modify === '_self') { # shortcut to modify the same page as the submitter $page_to_modify = $ID; } else { //resolve against page which contains the form resolve_pageid(getNS($ID), $page_to_modify, $ignored); } $template_section_id = cleanID(array_shift($argv)); if (!page_exists($page_to_modify)) { msg(sprintf($this->getLang('e_pagenotexists'), html_wikilink($page_to_modify)), -1); return false; } // check auth // // This is an important point. In order to be able to modify a page via this method ALL you need is READ access to the page // This is good for admins to be able to only allow people to modify a page via a certain method. If you want to protect the page // from people to WRITE via this method, deny access to the form page. $auth = $this->aclcheck($page_to_modify); // runas if ($auth < AUTH_READ) { msg($this->getLang('e_denied'), -1); return false; } // fetch template $template = rawWiki($page_to_modify); if (empty($template)) { msg(sprintf($this->getLang('e_template'), $page_to_modify), -1); return false; } // do the replacements $template = $this->updatePage($template, $template_section_id); if (!$template) { msg(sprintf($this->getLang('e_failedtoparse'), $page_to_modify), -1); return false; } // save page saveWikiText($page_to_modify, $template, sprintf($this->getLang('summary'), $ID)); //thanks message with redirect $link = wl($page_to_modify); return sprintf($this->getLang('pleasewait'), "<script type='text/javascript' charset='utf-8'>location.replace('{$link}')</script>", html_wikilink($page_to_modify)); }
function render($format, &$renderer, $data) { if ($format != 'xhtml') { return; } global $ID; $svg_wiki_page = trim(substr($data[1], 6, -2)); //name of wiki page containing SVG image resolve_pageid(getNS($ID), $svg_wiki_page, $exists); //resolve relative IDs //detect image size for stupid browsers (like firefox) - ugly (fails if svg does not contain information about it's size) $svg_dimensions = ''; preg_match('/width="[0-9]+" height="[0-9]+"/', $data[1] . rawWiki($svg_wiki_page), $_); if (isset($_[0])) { $svg_dimensions = $_[0]; } // Check alignment $ralign = (bool) preg_match('/^\\{\\{ /', $data[1]); $lalign = (bool) preg_match('/ \\}\\}$/', $data[1]); switch (true) { case $lalign & $ralign: $align = 'center'; break; case $ralign: $align = 'right'; break; case $lalign: $align = 'left'; break; default: $align = ''; } if ($data[0] === '<svg') { $svgenc = $this->svg_base64_encode($data[1]); $renderer->doc .= $this->svg_format_embed($svgenc, 'inline-svg@' . $ID, $svg_dimensions); return true; } if ($data[0] === '{{sv' || $data[0] === '{{ s') { $svglink = exportlink($svg_wiki_page, 'svg'); $renderer->doc .= $this->svg_format_embed($svglink, 'image:' . htmlspecialchars($svg_wiki_page), $svg_dimensions, $align); $renderer->doc .= '<br /><small>' . html_wikilink($svg_wiki_page, 'svg@' . $svg_wiki_page) . '</small>'; return true; } if ($data[0] === '{{SV' || $data[0] === '{{ S') { $svgenc = $this->svg_base64_encode(rawWiki($svg_wiki_page)); $renderer->doc .= $this->svg_format_embed($svgenc, 'image:' . htmlspecialchars($svg_wiki_page), $svg_dimensions, $align); $renderer->doc .= '<br /><small>' . html_wikilink($svg_wiki_page, 'SVG@' . $svg_wiki_page) . '</small>'; return true; } }
/** * Returns an utf8 encoded Namespace for a Page and input Namespace * @param $NS * @param $PAGE */ function getNamespaceFromID($NS, &$PAGE) { global $conf; // Check current page - if its an NS add the startpage $clean = true; resolve_pageid(getNS($NS), $NS, $clean); if (!page_exists($NS) && array_pop(explode(':', $NS)) != strtolower($conf['start'])) { // Compare to lowercase since clean lowers it. $NS .= ':' . $conf['start']; resolve_pageid(getNS($NS), $NS, $clean); } $PAGE = noNS($NS); $NS = getNS($NS); return utf8_encodeFN(str_replace(':', '/', $NS)); }
/** * Handler to prepare matched data for the rendering process */ function handle($match, $state, $pos, &$handler) { global $ID; if ($match == '~~BACKLINKS~~') { //check for deprecated syntax $match = $ID; } else { $match = substr($match, 12, -2); //strip {{backlinks> from start and }} from end $match = $match == '.' ? $ID : $match; if (strstr($match, ".:")) { resolve_pageid(getNS($ID), $match, $exists); } } return array($match); }
/** * Normalizes an internal link. */ function _normalize_internallink($instruction) { global $ID; // split off query string $parts = explode('?', $instruction[0], 2); $id = $parts[0]; list($id, $hash) = explode('#', $id, 2); // normalize selflink if ($id === '') { $id = $ID; } // actually resolve the page resolve_pageid(getNS($ID), $id, $exists); // render the link return $this->_linkSyntax($instruction, $id . '#' . $hash); }
/** * Handler to prepare matched data for the rendering process. * @see DokuWiki_Syntax_Plugin::handle() */ function handle($match, $state, $pos, &$handler) { // Take the id of the source // It can be a rendering of a sidebar global $INFO; global $ID; $id = $ID; // If it's a sidebar, get the original id. if ($INFO != null) { $id = $INFO['id']; } $match = substr($match, 12, -2); //strip {{backlinks> from start and }} from end $match = $match == '.' ? $id : $match; if (strstr($match, ".:")) { resolve_pageid(getNS($id), $match, $exists); } return array($match); }
function dw_internal_links($page) { global $conf; $instructions = p_get_instructions(file_get_contents($page['file'])); $links = array(); $cns = getNS($page['id']); $exists = false; foreach ($instructions as $ins) { if ($ins[0] == 'internallink' || $conf['camelcase'] && $ins[0] == 'camelcaselink') { $mid = $ins[1][0]; resolve_pageid($cns, $mid, $exists); if (!$exists) { list($mid) = explode('#', $mid); //record pages without hashs $links[] = $mid; } } } return $links; }
function test1() { global $conf; // we test multiple cases here // format: $ns, $page, $output $tests = array(); // relative current in root $tests[] = array('', 'page', 'page'); $tests[] = array('', '.page', 'page'); $tests[] = array('', '.:page', 'page'); // relative current in namespace $tests[] = array('lev1:lev2', 'page', 'lev1:lev2:page'); $tests[] = array('lev1:lev2', '.page', 'lev1:lev2:page'); $tests[] = array('lev1:lev2', '.:page', 'lev1:lev2:page'); // relative upper in root $tests[] = array('', '..page', 'page'); $tests[] = array('', '..:page', 'page'); // relative upper in namespace $tests[] = array('lev1:lev2', '..page', 'lev1:page'); $tests[] = array('lev1:lev2', '..:page', 'lev1:page'); $tests[] = array('lev1:lev2', '..:..:page', 'page'); $tests[] = array('lev1:lev2', '..:..:..:page', 'page'); // strange and broken ones $tests[] = array('lev1:lev2', '....:....:page', 'lev1:lev2:page'); $tests[] = array('lev1:lev2', '..:..:lev3:page', 'lev3:page'); $tests[] = array('lev1:lev2', '..:..:lev3:..:page', 'page'); $tests[] = array('lev1:lev2', '..:..:lev3:..:page:....:...', 'page'); // now some tests with existing and none existing files $conf['start'] = 'start'; $tests[] = array('', '.:', 'start'); $tests[] = array('foo', '.:', 'foo:start'); $tests[] = array('', 'foo:', 'foo:start'); $tests[] = array('foo', 'foo:', 'foo:start'); $tests[] = array('foo', 'playground:', 'playground:playground'); foreach ($tests as $test) { $page = $test[1]; resolve_pageid($test[0], $page, $foo); $this->assertEqual($page, $test[2]); } }
function handle_pageredirect_redirect(&$event, $param) { global $ID, $ACT, $REV; if (($ACT == 'show' || $ACT == '') && empty($REV)) { $page = p_get_metadata($ID, 'relation isreplacedby'); // return if no redirection data if (empty($page)) { return; } if (isset($_GET['redirect'])) { // return if redirection is temporarily disabled, // or we have been redirected 5 times in a row if ($_GET['redirect'] == 'no' || $_GET['redirect'] > 4) { return; } elseif ($_GET['redirect'] > 0) { $redirect = $_GET['redirect'] + 1; } else { $redirect = 1; } } else { $redirect = 1; } // verify metadata currency if (@filemtime(metaFN($ID, '.meta')) < @filemtime(wikiFN($ID))) { return; } if (!headers_sent() && $this->getConf('show_note')) { // remember to show note about being redirected from another page session_start(); if (!isset($_SESSION[DOKU_COOKIE]['redirect']) || $redirect == 1) { $_SESSION[DOKU_COOKIE]['redirect'] = $ID; } } // redirect resolve_pageid(getNS($ID), $page, $exists); header("Location: " . wl($page, array('redirect' => $redirect), TRUE, '&')); exit; } }
/** * Render a wiki internal link. * In book export mode a local link with a name/test will be inserted if the * referenced page is included in the exported pages. Otherwise an external * link will be created. * * @param string $id page ID to link to. eg. 'wiki:syntax' * @param string|array $name name for the link, array for media file * @param bool $returnonly whether to return odt or write to doc attribute * * @author Andreas Gohr <*****@*****.**>, LarsDW223 */ function internallink($id, $name = NULL, $returnonly = false) { global $ID; // default name is based on $id as given $default = $this->_simpleTitle($id); // now first resolve and clean up the $id resolve_pageid(getNS($ID), $id, $exists); $name = $this->_getLinkTitle($name, $default, $isImage, $id); // build the absolute URL (keeping a hash if any) list($id, $hash) = explode('#', $id, 2); // Is the link a link to a page included in the book? $pages = $this->actioninstance->getExportedPages(); if (in_array($id, $pages)) { // Yes, create a local link with a name parent::locallink_with_name($hash, $id, $name); return; } // No, create an external link $url = wl($id, '', true); if ($hash) { $url .= '#' . $hash; } if ($ID == $id) { if ($returnonly) { return $this->reference($hash, $name); } else { $this->doc .= $this->reference($hash, $name); } } else { if ($returnonly) { return $this->_doLink($url, $name); } else { $this->doc .= $this->_doLink($url, $name); } } }
/** * Search for backlinks to a given page * * $opts['ns'] namespace of the page * $opts['name'] name of the page without namespace * * @author Andreas Gohr <*****@*****.**> * @deprecated Replaced by ft_backlinks() */ function search_backlinks(&$data, $base, $file, $type, $lvl, $opts) { //we do nothing with directories if ($type == 'd') { return true; } //only search txt files if (substr($file, -4) != '.txt') { return true; } //absolute search id $sid = cleanID($opts['ns'] . ':' . $opts['name']); //current id and namespace $cid = pathID($file); $cns = getNS($cid); //check ACL if (auth_quickaclcheck($cid) < AUTH_READ) { return false; } //fetch instructions $instructions = p_cached_instructions($base . $file, true); if (is_null($instructions)) { return false; } //check all links for match foreach ($instructions as $ins) { if ($ins[0] == 'internallink' || $conf['camelcase'] && $ins[0] == 'camelcaselink') { $mid = $ins[1][0]; resolve_pageid($cns, $mid, $exists); //exists is not used if ($mid == $sid) { //we have a match - finish $data[]['id'] = $cid; break; } } } return false; }
/** * Gives a list of pages for a given include statement * * @author Michael Hamann <*****@*****.**> */ function _get_included_pages($mode, $page, $sect, $parent_id, $flags) { global $conf; $pages = array(); switch($mode) { case 'namespace': $page = cleanID($page); $ns = utf8_encodeFN(str_replace(':', '/', $page)); // depth is absolute depth, not relative depth, but 0 has a special meaning. $depth = $flags['depth'] ? $flags['depth'] + substr_count($page, ':') + ($page ? 1 : 0) : 0; search($pagearrays, $conf['datadir'], 'search_allpages', array('depth' => $depth), $ns); if (is_array($pagearrays)) { foreach ($pagearrays as $pagearray) { if (!isHiddenPage($pagearray['id'])) // skip hidden pages $pages[] = $pagearray['id']; } } break; case 'tagtopic': if (!$this->taghelper) $this->taghelper =& plugin_load('helper', 'tag'); if(!$this->taghelper) { msg('You have to install the tag plugin to use this functionality!', -1); return array(); } $tag = $page; $sect = ''; $pagearrays = $this->taghelper->getTopic('', null, $tag); foreach ($pagearrays as $pagearray) { $pages[] = $pagearray['id']; } break; default: $page = $this->_apply_macro($page); resolve_pageid(getNS($parent_id), $page, $exists); // resolve shortcuts and clean ID if (auth_quickaclcheck($page) >= AUTH_READ) $pages[] = $page; } if (count($pages) > 1) { if ($flags['order'] === 'id') { if ($flags['rsort']) { usort($pages, array($this, '_r_strnatcasecmp')); } else { natcasesort($pages); } } else { $ordered_pages = array(); foreach ($pages as $page) { $key = ''; switch ($flags['order']) { case 'title': $key = p_get_first_heading($page); break; case 'created': $key = p_get_metadata($page, 'date created', METADATA_DONT_RENDER); break; case 'modified': $key = p_get_metadata($page, 'date modified', METADATA_DONT_RENDER); break; case 'indexmenu': $key = p_get_metadata($page, 'indexmenu_n', METADATA_RENDER_USING_SIMPLE_CACHE); if ($key === null) $key = ''; break; case 'custom': $key = p_get_metadata($page, 'include_n', METADATA_RENDER_USING_SIMPLE_CACHE); if ($key === null) $key = ''; break; } $key .= '_'.$page; $ordered_pages[$key] = $page; } if ($flags['rsort']) { uksort($ordered_pages, array($this, '_r_strnatcasecmp')); } else { uksort($ordered_pages, 'strnatcasecmp'); } $pages = $ordered_pages; } } $result = array(); foreach ($pages as $page) { $exists = page_exists($page); $result[] = array('id' => $page, 'exists' => $exists, 'parent_id' => $parent_id); } return $result; }
/** * Render an internal Wiki Link * * $search,$returnonly & $linktype are not for the renderer but are used * elsewhere - no need to implement them in other renderers * * @author Andreas Gohr <*****@*****.**> * @param string $id pageid * @param string|null $name link name * @param string|null $search adds search url param * @param bool $returnonly whether to return html or write to doc attribute * @param string $linktype type to set use of headings * @return void|string writes to doc attribute or returns html depends on $returnonly */ function internallink($id, $name = null, $search = null, $returnonly = false, $linktype = 'content') { global $conf; global $ID; global $INFO; $params = ''; $parts = explode('?', $id, 2); if (count($parts) === 2) { $id = $parts[0]; $params = $parts[1]; } // For empty $id we need to know the current $ID // We need this check because _simpleTitle needs // correct $id and resolve_pageid() use cleanID($id) // (some things could be lost) if ($id === '') { $id = $ID; } // default name is based on $id as given $default = $this->_simpleTitle($id); // now first resolve and clean up the $id resolve_pageid(getNS($ID), $id, $exists, $this->date_at, true); $link = array(); $name = $this->_getLinkTitle($name, $default, $isImage, $id, $linktype); if (!$isImage) { if ($exists) { $class = 'wikilink1'; } else { $class = 'wikilink2'; $link['rel'] = 'nofollow'; } } else { $class = 'media'; } //keep hash anchor @(list($id, $hash) = explode('#', $id, 2)); if (!empty($hash)) { $hash = $this->_headerToLink($hash); } //prepare for formating $link['target'] = $conf['target']['wiki']; $link['style'] = ''; $link['pre'] = ''; $link['suf'] = ''; // highlight link to current page if ($id == $INFO['id']) { $link['pre'] = '<span class="curid">'; $link['suf'] = '</span>'; } $link['more'] = ''; $link['class'] = $class; if ($this->date_at) { $params['at'] = $this->date_at; } $link['url'] = wl($id, $params); $link['name'] = $name; $link['title'] = $id; //add search string if ($search) { $conf['userewrite'] ? $link['url'] .= '?' : ($link['url'] .= '&'); if (is_array($search)) { $search = array_map('rawurlencode', $search); $link['url'] .= 's[]=' . join('&s[]=', $search); } else { $link['url'] .= 's=' . rawurlencode($search); } } //keep hash if ($hash) { $link['url'] .= '#' . $hash; } //output formatted if ($returnonly) { return $this->_formatLink($link); } else { $this->doc .= $this->_formatLink($link); } }
/** * Returns the link for one given tag * * @param string $tag the tag the link shall point to * @param string $title the title of the link (optional) * @param bool $dynamic if the link class shall be changed if no pages with the specified tag exist * @return string The HTML code of the link */ function tagLink($tag, $title = '', $dynamic = false) { global $conf; $svtag = $tag; $tag_title = str_replace('_', ' ', noNS($tag)); resolve_pageid($this->namespace, $tag, $exists); // resolve shortcuts if ($exists) { $class = 'wikilink1'; $url = wl($tag); if ($conf['useheading']) { // important: set sendond param to false to prevent recursion! $heading = p_get_first_heading($tag, false); if ($heading) { $tag_title = $heading; } } } else { if ($dynamic) { $pages = $this->getTopic('', 1, $svtag); if (empty($pages)) { $class = 'wikilink2'; } else { $class = 'wikilink1'; } } else { $class = 'wikilink1'; } $url = wl($tag, array('do' => 'showtag', 'tag' => $svtag)); } if (!$title) { $title = $tag_title; } $link = '<a href="' . $url . '" class="' . $class . '" title="' . hsc($tag) . '" rel="tag">' . hsc($title) . '</a>'; return $link; }
/** * Gathers all page and media data for given namespaces. * * @namespaces array() of namespaces * @depth Search depth * @include_media Determines if media should be regarded, Values: 'ns','all','none'. * @use_cached_pages Determines if only cached pages should be used. If this option is turned off, the operation will cache all non-cached pages within the namespace. * @use_first_header Determines if the first header is used for title of the pages. * * @return array with pages and media: array('pages'=>pages, 'media'=>media). */ function gather_data($namespaces, $depth = 0, $include_media = 'none', $use_cached_pages = true, $use_first_header = false) { global $conf; $transplugin = plugin_load('helper', 'translation'); $pages = array(); $media = array(); // Loop through the namespaces foreach ($namespaces as $ns) { // Get the media of the namespace if ($include_media == 'ns') { $this->get_media($media, $ns, $depth); } // Get the pages of the namespace $this->get_pages($pages, $ns, $depth, $use_first_header); } // Loop through the pages to get links and media foreach ($pages as $pid => $item) { // get instructions $ins = p_cached_instructions(wikiFN($pid), $use_cached_pages, $pid); // find links and media usage foreach ($ins as $i) { $mid = null; // Internal link? if ($i[0] == 'internallink') { $id = $i[1][0]; $exists = true; resolve_pageid($item['ns'], $id, $exists); list($id) = explode('#', $id, 2); if ($id == $pid) { continue; } // skip self references if ($exists && isset($pages[$id])) { $pages[$pid]['links'][] = $id; } if (is_array($i[1][1]) && $i[1][1]['type'] == 'internalmedia') { $mid = $i[1][1]['src']; // image link } else { continue; // we're done here } } if ($i[0] == 'internalmedia') { $mid = $i[1][0]; } if (is_null($mid)) { continue; } if ($include_media == 'none') { continue; } // no media wanted $exists = true; resolve_mediaid($item['ns'], $mid, $exists); list($mid) = explode('#', $mid, 2); $mid = cleanID($mid); if ($exists) { if ($include_media == 'all') { if (!isset($media[$mid])) { //add node $media[$mid] = array('size' => filesize(mediaFN($mid)), 'time' => filemtime(mediaFN($mid)), 'ns' => getNS($mid), 'title' => noNS($mid)); } $pages[$pid]['media'][] = $mid; } elseif (isset($media[$mid])) { $pages[$pid]['media'][] = $mid; } } } // clean up duplicates $pages[$pid]['links'] = array_unique($pages[$pid]['links']); $pages[$pid]['media'] = array_unique($pages[$pid]['media']); } return array('pages' => $pages, 'media' => $media); }
/** * Hierarchical breadcrumbs * * This code was suggested as replacement for the usual breadcrumbs. * It only makes sense with a deep site structure. * * @author Andreas Gohr <*****@*****.**> * @author Nigel McNie <*****@*****.**> * @author Sean Coates <*****@*****.**> * @author <*****@*****.**> * @todo May behave strangely in RTL languages * @param string $sep Separator between entries * @return bool */ function tpl_youarehere($sep = ' ยป ') { global $conf; global $ID; global $lang; // check if enabled if (!$conf['youarehere']) { return false; } $parts = explode(':', $ID); $count = count($parts); echo '<span class="bchead">' . $lang['youarehere'] . ': </span>'; // always print the startpage tpl_pagelink(':' . $conf['start']); // print intermediate namespace links $part = ''; for ($i = 0; $i < $count - 1; $i++) { $part .= $parts[$i] . ':'; $page = $part; if ($page == $conf['start']) { continue; } // Skip startpage // output echo $sep; tpl_pagelink($page); } // print current page, skipping start page, skipping for namespace index resolve_pageid('', $page, $exists); if (isset($page) && $page == $part . $parts[$i]) { return true; } $page = $part . $parts[$i]; if ($page == $conf['start']) { return true; } echo $sep; tpl_pagelink($page); return true; }
/** * Initializes the labels, loaded from a defined labelpage * * @param array $data all data passed to render() */ protected function loadlabels(&$data) { global $INFO; $labelpage = $data['labels']; $exists = false; resolve_pageid($INFO['namespace'], $labelpage, $exists); if (!$exists) { msg(sprintf($this->getLang('e_labelpage'), html_wikilink($labelpage)), -1); return; } // parse simple list (first level cdata only) $labels = array(); $instructions = p_cached_instructions(wikiFN($labelpage)); $inli = 0; $item = ''; foreach ($instructions as $instruction) { if ($instruction[0] == 'listitem_open') { $inli++; continue; } if ($inli === 1 && $instruction[0] == 'cdata') { $item .= $instruction[1][0]; } if ($instruction[0] == 'listitem_close') { $inli--; if ($inli === 0) { list($k, $v) = explode('=', $item, 2); $k = trim($k); $v = trim($v); if ($k && $v) { $labels[$k] = $v; } $item = ''; } } } // apply labels to all fields $len = count($data['fields']); for ($i = 0; $i < $len; $i++) { if (isset($data['fields'][$i]->depends_on)) { // translate dependency on fieldsets $label = $data['fields'][$i]->depends_on[0]; if (isset($labels[$label])) { $data['fields'][$i]->depends_on[0] = $labels[$label]; } } else { if (isset($data['fields'][$i]->opt['label'])) { // translate field labels $label = $data['fields'][$i]->opt['label']; if (isset($labels[$label])) { $data['fields'][$i]->opt['display'] = $labels[$label]; } } } } if (isset($data['thanks'])) { if (isset($labels[$data['thanks']])) { $data['thanks'] = $labels[$data['thanks']]; } } }
function _recurse(&$renderer, $data, $dir, $ns, $excluPages, $excluNS, $depth = -1) { if ($depth == 0) { return; } $depth--; $mainPageId = $ns . ':'; $mainPageExists; resolve_pageid('', $mainPageId, $mainPageExists); if (!$mainPageExists) { $mainPageId = NULL; } global $conf; $path = $conf['savedir'] . '/pages/' . $dir; $handle = @opendir($path); if (!$handle) { msg(sprintf($this->getLang('dontexist'), $ns), 0); return; } while (($item = readdir($handle)) !== false) { if ($item[0] == '.' || $item[0] == '_') { continue; } $name = str_replace('.txt', '', $item); $id = $ns . ':' . $name; $infos = array('id' => $id, 'name' => $name); if (is_dir($path . '/' . $item)) { if ($excluNS) { continue; } $startid = $id . ':'; $startexist = false; resolve_pageid('', $startid, $startexist); $infos['title'] = $startexist ? p_get_first_heading($startid, true) : $name; if ($this->_isExcluded($infos, $data['exclutype'], $data['excluns'])) { continue; } $perms = auth_quickaclcheck($id . ':*'); $this->_displayNSBegin($renderer, $infos, $data['displayType'], ($startexist || $data['forceLinks']) && $perms >= AUTH_READ, $data['nsInBold'], $data['expand']); if (!$this->_isExcluded($infos, $data['exclutype'], $data['exclunsall']) && $perms >= AUTH_READ) { $exclunspages = $this->_isExcluded($infos, $data['exclutype'], $data['exclunspages']); $exclunsns = $this->_isExcluded($infos, $data['exclutype'], $data['exclunsns']); $this->_recurse($renderer, $data, $dir . '/' . $item, $ns . ':' . $item, $exclunspages, $exclunsns, $depth); } $this->_displayNSEnd($renderer, $data['displayType'], $data['createPageButtonEach'] && $perms >= AUTH_CREATE ? $id . ':' : NULL); } else { if (!$excluPages) { if (auth_quickaclcheck($id) < AUTH_READ) { continue; } $infos['title'] = p_get_first_heading($id, true); if (is_null($infos['title'])) { $infos['title'] = $name; } if ($this->_isExcluded($infos, $data['exclutype'], $data['exclupage'])) { continue; } if ($id != $mainPageId) { $this->_displayPage($renderer, $infos, $data['displayType']); } } } } closedir($handle); }
/** * Handle parameters that are specified uing <name>=<value> syntax */ protected function handleNamedParameter($name, $value, &$data) { global $ID; static $types = array('edit' => 'E', 'create' => 'C', 'delete' => 'D', 'minor' => 'e'); static $renderers = array('list', 'pagelist'); switch ($name) { case 'count': $data[$name] = intval($value); break; case 'ns': foreach (preg_split('/\\s*,\\s*/', $value) as $value) { $this->addNamespace($data, $value); } break; case 'type': foreach (preg_split('/\\s*,\\s*/', $value) as $value) { if (array_key_exists($value, $types)) { $data[$name][] = $types[$value]; } } break; case 'render': // parse "name(flag1, flag2)" syntax if (preg_match('/(\\w+)(?:\\((.*)\\))?/', $value, $match) == 1) { if (in_array($match[1], $renderers)) { $data[$name] = $match[1]; $flags = trim($match[2]); if ($flags != '') { $data['render-flags'] = preg_split('/\\s*,\\s*/', $flags); } } } break; case 'user': foreach (preg_split('/\\s*,\\s*/', $value) as $value) { $data[$name][] = $value; } break; case 'excludedpages': foreach (preg_split('/\\s*,\\s*/', $value) as $page) { if (!empty($page)) { resolve_pageid(getNS($ID), $page, $exists); $data[$name][] = $page; } } break; case 'maxage': $data[$name] = intval($value); break; } }
/** * keep track of internal links in $this->meta['relation']['references'] */ function internallink($id, $name = NULL) { global $ID; if (is_array($name)) { $this->_firstimage($name['src']); } $default = $this->_simpleTitle($id); // first resolve and clean up the $id resolve_pageid(getNS($ID), $id, $exists); list($page, $hash) = explode('#', $id, 2); // set metadata $this->meta['relation']['references'][$page] = $exists; // $data = array('relation' => array('isreferencedby' => array($ID => true))); // p_set_metadata($id, $data); // add link title to summary if ($this->capture) { $name = $this->_getLinkTitle($name, $default, $id); $this->doc .= $name; } }
/** * Search for internal wiki links in page $file */ function orph_Check_InternalLinks(&$data, $base, $file, $type, $lvl, $opts) { $dbg = false; define('LINK_PATTERN', '%\\[\\[([^\\]|#]*)(#[^\\]|]*)?\\|?([^\\]]*)]]%'); if (!preg_match("/.*\\.txt\$/", $file)) { return; } if ($dbg) { echo '<p><b>' . $file . '</b></p>'; } global $conf; // echo " <!-- checking file: $file -->\n"; $body = @file_get_contents($conf['datadir'] . $file); // ignores entries in <nowiki>, %%, <code> and emails with @ foreach (array('/<nowiki>[\\W\\w]*<\\/nowiki>/', '/%%.*%%/', '/<code>[\\W\\w]*<\\/code>/', '/\\[\\[\\ *\\\\.*\\]\\]/', '/\\[\\[\\ *[a-zA-Z0-9._-]+@[a-zA-Z0-9-]+\\..*\\ *\\]\\]/') as $ignored) { $body = preg_replace($ignored, '', $body); } $links = array(); preg_match_all(LINK_PATTERN, $body, $links); foreach ($links[1] as $link) { if ($dbg) { echo $link; } if (0 < strlen(ltrim($link)) and $link[0] != '/' and !preg_match('/^\\ *(https?|mailto|ftp|file):/', $link) and !preg_match('/^(.*)>/', $link) and !strpos('@', $link)) { // Try fixing the link... //$link = preg_replace("![ ]!", "_", strtolower($link)); // need to fix the namespace? if ($link[0] == ":") { // forced root namespace $link = substr($link, 1); //echo "\t\t<!-- !! (2) $link -->\n"; } else { if ($link[0] == ".") { // forced relative namespace // $link = preg_replace("!::!", ":",orph_fileNS($file) . ":" . substr($link, 1)); resolve_pageid(orph_fileNS($file), $link, $exists); // echo "\t\t<!-- !! (2) $link -->\n"; } else { if (strpos($link, ':') === false) { $link = preg_replace("!::!", ":", orph_fileNS($file) . ":" . $link); // echo "\t\t<!-- !! (3) $link -->\n"; } } } // namespace fix if ($link[strlen($link) - 1] == ":") { $link .= $conf["start"]; } // looks like an ID? $link = cleanID($link); if (strlen(ltrim($link)) > 0 and !auth_quickaclcheck($link) < AUTH_READ) { // should be visible to user // and (!preg_match("/^(http|mailto):/", $link)) // URL // and (!preg_match("/^(.*)>/", $link))) { // interwiki //check ACL //echo " <!-- adding $link -->\n"; //dae mod //orph_handle_link(&$data, $link); orph_handle_link($data, $link); } } // link is not empty? } // end of foreach link }
/** * Construct a new ID relative to the current page's location * * Uses a relative link only if the original was relative, too. This function is for * pages and media files. * * @param string $relold the old, possibly relative ID * @param string $new the new, full qualified ID * @param string $type 'media' or 'page' * @throws Exception on bad argument * @return string */ public function relativeLink($relold, $new, $type) { global $conf; if ($type != 'media' && $type != 'page') { throw new Exception('Not a valid type'); } // first check if the old link still resolves $exists = false; $old = $relold; if ($type == 'page') { resolve_pageid($this->ns, $old, $exists); } else { resolve_mediaid($this->ns, $old, $exists); } if ($old == $new) { return $relold; // old link still resolves, keep as is } if ($conf['useslash']) { $relold = str_replace('/', ':', $relold); } // check if the link was relative if (strpos($relold, ':') === false || $relold[0] == '.') { $wasrel = true; } else { $wasrel = false; } // if it wasn't relative then, leave it absolute now, too if (!$wasrel) { if ($this->ns && !getNS($new)) { $new = ':' . $new; } $new = $this->_nsStartCheck($relold, $new, $type); return $new; } // split the paths and see how much common parts there are $selfpath = explode(':', $this->ns); $goalpath = explode(':', getNS($new)); $min = min(count($selfpath), count($goalpath)); for ($common = 0; $common < $min; $common++) { if ($selfpath[$common] != $goalpath[$common]) { break; } } // we now have the non-common part and a number of uppers $ups = max(count($selfpath) - $common, 0); $remainder = array_slice($goalpath, $common); $upper = $ups ? array_fill(0, $ups, '..:') : array(); // build the new relative path $newrel = join(':', $upper); if ($remainder) { $newrel .= join(':', $remainder) . ':'; } $newrel .= noNS($new); $newrel = str_replace('::', ':', trim($newrel, ':')); if ($newrel[0] != '.' && $this->ns && getNS($newrel)) { $newrel = '.' . $newrel; } // if the old link ended with a colon and the new one is a start page, adjust $newrel = $this->_nsStartCheck($relold, $newrel, $type); // don't use relative paths if it is ridicoulus: if (strlen($newrel) > strlen($new)) { $newrel = $new; if ($this->ns && !getNS($new)) { $newrel = ':' . $newrel; } $newrel = $this->_nsStartCheck($relold, $newrel, $type); } return $newrel; }