xref: /plugin/combo/action/css.php (revision 04fd306c7c155fa133ebb3669986875d65988276)
1007225e5Sgerardnico<?php
2007225e5Sgerardnico
3007225e5Sgerardnico
4*04fd306cSNickeauuse ComboStrap\Api\ApiRouter;
5*04fd306cSNickeauuse ComboStrap\ArrayUtility;
6*04fd306cSNickeauuse ComboStrap\ExceptionNotFound;
7*04fd306cSNickeauuse ComboStrap\ExecutionContext;
8*04fd306cSNickeauuse ComboStrap\Identity;
9007225e5Sgerardnicouse ComboStrap\PluginUtility;
10007225e5Sgerardnico
112128d419Sgerardnico
12007225e5Sgerardnico/**
13007225e5Sgerardnico * Class action_plugin_combo_css
14007225e5Sgerardnico * Delete Backend CSS for front-end
15007225e5Sgerardnico *
16007225e5Sgerardnico * Bug:
17007225e5Sgerardnico *   * https://datacadamia.comlighthouse - no interwiki
18007225e5Sgerardnico *
19007225e5Sgerardnico * A call to /lib/exe/css.php?t=template&tseed=time()
20007225e5Sgerardnico *
21007225e5Sgerardnico *    * t is the template
22007225e5Sgerardnico *
23007225e5Sgerardnico *    * tseed is md5 of modified time of the below config file set at {@link tpl_metaheaders()}
24007225e5Sgerardnico *
25007225e5Sgerardnico *        * conf/dokuwiki.php
26007225e5Sgerardnico *        * conf/local.php
27007225e5Sgerardnico *        * conf/local.protected.php
28007225e5Sgerardnico *        * conf/tpl/strap/style.ini
29007225e5Sgerardnico *
30007225e5Sgerardnico */
31007225e5Sgerardnicoclass action_plugin_combo_css extends DokuWiki_Action_Plugin
32007225e5Sgerardnico{
33007225e5Sgerardnico
34007225e5Sgerardnico    /**
35*04fd306cSNickeau     * If anonymous
36007225e5Sgerardnico     */
37007225e5Sgerardnico    const CONF_ENABLE_MINIMAL_FRONTEND_STYLESHEET = 'enableMinimalFrontEndStylesheet';
38*04fd306cSNickeau    /**
39*04fd306cSNickeau     * If anonymous
40*04fd306cSNickeau     */
41007225e5Sgerardnico    const CONF_DISABLE_DOKUWIKI_STYLESHEET = 'disableDokuwikiStylesheet';
42007225e5Sgerardnico
43007225e5Sgerardnico    /**
44*04fd306cSNickeau     * Anonymous or not
45007225e5Sgerardnico     */
46*04fd306cSNickeau    const ANONYMOUS_KEY = 'ano';
47*04fd306cSNickeau    /**
48*04fd306cSNickeau     * Combo theme or not
49*04fd306cSNickeau     */
50*04fd306cSNickeau    const COMBO_THEME_ENABLED_KEY = "combo-theme-enabled";
51*04fd306cSNickeau
52*04fd306cSNickeau    /**
53*04fd306cSNickeau     * When anonymous, apply a minimal frontend optimization ?
54*04fd306cSNickeau     * (ie without Jquery used mostly for admin, ...)
55*04fd306cSNickeau     */
56*04fd306cSNickeau    const ANONYMOUS_MINIMAL_FRONT_KEY = "minimal-front";
57*04fd306cSNickeau
58007225e5Sgerardnico
59007225e5Sgerardnico    /**
60007225e5Sgerardnico     * List of excluded plugin
61007225e5Sgerardnico     */
62007225e5Sgerardnico    const EXCLUDED_PLUGINS = array(
63007225e5Sgerardnico        "acl",
64007225e5Sgerardnico        "authplain",
65007225e5Sgerardnico        "changes",
66007225e5Sgerardnico        "config",
67007225e5Sgerardnico        "extension",
68007225e5Sgerardnico        "info",
69007225e5Sgerardnico        "move",
70007225e5Sgerardnico        "popularity",
71007225e5Sgerardnico        "revert",
72007225e5Sgerardnico        "safefnrecode",
73007225e5Sgerardnico        "searchindex",
74007225e5Sgerardnico        "sqlite",
75007225e5Sgerardnico        "upgrade",
76007225e5Sgerardnico        "usermanager"
77007225e5Sgerardnico    );
78007225e5Sgerardnico
79*04fd306cSNickeau
80*04fd306cSNickeau
81007225e5Sgerardnico    /**
82007225e5Sgerardnico     * Registers a callback function for a given event
83007225e5Sgerardnico     *
84007225e5Sgerardnico     * @param Doku_Event_Handler $controller DokuWiki's event controller object
85007225e5Sgerardnico     * @return void
86007225e5Sgerardnico     *
87007225e5Sgerardnico     * To fire this event
88007225e5Sgerardnico     *   * Ctrl+Shift+R to disable browser cache
89007225e5Sgerardnico     *
90007225e5Sgerardnico     */
91007225e5Sgerardnico    public function register(Doku_Event_Handler $controller)
92007225e5Sgerardnico    {
93007225e5Sgerardnico
94*04fd306cSNickeau        $requestScript = PluginUtility::getRequestScript();
95*04fd306cSNickeau        switch ($requestScript) {
96*04fd306cSNickeau            case "css.php":
97007225e5Sgerardnico                /**
98007225e5Sgerardnico                 * The process follows the following steps:
99007225e5Sgerardnico                 *     * With CSS_STYLES_INCLUDED, you choose the file that you want
100007225e5Sgerardnico                 *     * then with CSS_CACHE_USE, you can change the cache key name
101007225e5Sgerardnico                 */
102007225e5Sgerardnico                $controller->register_hook('CSS_STYLES_INCLUDED', 'BEFORE', $this, 'handle_front_css_styles');
103007225e5Sgerardnico                $controller->register_hook('CSS_CACHE_USE', 'BEFORE', $this, 'handle_css_cache');
104*04fd306cSNickeau                break;
105*04fd306cSNickeau            case "doku.php":
106*04fd306cSNickeau                /**
107*04fd306cSNickeau                 * Add property to the css URL to create multiple CSS file:
108*04fd306cSNickeau                 *   * public/private (anonymous/loggedIn)
109*04fd306cSNickeau                 */
110*04fd306cSNickeau                $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'handle_css_metaheader');
111*04fd306cSNickeau                break;
112007225e5Sgerardnico        }
113007225e5Sgerardnico
114007225e5Sgerardnico
115007225e5Sgerardnico    }
116007225e5Sgerardnico
117007225e5Sgerardnico    /**
118007225e5Sgerardnico     * @param Doku_Event $event
119007225e5Sgerardnico     * @param $param
120007225e5Sgerardnico     *
121007225e5Sgerardnico     * Add query parameter to the CSS header call. ie
122007225e5Sgerardnico     * <link rel="preload" href="/lib/exe/css.php?t=template&tseed=8e31090353c8fcf80aa6ff0ea9bf3746" as="style">
123007225e5Sgerardnico     * to indicate if the page that calls the css is from a user that is logged in or not:
124007225e5Sgerardnico     *   * public vs private
125007225e5Sgerardnico     *   * ie frontend vs backend
126007225e5Sgerardnico     */
127007225e5Sgerardnico    public function handle_css_metaheader(Doku_Event &$event, $param)
128007225e5Sgerardnico    {
129007225e5Sgerardnico
130*04fd306cSNickeau        $executionContext = ExecutionContext::getActualOrCreateFromEnv();
131*04fd306cSNickeau        $config = $executionContext->getConfig();
132*04fd306cSNickeau        $disableDokuwikiStylesheetConf = $config->getBooleanValue(self::CONF_DISABLE_DOKUWIKI_STYLESHEET, false);
133*04fd306cSNickeau        $isExecutingTheme = $executionContext->isExecutingPageTemplate();
134*04fd306cSNickeau
135*04fd306cSNickeau        $disableDokuwikiStylesheet = $disableDokuwikiStylesheetConf && $isExecutingTheme;
136*04fd306cSNickeau
137*04fd306cSNickeau
138007225e5Sgerardnico        $links = &$event->data['link'];
139007225e5Sgerardnico        foreach ($links as $key => &$link) {
140*04fd306cSNickeau
141007225e5Sgerardnico            $pos = strpos($link['href'], 'css.php');
142*04fd306cSNickeau            if ($pos === false) {
143*04fd306cSNickeau                continue;
144*04fd306cSNickeau            }
145*04fd306cSNickeau
146*04fd306cSNickeau            if (Identity::isAnonymous()) {
147007225e5Sgerardnico
148007225e5Sgerardnico                if ($disableDokuwikiStylesheet) {
149007225e5Sgerardnico                    unset($links[$key]);
150007225e5Sgerardnico                    return;
151007225e5Sgerardnico                }
152007225e5Sgerardnico
153*04fd306cSNickeau                $link['href'] .= '&' . self::ANONYMOUS_KEY;
154*04fd306cSNickeau                $isEnabledMinimalFrontEnd = ExecutionContext::getActualOrCreateFromEnv()
155*04fd306cSNickeau                    ->getConfig()
156*04fd306cSNickeau                    ->getBooleanValue(self::CONF_ENABLE_MINIMAL_FRONTEND_STYLESHEET, 1);
157*04fd306cSNickeau
158*04fd306cSNickeau                if($isEnabledMinimalFrontEnd){
159*04fd306cSNickeau                    $link['href'] .= '&' . self::ANONYMOUS_MINIMAL_FRONT_KEY;
160*04fd306cSNickeau                }
161007225e5Sgerardnico            }
162007225e5Sgerardnico
163*04fd306cSNickeau            if ($executionContext->isExecutingPageTemplate()) {
164*04fd306cSNickeau                $link['href'] .= '&' . self::COMBO_THEME_ENABLED_KEY;
165007225e5Sgerardnico            }
166*04fd306cSNickeau
167*04fd306cSNickeau
168*04fd306cSNickeau
169007225e5Sgerardnico        }
170007225e5Sgerardnico
171007225e5Sgerardnico    }
172007225e5Sgerardnico
173007225e5Sgerardnico    /**
174007225e5Sgerardnico     *
175007225e5Sgerardnico     * @param Doku_Event $event event object by reference
176007225e5Sgerardnico     * @param mixed $param [the parameters passed as fifth argument to register_hook() when this
177007225e5Sgerardnico     *                           handler was registered]
178007225e5Sgerardnico     * @return void
179007225e5Sgerardnico     *
180007225e5Sgerardnico     * Change the key of the cache.
181007225e5Sgerardnico     *
182007225e5Sgerardnico     * The default key can be seen in the {@link css_out()} function
183007225e5Sgerardnico     * when a new cache is created (ie new cache(key,ext)
184007225e5Sgerardnico     *
185007225e5Sgerardnico     * This is only called when this is a front call, see {@link register()}
186007225e5Sgerardnico     *
187007225e5Sgerardnico     * @see <a href="https://github.com/i-net-software/dokuwiki-plugin-lightweightcss/blob/master/action.php#L122">Credits</a>
188007225e5Sgerardnico     */
189007225e5Sgerardnico    public function handle_css_cache(Doku_Event &$event, $param)
190007225e5Sgerardnico    {
191007225e5Sgerardnico
192*04fd306cSNickeau        /**
193*04fd306cSNickeau         * Add Anonymous and comboTheme in the cache key
194*04fd306cSNickeau         * if present
195*04fd306cSNickeau         */
196*04fd306cSNickeau        $keys = [self::ANONYMOUS_KEY, self::COMBO_THEME_ENABLED_KEY, self::ANONYMOUS_MINIMAL_FRONT_KEY];
197*04fd306cSNickeau        $foundKeys = [];
198*04fd306cSNickeau        foreach ($keys as $key) {
199*04fd306cSNickeau            if (ApiRouter::hasRequestParameter($key)) {
200*04fd306cSNickeau                $foundKeys[] = $key;
201*04fd306cSNickeau            }
202*04fd306cSNickeau        }
203*04fd306cSNickeau        if (empty($foundKeys)) {
204*04fd306cSNickeau            return;
205*04fd306cSNickeau        }
206*04fd306cSNickeau
207*04fd306cSNickeau        /**
208*04fd306cSNickeau         * Add Anonymous and comboTheme in the cache key
209*04fd306cSNickeau         * if present
210*04fd306cSNickeau         */
211*04fd306cSNickeau        $event->data->key .= implode('.', $foundKeys);
212007225e5Sgerardnico        $event->data->cache = getCacheName($event->data->key, $event->data->ext);
213*04fd306cSNickeau
214007225e5Sgerardnico
215007225e5Sgerardnico    }
216007225e5Sgerardnico
217007225e5Sgerardnico    /**
218007225e5Sgerardnico     * Handle the front CSS script list. The script would be fit to do even more stuff / types
219007225e5Sgerardnico     * but handles only admin and default currently.
220007225e5Sgerardnico     *
221007225e5Sgerardnico     * @param Doku_Event $event event object by reference
222007225e5Sgerardnico     * @param mixed $param [the parameters passed as fifth argument to register_hook() when this
223007225e5Sgerardnico     *                           handler was registered]
224007225e5Sgerardnico     * @return void
225007225e5Sgerardnico     */
226007225e5Sgerardnico    public function handle_front_css_styles(Doku_Event &$event, $param)
227007225e5Sgerardnico    {
228*04fd306cSNickeau
229*04fd306cSNickeau        $isAnonymous = ApiRouter::hasRequestParameter(self::ANONYMOUS_KEY);
230*04fd306cSNickeau        $isThemeEnabled = ApiRouter::hasRequestParameter(self::COMBO_THEME_ENABLED_KEY);
231*04fd306cSNickeau        $isMinimalFrontEnd = ApiRouter::hasRequestParameter(self::ANONYMOUS_MINIMAL_FRONT_KEY);
232*04fd306cSNickeau        if (!$isAnonymous && !$isThemeEnabled) {
233007225e5Sgerardnico            return;
234007225e5Sgerardnico        }
235007225e5Sgerardnico
236007225e5Sgerardnico
237*04fd306cSNickeau
238007225e5Sgerardnico        /**
239007225e5Sgerardnico         * There is one call by:
240*04fd306cSNickeau         *   * mediatype (ie screen, all, print, speech)
241007225e5Sgerardnico         *   * and one call for the dokuwiki default
242007225e5Sgerardnico         */
243007225e5Sgerardnico        switch ($event->data['mediatype']) {
244007225e5Sgerardnico
245007225e5Sgerardnico            case 'print':
246007225e5Sgerardnico            case 'screen':
247007225e5Sgerardnico            case 'all':
248007225e5Sgerardnico                $filteredDataFiles = array();
249007225e5Sgerardnico                $files = $event->data['files'];
250007225e5Sgerardnico                foreach ($files as $file => $fileDirectory) {
251*04fd306cSNickeau
252*04fd306cSNickeau                    // template style
253*04fd306cSNickeau                    if ($isThemeEnabled && strpos($fileDirectory, 'lib/tpl')) {
254007225e5Sgerardnico                        continue;
255007225e5Sgerardnico                    }
256*04fd306cSNickeau
257*04fd306cSNickeau                    // Lib styles
258*04fd306cSNickeau                    if (($isThemeEnabled || $isMinimalFrontEnd) && strpos($fileDirectory, 'lib/styles')) {
259*04fd306cSNickeau                        // Geshi (syntax highlighting) and basic style of doku, we don't keep.
260*04fd306cSNickeau                        continue;
261*04fd306cSNickeau                    }
262*04fd306cSNickeau
263007225e5Sgerardnico                    // No Css from lib scripts
264007225e5Sgerardnico                    // Jquery is here
265*04fd306cSNickeau                    if (($isThemeEnabled || $isMinimalFrontEnd) && $isAnonymous && strpos($fileDirectory, 'lib/scripts')) {
266*04fd306cSNickeau                        // Jquery is needed for admin (not anonymous)
267*04fd306cSNickeau                        // scripts\jquery\jquery-ui-theme\smoothness.css
268007225e5Sgerardnico                        continue;
269007225e5Sgerardnico                    }
270*04fd306cSNickeau
271*04fd306cSNickeau                    if (($isThemeEnabled || $isMinimalFrontEnd)) {
272007225e5Sgerardnico                        // Excluded
273007225e5Sgerardnico                        $isExcluded = false;
274007225e5Sgerardnico                        foreach (self::EXCLUDED_PLUGINS as $plugin) {
275007225e5Sgerardnico                            if (strpos($file, 'lib/plugins/' . $plugin)) {
276007225e5Sgerardnico                                $isExcluded = true;
277007225e5Sgerardnico                                break;
278007225e5Sgerardnico                            }
279007225e5Sgerardnico                        }
280007225e5Sgerardnico                        if (!$isExcluded) {
281007225e5Sgerardnico                            $filteredDataFiles[$file] = $fileDirectory;
282007225e5Sgerardnico                        }
283007225e5Sgerardnico                    }
284*04fd306cSNickeau                }
285007225e5Sgerardnico
286007225e5Sgerardnico                $event->data['files'] = $filteredDataFiles;
287007225e5Sgerardnico
288007225e5Sgerardnico                break;
289007225e5Sgerardnico
290007225e5Sgerardnico            case 'speech':
291*04fd306cSNickeau                if (!PluginUtility::isTest()) {
292007225e5Sgerardnico                    $event->preventDefault();
293*04fd306cSNickeau                }
294007225e5Sgerardnico                break;
295007225e5Sgerardnico            case 'DW_DEFAULT':
296007225e5Sgerardnico                // Interwiki styles are here, we keep (in the lib/css.php file)
297007225e5Sgerardnico                break;
298007225e5Sgerardnico
299007225e5Sgerardnico        }
300007225e5Sgerardnico    }
301007225e5Sgerardnico
302007225e5Sgerardnico
303007225e5Sgerardnico}
304007225e5Sgerardnico
305007225e5Sgerardnico
306