1<?php
2/**
3 * DokuWiki Plugin highlightparent (Action Component)
4 *
5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6 * @author  Michael Große <dokuwiki@cosmocode.de>
7 */
8
9// must be run within Dokuwiki
10if(!defined('DOKU_INC')) die();
11
12class action_plugin_highlightparent extends DokuWiki_Action_Plugin {
13
14    protected $hasBeenRendered = false;
15
16    /**
17     * Registers a callback function for a given event
18     *
19     * @param Doku_Event_Handler $controller DokuWiki's event controller object
20     * @return void
21     */
22    public function register(Doku_Event_Handler $controller) {
23
24       $controller->register_hook('TPL_CONTENT_DISPLAY', 'BEFORE', $this, 'handle_tpl_content_display');
25
26    }
27
28    /**
29     * [Custom event handler which performs action]
30     *
31     * @param Doku_Event $event  event object by reference
32     * @param mixed      $param  [the parameters passed as fifth argument to register_hook() when this
33     *                           handler was registered]
34     * @return void
35     */
36    public function handle_tpl_content_display(Doku_Event $event, $param) {
37        if ($this->hasBeenRendered) {
38            return;
39        }
40        $link = $this->tpl();
41        $event->data = $link . $event->data;
42
43    }
44
45    /**
46     * Return a link to the configured parent page
47     *
48     * @return string
49     */
50    public function tpl() {
51        global $ID, $ACT;
52        if (act_clean($ACT) !== 'show') {
53            return '';
54        }
55
56        $baseID = $this->getBaseID();
57        if ($baseID === '') {
58            return '';
59        }
60        return $this->buildLinkToPage($baseID);
61    }
62
63    /**
64     * Determine the page to which to link
65     *
66     * @return string pageid or empty string
67     */
68    protected function getBaseID()
69    {
70        $pattern = trim($this->getConf('namespace pattern'));
71        if ($pattern === '') {
72            return $this->getStartpageOrParentStartpage();
73        }
74
75        return $this->getParentIDFromPattern($pattern);
76    }
77
78    /**
79     * Determine if and to which page to link based on the configured pattern
80     *
81     * @param string $pattern regex to match a namespace
82     *
83     * @return string pageid or empty string
84     */
85    protected function getParentIDFromPattern($pattern)
86    {
87        global $ID;
88        $matches = array();
89
90        if (preg_match('/' . $pattern . '/', $ID, $matches) === 1) {
91            global $conf;
92            $baseID = $matches[1];
93            if (substr($baseID, -1) === ':') {
94                $baseID .= $conf['start'];
95            }
96            if ($baseID === $ID) {
97                return '';
98            }
99            return $baseID;
100        }
101        return '';
102    }
103
104    /**
105     * Get the startpage of the current namespace or of the parent namespace if on a startpage
106     *
107     * @return string pageid or empty string if on startpage in root namespace
108     */
109    protected function getStartpageOrParentStartpage()
110    {
111        global $ID, $conf;
112        if ($ID === $conf['start']) {
113            return '';
114        }
115        $ns = getNS($ID);
116        $page = noNS($ID);
117
118        if ($ns === false) {
119            return ':' . $conf['start'];
120        }
121
122        if ($page !== $conf['start']) {
123            return $ns . ':' . $conf['start'];
124        }
125
126        return getNS($ns) . ':' . $conf['start'];
127    }
128
129    /**
130     * Render a link to a wikipage as HTML, wrapped by a span with an id
131     *
132     * @param string $baseID
133     *
134     * @return string
135     */
136    protected function buildLinkToPage($baseID)
137    {
138        $baseTitle = p_get_first_heading($baseID);
139        $xhtml_renderer = new Doku_Renderer_xhtml();
140        $link = $xhtml_renderer->internallink($baseID, ($baseTitle ?: $baseID), false, true);
141        $link = "<span id='plugin__highlightparent'>$link</span>";
142        $this->hasBeenRendered = true;
143        return $link;
144    }
145}
146
147// vim:ts=4:sw=4:et:
148