* @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);
}
}
}