1<?php
2
3/**
4 * Bloglinks Plugin: displays a link to the previous and the next blog entry above posts in configured namespaces
5 *
6 * @license  GPL 2 (http://www.gnu.org/licenses/gpl.html)
7 * @author   Gina Haeussge <osd@foosel.net>
8 */
9
10class action_plugin_bloglinks extends DokuWiki_Action_Plugin {
11
12    /**
13     * Register the eventhandlers.
14     */
15    function register(Doku_Event_Handler $controller) {
16        $controller->register_hook('TPL_ACT_RENDER', 'BEFORE', $this, 'handle_act_render', array ());
17        $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'handle_metaheader_output', array ());
18    }
19
20    function handle_metaheader_output(Doku_Event $event, $params) {
21        global $ACT;
22
23        if ($ACT != 'show')
24            return;
25
26        $namespace = $this->_getActiveNamespace();
27        if (!$namespace)
28            return;
29
30        $relatedEntries = $this->_getRelatedEntries($namespace);
31
32        if (isset ($relatedEntries['prev'])) {
33            $event->data['link'][] = array (
34                'rel' => 'prev',
35                'href' => wl($relatedEntries['prev']['id'], '')
36            );
37        }
38        if (isset ($relatedEntries['next'])) {
39            $event->data['link'][] = array (
40                'rel' => 'next',
41                'href' => wl($relatedEntries['next']['id'], '')
42            );
43        }
44
45        return true;
46    }
47
48    function handle_act_render(Doku_Event $event, $params) {
49        global $ACT;
50
51        if ($ACT != 'show')
52            return;
53
54        $namespace = $this->_getActiveNamespace();
55        if ($namespace)
56            $this->_printLinks($this->_getRelatedEntries($namespace));
57
58        return true;
59    }
60
61    function _getActiveNamespace() {
62        global $ID;
63        global $INFO;
64
65        $pattern = $this->getConf('excluded_pages');
66        if (strlen($pattern) > 0 && preg_match($pattern, $ID)) {
67            return false;
68        }
69
70        if (!$INFO['exists'])
71            return false;
72
73        $namespaces = explode(',', $this->getConf('enabled_namespaces'));
74        foreach ($namespaces as $namespace) {
75            if (trim($namespace) && (strpos($ID, $namespace . ':') === 0)) {
76                return $namespace;
77            }
78        }
79
80        return false;
81    }
82
83    function _getRelatedEntries($namespace) {
84        global $ID;
85
86        // get the blog entries for the namespace
87        if ($my = & plugin_load('helper', 'blog'))
88            $entries = $my->getBlog($namespace);
89
90        if (!$entries)
91            return;
92
93        // normalize keys
94        $entries = array_values($entries);
95
96        // prepare search for current page
97        $meta = p_get_metadata($ID);
98        if ($my->sort == 'mdate') {
99            $date = $meta['date']['modified'];
100            if (!$date) $date = filemtime(wikiFN($ID));
101        } else {
102            $date = $meta['date']['created'];
103            if (!$date) $date = filectime(wikiFN($ID));
104        }
105        $perm = auth_quickaclcheck($ID);
106        // Diagnostic
107        $curPage = array (
108            'id' => $ID,
109            'title' => $meta['title'],
110            'date' => $date,
111            'user' => $meta['creator'],
112            'desc' => $meta['description']['abstract'],
113            'exists' => true,
114            'perm' => $perm,
115            'draft' => (isset($meta['type']) && $meta['type'] == 'draft'),
116        );
117
118        // get index of current page
119        $curIndex = array_search($curPage, $entries);
120
121        // Initialize prev, cur and next with null
122        $cur = null;
123        $prev = null;
124        $next = null;
125
126        // get previous and next entries
127        if ($curIndex > 0 && $curIndex < count($entries) - 1) { // got a prev and a next
128            list ($next, $cur, $prev) = array_slice($entries, $curIndex -1, 3);
129        } else if ($curIndex == 0) { // only got a prev
130            list ($cur, $prev) = array_slice($entries, $curIndex, 2);
131        } else { // only got a next
132            list ($next, $cur) = array_slice($entries, $curIndex -1, 2);
133        }
134
135        return array('prev' => $prev, 'cur' => $cur, 'next' => $next);
136    }
137
138    /**
139     * Prints the links to the related entries
140     */
141    function _printLinks($relatedEntries) {
142        // display links
143        echo '<div id="plugin_bloglinks__links">';
144
145        foreach(array('prev', 'next') as $type) {
146            if (isset ($relatedEntries[$type])) {
147                echo '<div class="plugin_bloglinks__'.$type.'">';
148                echo '<a href="' . wl($relatedEntries[$type]['id'], '') . '" class="wikilink1" rel="'.$type.'">' . $this->_linkTemplate($relatedEntries[$type], $type) . '</a>';
149                echo '</div>';
150            }
151        }
152        echo DOKU_LF . '</div>';
153    }
154
155    function _linkTemplate($entry, $type) {
156        global $conf;
157
158        $replace = array(
159            '@@TITLE@@' => $entry['title'],
160            '@@AUTHOR@@' => $entry['user'],
161            '@@DATE@@' => date($conf['dformat'], $entry['date']),
162            '@@NAME@@' => $this->getLang($type . '_link'),
163        );
164
165        $linktext = $this->getConf($type.'_template');
166        $linktext = str_replace(array_keys($replace), array_values($replace), $linktext);
167        return $linktext;
168    }
169}
170
171//Setup VIM: ex: et ts=4 enc=utf-8 :
172