1<?php 2/** 3 * DokuWiki Action Plugin LoadSkin 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @author Michael Klier <chi@chimeric.de> 7 * @author Anika Henke <anika@selfthinker.org> 8 */ 9// must be run within Dokuwiki 10if(!defined('DOKU_INC')) die(); 11 12if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN', DOKU_INC.'lib/plugins/'); 13if(!defined('DOKU_LF')) define('DOKU_LF', "\n"); 14 15require_once(DOKU_PLUGIN.'action.php'); 16 17/** 18 * All DokuWiki plugins to interfere with the event system 19 * need to inherit from this class 20 */ 21class action_plugin_loadskin extends DokuWiki_Action_Plugin { 22 23 // register hook 24 public function register(Doku_Event_Handler $controller) { 25 $controller->register_hook('DOKUWIKI_STARTED', 'BEFORE', $this, '_handleConf'); 26 $controller->register_hook('MEDIAMANAGER_STARTED', 'BEFORE', $this, '_handleConf'); 27 $controller->register_hook('DETAIL_STARTED', 'BEFORE', $this, '_handleConf'); 28 $controller->register_hook('TPL_CONTENT_DISPLAY', 'BEFORE', $this, '_handleContent', array()); 29 // only needed for not yet up-to-date templates: 30 $controller->register_hook('DOKUWIKI_STARTED', 'AFTER', $this, '_defineConstants'); 31 $controller->register_hook('MEDIAMANAGER_STARTED', 'AFTER', $this, '_defineConstants'); 32 $controller->register_hook('DETAIL_STARTED', 'AFTER', $this, '_defineConstants'); 33 } 34 35 /** 36 * Define DOKU_TPL and DOKU_TPLINC after $conf['template'] has been overwritten 37 * (this still needs the original constant definition in init.php to be removed) 38 * @deprecated DOKU_TPL and DOKU_TPLINC are deprecated since Adora Belle 39 * 40 * @author Anika Henke <anika@selfthinker.org> 41 */ 42 public function _defineConstants(Doku_Event $event, $param) { 43 global $conf; 44 45 // define Template baseURL 46 if(!defined('DOKU_TPL')) 47 define('DOKU_TPL', DOKU_BASE.'lib/tpl/'.$conf['template'].'/'); 48 49 // define real Template directory 50 if(!defined('DOKU_TPLINC')) 51 define('DOKU_TPLINC', DOKU_INC.'lib/tpl/'.$conf['template'].'/'); 52 } 53 54 /** 55 * Overwrites the $conf['template'] setting 56 * 57 * @author Michael Klier <chi@chimeric.de> 58 * @author Anika Henke <anika@selfthinker.org> 59 */ 60 public function _handleConf(Doku_Event $event, $param) { 61 global $conf; 62 global $ACT; 63 64 // store original template in helper attribute 65 $helper = $this->loadHelper('loadskin', true); 66 $helper->origTpl = $conf['template']; 67 68 // set template 69 $tpl = $this->_getTpl(); 70 $inAdmin = $ACT == 'admin'; 71 $allowInAdmin = $this->getConf('allowInAdmin'); 72 if($tpl && (!$inAdmin || ($inAdmin && $allowInAdmin))) { 73 $conf['template'] = $tpl; 74 } 75 } 76 77 /** 78 * Output the template switcher if 'automaticOutput' is on 79 * 80 * @author Anika Henke <anika@selfthinker.org> 81 */ 82 public function _handleContent(Doku_Event $event, $param){ 83 // @todo: should ideally be in showTemplateSwitcher() 84 $isOverwrittenByAdmin = !$this->getConf('preferUserChoice') && $this->_getTplPerNamespace(); 85 86 if ($this->getConf('automaticOutput') && !$isOverwrittenByAdmin) { 87 $helper = $this->loadHelper('loadskin', true); 88 $event->data = $helper->showTemplateSwitcher().$event->data; 89 } 90 } 91 92 /** 93 * Checks if a given page should use a different template then the default 94 * 95 * @author Michael Klier <chi@chimeric.de> 96 * @author Anika Henke <anika@selfthinker.org> 97 */ 98 private function _getTpl() { 99 $tplPerUser = $this->_getTplPerUser(); 100 $tplPerNamespace = $this->_getTplPerNamespace(); 101 102 if($this->getConf('preferUserChoice')) { 103 if($tplPerUser) 104 return $tplPerUser; 105 if($tplPerNamespace) 106 return $tplPerNamespace; 107 } else { 108 if($tplPerNamespace) 109 return $tplPerNamespace; 110 if($tplPerUser) 111 return $tplPerUser; 112 } 113 114 return false; 115 } 116 117 /** 118 * Get template from session and/or user config 119 * 120 * @author Anika Henke <anika@selfthinker.org> 121 */ 122 private function _getTplPerUser() { 123 global $INPUT; 124 125 // get all available templates 126 $helper = $this->loadHelper('loadskin', true); 127 $tpls = $helper->getTemplates(); 128 129 $mobileSwitch = $this->getConf('mobileSwitch'); 130 $user = $_SERVER['REMOTE_USER']; 131 132 $tplRequest = $INPUT->str('tpl'); 133 $actSelect = $INPUT->str('act') && ($INPUT->str('act') == 'select'); 134 135 // if template switcher was used 136 if ($tplRequest && $actSelect && (in_array($tplRequest, $tpls) || ($tplRequest == '*') )) { 137 // hidden way of deleting the cookie and config values 138 if ($tplRequest == '*') 139 $tplRequest = false; // not backwards-compatible, will only work with core PR #1129 140 // store in cookie 141 set_doku_pref('loadskinTpl', $tplRequest); 142 // if registered user, store also in conf file (not for mobile switcher) 143 if ($user && !$mobileSwitch) 144 $this->_tplUserConfig('set', $user, $tplRequest); 145 return $tplRequest; 146 } 147 148 $tplUser = $this->_tplUserConfig('get', $user);// from user conf file 149 $tplCookie = get_doku_pref('loadskinTpl', ''); 150 // if logged in and user is in conf (not for mobile) 151 if ($user && $tplUser && in_array($tplUser, $tpls) && !$mobileSwitch){ 152 if ($tplCookie && ($tplCookie == $tplUser)) 153 return $tplCookie; 154 // store in cookie 155 set_doku_pref('loadskinTpl', $tplUser); 156 return $tplUser; 157 } 158 // if template is stored in cookie 159 if ($tplCookie && in_array($tplCookie, $tpls)) 160 return $tplCookie; 161 162 // if viewed on a mobile and mobile switcher is used, set mobile template as default 163 global $INFO; 164 $mobileTpl = $this->getConf('mobileTemplate'); 165 if ($mobileTpl && $INFO['ismobile']) { 166 set_doku_pref('loadskinTpl', $mobileTpl); 167 return $mobileTpl; 168 } 169 170 return false; 171 } 172 173 /** 174 * Get template from namespace/page and config 175 * 176 * @author Michael Klier <chi@chimeric.de> 177 * @author Anika Henke <anika@selfthinker.org> 178 */ 179 private function _getTplPerNamespace() { 180 global $ID; 181 $config = DOKU_CONF.'loadskin.conf'; 182 183 if(@file_exists($config)) { 184 $data = unserialize(io_readFile($config, false)); 185 $id = $ID; 186 187 // remove language path from $id before you check for a match (it would only be at the start) 188 if ($this->getConf('inheritInTranslations') && !plugin_isdisabled('translation')) { 189 $transplugin = &plugin_load('helper', 'translation'); 190 $langPath = $transplugin->getLangPart($id).':'; 191 $pos = strpos($id, $langPath); 192 if (($pos !== false) && ($pos == 0)) 193 $id = str_ireplace($langPath, '', $id); 194 } 195 196 if($data[$id]) return $data[$id]; 197 198 $path = explode(':', $id); 199 200 while(count($path) > 0) { 201 $id = implode(':', $path); 202 if($data[$id]) return $data[$id]; 203 array_pop($path); 204 } 205 } 206 return false; 207 } 208 209 /** 210 * Get/set template for user in config 211 * 212 * @author Anika Henke <anika@selfthinker.org> 213 */ 214 private function _tplUserConfig($act, $user, $tpl='') { 215 $data = array(); 216 $userConf = DOKU_CONF.'loadskin.users.conf'; 217 if(@file_exists($userConf)) { 218 $data = unserialize(io_readFile($userConf, false)); 219 if ($act == 'get') 220 return $data[$user]; 221 unset($data[$user]); 222 } 223 if ($act == 'get') 224 return false; 225 // keep line deleted if $tpl is empty 226 if ($tpl) 227 $data[$user] = $tpl; 228 io_saveFile($userConf, serialize($data)); 229 } 230} 231 232// vim:ts=4:sw=4: 233