1<?php
2/**
3 * DokuWiki Action Plugin SidebarNG
4 *
5 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @author     Michael Klier <chi@chimeric.de>
7 */
8// must be run within Dokuwiki
9if(!defined('DOKU_INC')) die();
10
11if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN', DOKU_INC.'lib/plugins/');
12if(!defined('DOKU_LF')) define('DOKU_LF', "\n");
13
14require_once(DOKU_PLUGIN.'action.php');
15
16/**
17 * All DokuWiki plugins to extend the admin function
18 * need to inherit from this class
19 */
20class action_plugin_sidebarng extends DokuWiki_Action_Plugin {
21
22    // register hook
23    function register(&$controller) {
24        $controller->register_hook('TPL_CONTENT_DISPLAY', 'BEFORE', $this, '_before');
25        $controller->register_hook('TPL_CONTENT_DISPLAY', 'AFTER', $this, '_after');
26    }
27
28    function _before(&$event, $param) {
29        $pos = $this->getConf('pos');
30
31        ob_start();
32        $this->p_sidebar($pos);
33        $this->sidebar = ob_get_contents();
34        ob_end_clean();
35
36        if(empty($this->sidebar) && !$this->getConf('main_always')) {
37            print '<div class="page">' . DOKU_LF;
38        } else {
39            if($pos == 'left') {
40                    print '<div class="' . $pos . '_sidebar">' . DOKU_LF;
41                    print $this->sidebar;
42                    print '</div>' . DOKU_LF;
43                    print '<div class="page_right">' . DOKU_LF;
44            } else {
45                print '<div class="page_left">' . DOKU_LF;
46            }
47        }
48    }
49
50    function _after(&$event, $param) {
51        $pos = $this->getConf('pos');
52        if(empty($this->sidebar) && !$this->getConf('main_always')) {
53            print '</div>' . DOKU_LF;
54        } else {
55            if($pos == 'left') {
56            print '</div>' . DOKU_LF;
57            } else {
58                print '</div>' . DOKU_LF;
59                print '<div class="' . $pos . '_sidebar">' . DOKU_LF;
60                print $this->sidebar;
61                print '</div>'. DOKU_LF;
62            }
63        }
64    }
65
66    /**
67     * Displays the sidebar
68     *
69     * Michael Klier <chi@chimeric.de>
70     */
71    function p_sidebar($pos) {
72        $sb_order   = explode(',', $this->getConf('order'));
73        $sb_content = explode(',', $this->getConf('content'));
74        $notoc      = (in_array('toc', $sb_content)) ? true : false;
75
76        // process contents by given order
77        foreach($sb_order as $sb) {
78            if(in_array($sb,$sb_content)) {
79                $key = array_search($sb,$sb_content);
80                unset($sb_content[$key]);
81                $this->_sidebar_dispatch($sb,$pos);
82            }
83        }
84
85        // check for left content not specified by order
86        if(is_array($sb_content) && !empty($sb_content) > 0) {
87            foreach($sb_content as $sb) {
88                $this->_sidebar_dispatch($sb,$pos);
89            }
90        }
91    }
92
93    /**
94     * Prints given sidebar box
95     *
96     * @author Michael Klier <chi@chimeric.de>
97     */
98    function _sidebar_dispatch($sb, $pos) {
99        global $lang;
100        global $conf;
101        global $ID;
102        global $REV;
103        global $INFO;
104
105        $svID  = $ID;   // save current ID
106        $svREV = $REV;  // save current REV
107
108        $pname = $this->getConf('pagename');
109
110        switch($sb) {
111
112            case 'main':
113                $main_sb = $pname;
114                if(@page_exists($main_sb)) {
115                    if(auth_quickaclcheck($main_sb) >= AUTH_READ) {
116                        $always = $this->getConf('main_always');
117                        if($always or (!$always && !getNS($ID))) {
118                            print '<div class="main_sidebar sidebar_box">' . DOKU_LF;
119                            print $this->p_sidebar_xhtml($main_sb,$pos) . DOKU_LF;
120                            print '</div>' . DOKU_LF;
121                        }
122                    }
123                } else {
124                    $out = $this->locale_xhtml('nosidebar');
125                    $link = '<a href="' . wl($pname) . '" class="wikilink2">' . $pname . '</a>' . DOKU_LF;
126                    print '<div class="main_sidebar sidebar_box">' . DOKU_LF;
127                    print str_replace('LINK', $link, $out);
128                    print '</div>' . DOKU_LF;
129                }
130                break;
131
132            case 'namespace':
133                $user_ns  = $this->getConf('user_ns');
134                $group_ns = $this->getConf('group_ns');
135                if(!preg_match("/^".$user_ns.":.*?$|^".$group_ns.":.*?$/", $svID)) { // skip group/user sidebars and current ID
136                    $ns_sb = $this->_getNsSb($svID);
137                    if($ns_sb && auth_quickaclcheck($ns_sb) >= AUTH_READ) {
138                        print '<div class="namespace_sidebar sidebar_box">' . DOKU_LF;
139                        print $this->p_sidebar_xhtml($ns_sb,$pos) . DOKU_LF;
140                        print '</div>' . DOKU_LF;
141                    }
142                }
143                break;
144
145            case 'user':
146                $user_ns = $this->getConf('user_ns');
147                if(isset($INFO['userinfo']['name'])) {
148                    $user = $_SERVER['REMOTE_USER'];
149                    $user_sb = $user_ns . ':' . $user . ':' . $pname;
150                    if(@page_exists($user_sb)) {
151                        $subst = array('pattern' => array('/@USER@/'), 'replace' => array($user));
152                        print '<div class="user_sidebar sidebar_box">' . DOKU_LF;
153                        print $this->p_sidebar_xhtml($user_sb,$pos,$subst) . DOKU_LF;
154                        print '</div>';
155                    }
156                    // check for namespace sidebars in user namespace too
157                    if(preg_match('/'.$user_ns.':'.$user.':.*/', $svID)) {
158                        $ns_sb = $this->_getNsSb($svID);
159                        if($ns_sb && $ns_sb != $user_sb && auth_quickaclcheck($ns_sb) >= AUTH_READ) {
160                            print '<div class="namespace_sidebar sidebar_box">' . DOKU_LF;
161                            print $this->p_sidebar_xhtml($ns_sb,$pos) . DOKU_LF;
162                            print '</div>' . DOKU_LF;
163                        }
164                    }
165
166                }
167                break;
168
169            case 'group':
170                $group_ns = $this->getConf('group_ns');
171                if(isset($INFO['userinfo']['grps'])) {
172                    foreach($INFO['userinfo']['grps'] as $grp) {
173                        $group_sb = $group_ns.':'.$grp.':'.$pname;
174                        if(@page_exists($group_sb) && auth_quickaclcheck(cleanID($group_sb)) >= AUTH_READ) {
175                            $subst = array('pattern' => array('/@GROUP@/'), 'replace' => array($grp));
176                            print '<div class="group_sidebar sidebar_box">' . DOKU_LF;
177                            print $this->p_sidebar_xhtml($group_sb,$pos,$subst) . DOKU_LF;
178                            print '</div>' . DOKU_LF;
179                        }
180                    }
181                } else {
182                    $group_sb = $group_ns.':all:'.$pname;
183                    if(@page_exists($group_sb) && auth_quickaclcheck(cleanID($group_sb)) >= AUTH_READ) {
184                        print '<div class="group_sidebar sidebar_box">' . DOKU_LF;
185                        print $this->p_sidebar_xhtml($group_sb,$pos,$subst) . DOKU_LF;
186                        print '</div>' . DOKU_LF;
187                    }
188                }
189                break;
190
191            case 'toolbox':
192                $actions = array('admin', 'edit', 'history', 'recent', 'backlink', 'subscribe', 'subscribens', 'index', 'login', 'profile');
193
194                print '<div class="toolbox_sidebar sidebar_box">' . DOKU_LF;
195                print '  <ul>' . DOKU_LF;
196
197                foreach($actions as $action) {
198                    if(!actionOK($action)) continue;
199                    // start output buffering
200                    if($action == 'edit') {
201                        // check if new page button plugin is available
202                        if(!plugin_isdisabled('npd') && ($npd =& plugin_load('helper', 'npd'))) {
203                            $npb = $npd->html_new_page_button(true);
204                            if($npb) {
205                                print '    <li class="level1"><div class="li">';
206                                print $npb;
207                                print '</div></li>' . DOKU_LF;
208                            }
209                        }
210                    }
211                    ob_start();
212                    print '   <li><div class="li">';
213                    if(tpl_actionlink($action)) {
214                        print '</div></li>' . DOKU_LF;
215                        ob_end_flush();
216                    } else {
217                        ob_end_clean();
218                    }
219                }
220
221                print '  </ul>' . DOKU_LF;
222                print '</div>' . DOKU_LF;
223                break;
224
225            case 'trace':
226                print '<div class="trace_sidebar sidebar_box">' . DOKU_LF;
227                print '  <h1>'.$lang['breadcrumb'].'</h1>' . DOKU_LF;
228                print '  <div class="breadcrumbs">' . DOKU_LF;
229                ($conf['youarehere'] != 1) ? tpl_breadcrumbs() : tpl_youarehere();
230                print '  </div>' . DOKU_LF;
231                print '</div>' . DOKU_LF;
232                break;
233
234            case 'extra':
235                print '<div class="extra_sidebar sidebar_box">' . DOKU_LF;
236                @include(dirname(__FILE__).'/sidebar.html');
237                print '</div>' . DOKU_LF;
238                break;
239
240            default:
241                // check for user defined sidebars
242                if(@file_exists(DOKU_PLUGIN.'sidebarng/sidebars/'.$sb.'/sidebar.php')) {
243                    print '<div class="'.$sb.'_sidebar sidebar_box">' . DOKU_LF;
244                    @require_once(DOKU_PLUGIN.'sidebarng/sidebars/'.$sb.'/sidebar.php');
245                    print '</div>' . DOKU_LF;
246                }
247                break;
248        }
249
250        // restore ID and REV
251        $ID  = $svID;
252        $REV = $svREV;
253    }
254
255    /**
256     * Removes the TOC of the sidebar pages and
257     * shows a edit button if the user has enough rights
258     *
259     * @author Michael Klier <chi@chimeric.de>
260     */
261    function p_sidebar_xhtml($sb,$pos,$subst=array()) {
262        $data = p_wiki_xhtml($sb,'',false);
263        if(!empty($subst)) {
264            $data = preg_replace($subst['pattern'], $subst['replace'], $data);
265        }
266        if(auth_quickaclcheck($sb) >= AUTH_EDIT) {
267            $data .= '<div class="secedit">'.html_btn('secedit',$sb,'',array('do'=>'edit','rev'=>'','post')).'</div>';
268        }
269        // strip TOC
270        $data = preg_replace('/<div class="toc">.*?(<\/div>\n<\/div>)/s', '', $data);
271        // replace headline ids for XHTML compliance
272        $data = preg_replace('/(<h.*?><a.*?name=")(.*?)(".*?id=")(.*?)(">.*?<\/a><\/h.*?>)/','\1sb_'.$pos.'_\2\3sb_'.$pos.'_\4\5', $data);
273        return ($data);
274    }
275
276    /**
277     * Searches for namespace sidebars
278     *
279     * @author Michael Klier <chi@chimeric.de>
280     */
281    function _getNsSb($id) {
282        $pname = $this->getConf('pagename');
283        $ns_sb = '';
284        $path  = explode(':', $id);
285        $found = false;
286
287        while(count($path) > 0) {
288            $ns_sb = implode(':', $path).':'.$pname;
289            if(@page_exists($ns_sb)) return $ns_sb;
290            array_pop($path);
291        }
292
293        // nothing found
294        return false;
295    }
296}
297// vim:ts=4:sw=4:et:enc=utf-8:
298