1<?php
2/**
3 * nssearch Plugin for DokuWiki / action.php
4 *
5 * @license None. This is free with no conditions.
6 * @author  Eli Fenton
7 */
8
9if (!defined('DOKU_INC')) {die();}
10if (!defined('DOKU_PLUGIN')) {define('DOKU_PLUGIN', DOKU_INC . 'lib/plugins/');}
11require_once DOKU_PLUGIN . 'action.php';
12
13class action_plugin_nssearch extends DokuWiki_Action_Plugin
14{
15	function getInfo() {return array('author' => 'Eli Fenton', 'name' => 'Namespace Search Plugin', 'url' => 'http://dokuwiki.org/plugin:nssearch');}
16
17	function register(Doku_Event_Handler $controller)
18	{
19		// Edit the query before doing a string search.
20		$controller->register_hook('SEARCH_QUERY_FULLPAGE', 'BEFORE', $this, 'handleQuery');
21		// The page results don't have an edittable query for some reason, so filter invalid results after the search.
22		$controller->register_hook('SEARCH_QUERY_PAGELOOKUP', 'AFTER', $this, 'filterPages');
23	}
24
25	function getLastCrumb()
26	{
27		$br = breadcrumbs();
28		$lastcrumb = '';
29		foreach ($br as $a=>$b) $lastcrumb=$a;
30		return $lastcrumb;
31	}
32	function getBaseNs($id)
33	{
34		return preg_replace('/:.*$/', '', getNS(cleanID($id)));
35	}
36	function getDepthNs($id, $depth)
37	{
38
39		$a = explode(':', getNS(cleanID($id)));
40		array_splice($a, 1+(int)$depth);
41		return implode(':', $a);
42	}
43
44	function handleQuery(&$event, $param)
45	{
46		$ns = $this->getLimitNs($this->getLastCrumb());
47		if ($ns && $event->data['query'])
48        		$event->data['query'] = 'ns:' . $ns . ' ' . $event->data['query'];
49	}
50
51	// You can't edit the query before a page search, so instead we have to filter the results after the search.
52	function filterPages(&$event, $param)
53	{
54		$ns = $this->getLimitNs($this->getLastCrumb());
55		if (!$ns)
56			return;
57		$newresult = array();
58		foreach ($event->result as $a=>$b)
59		{
60			if ($ns.':' == substr(cleanID($a), 0, strlen($ns)+1))
61				$newresult[$a] = $b;
62		}
63		$event->result = $newresult;
64	}
65
66	function getLimitNs($id)
67	{
68		$nslist = explode(';', $this->getConf('namespaces'));
69		rsort($nslist);
70
71		if ($nslist[0] == '@all')
72			return getNS($id);
73		if ($nslist[0] == '@base')
74			return $this->getBaseNs($id);
75		if (substr($nslist[0],0,6) == '@depth')
76			return $this->getDepthNs($id, substr($nslist[0],6));
77
78		foreach ($nslist as $nstest)
79		{
80			if ($nstest.':' == substr($id, 0, strlen($nstest)+1))
81				return $nstest;
82		}
83	}
84}
85