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