1<?php 2/** 3 * Helper Component for the TwistieNav Plugin 4 * 5 * @author Simon DELAGE <sdelage@gmail.com> 6 * @license: CC Attribution-Share Alike 3.0 Unported <http://creativecommons.org/licenses/by-sa/3.0/> 7 */ 8 9// must be run within Dokuwiki 10if(!defined('DOKU_INC')) die(); 11 12class helper_plugin_twistienav extends DokuWiki_Plugin { 13 14 protected $title_metadata = array(); 15 protected $exclusions = array(); 16 protected $nsignore = array(); 17 18 function build_titlemetafields() { 19 // Known plugins that set title and corresponding metadata keys 20 $this->title_metadata = array( 21 'croissant' => 'plugin_croissant_bctitle', 22 'pagetitle' => 'shorttitle', 23 ); 24 foreach (array_keys($this->title_metadata) as $plugin) { 25 if(plugin_isdisabled($plugin)) unset($this->title_metadata[$plugin]); 26 } 27 $this->title_metadata['dokuwiki'] = 'title'; 28 return $this->title_metadata; 29 } 30 31 function build_exclusions() { 32 global $conf; 33 34 // Convert "exclusions" config setting to array 35 foreach (explode(',', $this->getConf('exclusions')) as $exclusion) { 36 if (substr($exclusion, 0, 1) === '@') { 37 $this->nsignore[] = ltrim($exclusion, "@"); 38 } else { 39 switch ($exclusion) { // care pre-defined keys in multicheckbox 40 case 'start': 41 $this->exclusions[] = $conf['start']; 42 break; 43 case 'sidebar': 44 $this->exclusions[] = $conf['sidebar']; 45 break; 46 default: 47 $this->exclusions[] = $exclusion; 48 } 49 } 50 } 51 return array($this->exclusions, $this->nsignore); 52 } 53 54 /** 55 * Build a namespace index (list sub-namespaces and pages). 56 * 57 * @param (str) $idx namespace ID, must not be a page ID. 58 * Could be provided with : cleanID(getNS($ID)) 59 * @param (bool) $useexclusions use `exclusions` setting or not 60 * @param (bool) $split return a simple level or more complex array 61 * @return (arr) list of sub namespaces and pages found within $idx namespace 62 * 63 * See https://www.dokuwiki.org/plugin:twistienav?do=draft#helper_component for details 64 * 65 */ 66 function get_idx_data($idx = null, $useexclusions = true, $split = false) { 67 global $conf, $ID; 68 // From an ajax call (ie. a click on a TwistieNav), $ID value isn't available so we need to get it from another way 69 if ($ID == null) { 70 $ajaxId = ltrim(explode("id=", $_SERVER["HTTP_REFERER"])[1], ":"); 71 } else { 72 $ajaxId = null; 73 } 74 75 $dir = utf8_encodeFN(str_replace(':','/',$idx)); 76 $data = array(); 77 search($data,$conf['datadir'],'search_index',array('ns' => $idx),$dir); 78 79 if (count($data) != 0) { 80 foreach ($data as $datakey => $item) { 81 // Unset item if is in 'exclusions' 82 if (($useexclusions) && (in_array(noNS($item['id']), $this->exclusions))) { 83 unset($data[$datakey]); 84 continue; 85 // Unset item if it is in 'nsignore' 86 } elseif (($useexclusions) && (in_array(explode(":", $item['id'])[0], $this->nsignore))) { 87 unset($data[$datakey]); 88 continue; 89 // Unset item if it starts with "playground" or is equal to current $ID 90 } elseif ((explode(":", $item['id'])[0] == "playground") or ($item['id'] == $ID) or ($item['id'] == $ajaxId)) { 91 unset($data[$datakey]); 92 continue; 93 } 94 // If item is a directory, we need an ID that points to that namespace's start page (even if it doesn't exist) 95 if ($item['type'] == 'd') { 96 $target = $item['id'].':'.$conf['start']; 97 $classes = "is_ns "; 98 // Or just keep current item ID 99 } else { 100 $target = $item['id']; 101 $classes = "is_page "; 102 } 103 // Add (non-)existence class 104 if (page_exists($target)) { 105 $classes .= "wikilink1"; 106 } else { 107 $classes .= "wikilink2"; 108 } 109 // Get page title from metadata 110 $title = null; 111 if ($this->getConf('useheading')) { 112 foreach ($this->title_metadata as $plugin => $pluginkey) { 113 $title = p_get_metadata($target, $pluginkey, METADATA_DONT_RENDER); 114 if ($title != null) break; 115 } 116 } 117 $data[$datakey]['id'] = $target; 118 $title = @$title ?: hsc(noNS($item['id'])); 119 // Store a link to the page in the data that will be sent back 120 $data[$datakey]['link'] = '<a href="'.wl($target).'" class="'.$classes.'">'.$title.'</a>'; 121 } 122 } 123 if ($split) { 124 $result = array(); 125 $result['namespaces'] = array_values(array_filter($data, function ($row) { 126 return $row["type"] == "d"; 127 })); 128 $result['pages'] = array_values(array_filter($data, function ($row) { 129 return $row["type"] == "f"; 130 })); 131 return $result; 132 } else { 133 return array_values($data); 134 } 135 } 136 137} 138