* @license: CC Attribution-Share Alike 3.0 Unported */ // must be run within Dokuwiki if(!defined('DOKU_INC')) die(); class helper_plugin_twistienav extends DokuWiki_Plugin { protected $title_metadata = array(); protected $exclusions = array(); protected $nsignore = array(); function build_titlemetafields() { // Known plugins that set title and corresponding metadata keys $this->title_metadata = array( 'croissant' => 'plugin_croissant_bctitle', 'pagetitle' => 'shorttitle', ); foreach (array_keys($this->title_metadata) as $plugin) { if(plugin_isdisabled($plugin)) unset($this->title_metadata[$plugin]); } $this->title_metadata['dokuwiki'] = 'title'; return $this->title_metadata; } function build_exclusions() { global $conf; // Convert "exclusions" config setting to array foreach (explode(',', $this->getConf('exclusions')) as $exclusion) { if (substr($exclusion, 0, 1) === '@') { $this->nsignore[] = ltrim($exclusion, "@"); } else { switch ($exclusion) { // care pre-defined keys in multicheckbox case 'start': $this->exclusions[] = $conf['start']; break; case 'sidebar': $this->exclusions[] = $conf['sidebar']; break; default: $this->exclusions[] = $exclusion; } } } return array($this->exclusions, $this->nsignore); } /** * Build a namespace index (list sub-namespaces and pages). * * @param (str) $idx namespace ID, must not be a page ID. * Could be provided with : cleanID(getNS($ID)) * @param (bool) $useexclusions use `exclusions` setting or not * @param (bool) $split return a simple level or more complex array * @return (arr) list of sub namespaces and pages found within $idx namespace * * See https://www.dokuwiki.org/plugin:twistienav?do=draft#helper_component for details * */ function get_idx_data($idx = null, $useexclusions = true, $split = false) { global $conf, $ID; // From an ajax call (ie. a click on a TwistieNav), $ID value isn't available so we need to get it from another way if ($ID == null) { $ajaxId = ltrim(explode("id=", $_SERVER["HTTP_REFERER"])[1], ":"); } else { $ajaxId = null; } $dir = utf8_encodeFN(str_replace(':','/',$idx)); $data = array(); search($data,$conf['datadir'],'search_index',array('ns' => $idx),$dir); if (count($data) != 0) { foreach ($data as $datakey => $item) { // Unset item if is in 'exclusions' if (($useexclusions) && (in_array(noNS($item['id']), $this->exclusions))) { unset($data[$datakey]); continue; // Unset item if it is in 'nsignore' } elseif (($useexclusions) && (in_array(explode(":", $item['id'])[0], $this->nsignore))) { unset($data[$datakey]); continue; // Unset item if it starts with "playground" or is equal to current $ID } elseif ((explode(":", $item['id'])[0] == "playground") or ($item['id'] == $ID) or ($item['id'] == $ajaxId)) { unset($data[$datakey]); continue; } // If item is a directory, we need an ID that points to that namespace's start page (even if it doesn't exist) if ($item['type'] == 'd') { $target = $item['id'].':'.$conf['start']; $classes = "is_ns "; // Or just keep current item ID } else { $target = $item['id']; $classes = "is_page "; } // Add (non-)existence class if (page_exists($target)) { $classes .= "wikilink1"; } else { $classes .= "wikilink2"; } // Get page title from metadata $title = null; if ($this->getConf('useheading')) { foreach ($this->title_metadata as $plugin => $pluginkey) { $title = p_get_metadata($target, $pluginkey, METADATA_DONT_RENDER); if ($title != null) break; } } $data[$datakey]['id'] = $target; $title = @$title ?: hsc(noNS($item['id'])); // Store a link to the page in the data that will be sent back $data[$datakey]['link'] = ''.$title.''; } } if ($split) { $result = array(); $result['namespaces'] = array_values(array_filter($data, function ($row) { return $row["type"] == "d"; })); $result['pages'] = array_values(array_filter($data, function ($row) { return $row["type"] == "f"; })); return $result; } else { return array_values($data); } } }