1<?php
2/**
3 * DokuWiki Plugin inetmodifications (Action Component)
4 *
5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6 * @author  i-net /// software <tools@inetsoftware.de>
7 */
8
9// must be run within Dokuwiki
10if(!defined('DOKU_INC')) die();
11
12class action_plugin_leightweightscript extends DokuWiki_Action_Plugin {
13
14    /**
15     * Registers a callback function for a given event
16     *
17     * @param Doku_Event_Handler $controller DokuWiki's event controller object
18     * @return void
19     */
20    public function register(Doku_Event_Handler $controller) {
21       $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'handle_tpl_metaheader_output');
22       $controller->register_hook('JS_SCRIPT_LIST', 'BEFORE', $this, 'handle_js_script_list');
23       $controller->register_hook('TOOLBAR_DEFINE', 'BEFORE', $this, 'handle_js_toolbar');
24
25       // $controller->register_hook('JS_CACHE_USE', 'BEFORE', $this, 'handle_use_cache');
26    }
27
28    /**
29     * Insert an extra script tag for users that have AUTH_EDIT or better
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_metaheader_output(Doku_Event &$event, $param) {
37        global $ID;
38
39        // add script if user has better auth than AUTH_EDIT
40        if ( auth_quickaclcheck( $ID ) >= AUTH_EDIT ) {
41            $event->data['script'][] = array(
42                'type'=> 'text/javascript', 'charset'=> 'utf-8', '_data'=> '',
43                'src' => DOKU_BASE.'lib/exe/js.php'.'?t='.rawurlencode($conf['template']).'&type=admin&tseed='.$tseed
44            );
45        }
46
47        // The first one is the static JavaScript block. PageSpeed says it would be good to print this first.
48        _tpl_metaheaders_action( array( 'script' => array( array_shift($event->data['script']) ) ) );
49    }
50
51    /**
52     * Hacking the toolbar for the requested script.
53     * If it is NOT the previously added admin script, remove the toolbar
54     * because the user has no edit rights.
55     *
56     * @param Doku_Event $event  event object by reference
57     * @param mixed      $param  [the parameters passed as fifth argument to register_hook() when this
58     *                           handler was registered]
59     * @return void
60     */
61    public function handle_js_toolbar(Doku_Event &$event, $param) {
62        global $INPUT;
63
64        if ( $INPUT->str('type')  != 'admin' ) {
65            $data = array();
66
67            // Remove the toolbar and do not add (which is done after this function) the default buttons
68            $event->data = &$data;
69            $event->preventDefault();
70
71            return false;
72        } else {
73            // Only defaults if admin, the whole header part will be removed.
74            // This is a bit hacky ...
75            ob_clean();
76        }
77    }
78
79    /**
80     * This function serves debugging purposes and has to be enabled in the register phase
81     *
82     * @param Doku_Event $event  event object by reference
83     * @param mixed      $param  [the parameters passed as fifth argument to register_hook() when this
84     *                           handler was registered]
85     * @return void
86     */
87    public function handle_use_cache(Doku_Event &$event, $param) {
88        $event->preventDefault();
89        return false;
90    }
91
92    /**
93     * Finally, handle the JS script list. The script would be fit to do even more stuff / types
94     * but handles only admin and default currently.
95     *
96     * @param Doku_Event $event  event object by reference
97     * @param mixed      $param  [the parameters passed as fifth argument to register_hook() when this
98     *                           handler was registered]
99     * @return void
100     */
101    public function handle_js_script_list(Doku_Event &$event, $param) {
102        global $INPUT;
103
104        switch( $INPUT->str('type') ) {
105
106            case 'admin':
107                // Filter for admin scripts
108                $event->data = array_filter( $event->data, array($this, 'filter_admin_scripts') );
109                break;
110
111            default:
112                // Filter for the-rest-if-us scripts
113                $event->data = array_filter( $event->data, array($this, 'filter_user_scripts') );
114        }
115    }
116
117    /**
118     * A simple filter function to check the input string against a list of path-parts that are allowed
119     *
120     * @param string    $str   the script file to check against the list
121     * @param mixed     $list  the list of path parts to test
122     * @return boolean
123     */
124    private function includeFilter( $str, $list ) {
125
126        foreach( $list as $entry ) {
127            if ( strpos( $str, $entry ) ) return true;
128        }
129
130        return false;
131    }
132
133    /**
134     * A simple filter function to check the input string against a list of path-parts that are allowed
135     * Is the inversion of includeFilter( $str, $list )
136     *
137     * @param string    $str   the script file to check against the list
138     * @param mixed     $list  the list of path parts to test
139     * @return boolean
140     */
141    private function excludeFilter( $str, $list ) {
142        return !$this->includeFilter( $str, $list );
143    }
144
145    /**
146     * Filters scripts that are intended for admins only
147     *
148     * @param string    $script   the script file to check against the list
149     * @return boolean
150     */
151    private function filter_admin_scripts( $script ) {
152        return $this->includeFilter( $script, array(
153
154            '/lib/scripts/fileuploader',
155            'jquery.ui.datepicker.js',
156            '/lib/scripts/',
157
158            // Plugins
159            '/lib/plugins/tag/',
160            '/lib/plugins/extension/',
161            '/lib/plugins/move/',
162            '/lib/plugins/styling/',
163            '/lib/plugins/sectionedit/',
164            '/lib/plugins/searchindex/',
165            '/lib/plugins/acl/',
166            '/lib/plugins/pagequery/',
167            '/lib/plugins/colorpicker/',
168            '/lib/plugins/sync/',
169            '/lib/plugins/multiorphan/',
170            '/lib/plugins/color/',
171            '/lib/plugins/usermanager/',
172            '/lib/plugins/edittable/',
173            '/lib/plugins/imagemapping/',
174            '/lib/plugins/edittable/',
175            '/lib/plugins/include/',
176            '/lib/plugins/toctweak/',
177
178        )) && $this->excludeFilter( $script, array(
179            'jquery.cookie.js',
180        ));
181    }
182
183    /**
184     * Filters scripts that are intended for users only
185     *
186     * @param string    $script   the script file to check against the list
187     * @return boolean
188     */
189    private function filter_user_scripts( $script ) {
190        return !$this->filter_admin_scripts( $script );
191    }
192}
193
194// vim:ts=4:sw=4:et:
195