10a7415d3SAndreas Gohr<?php 20a7415d3SAndreas Gohr/** 3af1904f9SAndreas Gohr * Translation Plugin: Simple multilanguage plugin 40a7415d3SAndreas Gohr * 50a7415d3SAndreas Gohr * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 60a7415d3SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 70a7415d3SAndreas Gohr * @author Guy Brand <gb@isis.u-strasbg.fr> 80a7415d3SAndreas Gohr */ 90a7415d3SAndreas Gohr 100a7415d3SAndreas Gohr// must be run within Dokuwiki 110a7415d3SAndreas Gohrif(!defined('DOKU_INC')) die(); 120a7415d3SAndreas Gohr 13*3b18cb70SGerry Weißbachclass action_plugin_autotranslation extends \dokuwiki\Extension\ActionPlugin { 140a7415d3SAndreas Gohr 150a7415d3SAndreas Gohr /** 16c54240efSGuillaume Turri * For the helper plugin 1725fca7bdSGerry Weißbach * @var helper_plugin_autotranslation 18af1904f9SAndreas Gohr */ 195ceaa3d5SGerry Weißbach private $helper = null; 20af1904f9SAndreas Gohr 215ceaa3d5SGerry Weißbach private $locale; 22ec6cbde6SDominik Eckelmann 23af1904f9SAndreas Gohr /** 24af1904f9SAndreas Gohr * Constructor. Load helper plugin 25af1904f9SAndreas Gohr */ 26488e4722SAndreas Gohr function __construct() { 275aa700abSGerry Weißbach $this->helper = plugin_load('helper', 'autotranslation'); 28af1904f9SAndreas Gohr } 29af1904f9SAndreas Gohr 30af1904f9SAndreas Gohr /** 31c54240efSGuillaume Turri * Register the events 320a7415d3SAndreas Gohr */ 3343ffc77dSGerry Weißbach function register(Doku_Event_Handler $controller) { 34ec6cbde6SDominik Eckelmann $scriptName = basename($_SERVER['PHP_SELF']); 35e5e7e41dSAndreas Gohr 36c54240efSGuillaume Turri // should the lang be applied to UI? 3734591120SDominik Eckelmann if($this->getConf('translateui')) { 38ec6cbde6SDominik Eckelmann switch($scriptName) { 39ec6cbde6SDominik Eckelmann case 'js.php': 40ec6cbde6SDominik Eckelmann $controller->register_hook('INIT_LANG_LOAD', 'BEFORE', $this, 'translation_js'); 41db7c51b4SAndreas Gohr $controller->register_hook('JS_CACHE_USE', 'BEFORE', $this, 'translation_jscache'); 42ec6cbde6SDominik Eckelmann break; 43ec6cbde6SDominik Eckelmann 44ec6cbde6SDominik Eckelmann case 'ajax.php': 45ec6cbde6SDominik Eckelmann $controller->register_hook('INIT_LANG_LOAD', 'BEFORE', $this, 'translate_media_manager'); 46ec6cbde6SDominik Eckelmann break; 47ec6cbde6SDominik Eckelmann 48ec6cbde6SDominik Eckelmann case 'mediamanager.php': 49ec6cbde6SDominik Eckelmann $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'setJsCacheKey'); 50ec6cbde6SDominik Eckelmann break; 51ec6cbde6SDominik Eckelmann 52ec6cbde6SDominik Eckelmann default: 53ec6cbde6SDominik Eckelmann $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'setJsCacheKey'); 54ec6cbde6SDominik Eckelmann } 550a7415d3SAndreas Gohr } 5634591120SDominik Eckelmann 5734591120SDominik Eckelmann if($scriptName !== 'js.php' && $scriptName !== 'ajax.php') { 5834591120SDominik Eckelmann $controller->register_hook('DOKUWIKI_STARTED', 'BEFORE', $this, 'translation_hook'); 5934591120SDominik Eckelmann $controller->register_hook('MEDIAMANAGER_STARTED', 'BEFORE', $this, 'translation_hook'); 6034591120SDominik Eckelmann } 6134591120SDominik Eckelmann 62af1904f9SAndreas Gohr $controller->register_hook('SEARCH_QUERY_PAGELOOKUP', 'AFTER', $this, 'translation_search'); 63cabcc95dSDominik Eckelmann $controller->register_hook('COMMON_PAGETPL_LOAD', 'AFTER', $this, 'page_template_replacement'); 64cabcc95dSDominik Eckelmann } 65cabcc95dSDominik Eckelmann 66bbe70520SAndreas Gohr /** 67bbe70520SAndreas Gohr * Hook Callback. Make current language available as page template placeholder and handle 68bbe70520SAndreas Gohr * original language copying 69bbe70520SAndreas Gohr * 70bbe70520SAndreas Gohr * @param $event 71bbe70520SAndreas Gohr * @param $args 72bbe70520SAndreas Gohr */ 735aa700abSGerry Weißbach function page_template_replacement(Doku_Event $event, $args) { 74cabcc95dSDominik Eckelmann global $ID; 75bbe70520SAndreas Gohr 76bbe70520SAndreas Gohr // load orginal content as template? 77c54240efSGuillaume Turri if($this->getConf('copytrans') && $this->helper->istranslatable($ID, false)) { 78bbe70520SAndreas Gohr // look for existing translations 79c54240efSGuillaume Turri $translations = $this->helper->getAvailableTranslations($ID); 80bbe70520SAndreas Gohr if($translations) { 81bbe70520SAndreas Gohr // find original language (might've been provided via parameter or use first translation) 82bbe70520SAndreas Gohr $orig = (string) $_REQUEST['fromlang']; 83bbe70520SAndreas Gohr if(!$orig) $orig = array_shift(array_keys($translations)); 84bbe70520SAndreas Gohr 85bbe70520SAndreas Gohr // load file 86bbe70520SAndreas Gohr $origfile = $translations[$orig]; 87bbe70520SAndreas Gohr $event->data['tpl'] = io_readFile(wikiFN($origfile)); 88bbe70520SAndreas Gohr 89bbe70520SAndreas Gohr // prefix with warning 90bbe70520SAndreas Gohr $warn = io_readFile($this->localFN('totranslate')); 91bbe70520SAndreas Gohr if($warn) $warn .= "\n\n"; 92bbe70520SAndreas Gohr $event->data['tpl'] = $warn . $event->data['tpl']; 93bbe70520SAndreas Gohr 94bbe70520SAndreas Gohr // show user a choice of translations if any 95bbe70520SAndreas Gohr if(count($translations) > 1) { 96bbe70520SAndreas Gohr $links = array(); 97bbe70520SAndreas Gohr foreach($translations as $t => $l) { 98c54240efSGuillaume Turri $links[] = '<a href="' . wl($ID, array('do' => 'edit', 'fromlang' => $t)) . '">' . $this->helper->getLocalName($t) . '</a>'; 99bbe70520SAndreas Gohr } 100bbe70520SAndreas Gohr 1015fd0d0d1SAndreas Gohr msg( 1025fd0d0d1SAndreas Gohr sprintf( 103bbe70520SAndreas Gohr $this->getLang('transloaded'), 104c54240efSGuillaume Turri $this->helper->getLocalName($orig), 105bbe70520SAndreas Gohr join(', ', $links) 106bbe70520SAndreas Gohr ) 107bbe70520SAndreas Gohr ); 108bbe70520SAndreas Gohr } 109bbe70520SAndreas Gohr 110bbe70520SAndreas Gohr } 111bbe70520SAndreas Gohr } 112bbe70520SAndreas Gohr 113bbe70520SAndreas Gohr // apply placeholders 114c54240efSGuillaume Turri $event->data['tpl'] = str_replace('@LANG@', $this->helper->realLC(''), $event->data['tpl']); 115c54240efSGuillaume Turri $event->data['tpl'] = str_replace('@TRANS@', $this->helper->getLangPart($ID), $event->data['tpl']); 1160a7415d3SAndreas Gohr } 1170a7415d3SAndreas Gohr 118bbe70520SAndreas Gohr /** 119bbe70520SAndreas Gohr * Hook Callback. Load correct translation when loading JavaScript 120bbe70520SAndreas Gohr * 121bbe70520SAndreas Gohr * @param $event 122bbe70520SAndreas Gohr * @param $args 123bbe70520SAndreas Gohr */ 1245aa700abSGerry Weißbach function translation_js(Doku_Event $event, $args) { 125bbe70520SAndreas Gohr global $conf; 126bbe70520SAndreas Gohr if(!isset($_GET['lang'])) return; 1275e1f71acSGuillaume Turri if(!in_array($_GET['lang'], $this->helper->translations)) return; 128bbe70520SAndreas Gohr $lang = $_GET['lang']; 129bbe70520SAndreas Gohr $event->data = $lang; 130bbe70520SAndreas Gohr $conf['lang'] = $lang; 131bbe70520SAndreas Gohr } 132bbe70520SAndreas Gohr 133bbe70520SAndreas Gohr /** 134bbe70520SAndreas Gohr * Hook Callback. Pass language code to JavaScript dispatcher 135bbe70520SAndreas Gohr * 136bbe70520SAndreas Gohr * @param $event 137bbe70520SAndreas Gohr * @param $args 138bbe70520SAndreas Gohr * @return bool 139bbe70520SAndreas Gohr */ 1405aa700abSGerry Weißbach function setJsCacheKey(Doku_Event $event, $args) { 141ec6cbde6SDominik Eckelmann if(!isset($this->locale)) return false; 142ec6cbde6SDominik Eckelmann $count = count($event->data['script']); 143ec6cbde6SDominik Eckelmann for($i = 0; $i < $count; $i++) { 14443ffc77dSGerry Weißbach if(!empty($event->data['script'][$i]['src']) && strpos($event->data['script'][$i]['src'], '/lib/exe/js.php') !== false) { 145db7c51b4SAndreas Gohr $event->data['script'][$i]['src'] .= '&lang=' . hsc($this->locale); 146ec6cbde6SDominik Eckelmann } 147ec6cbde6SDominik Eckelmann } 148ec6cbde6SDominik Eckelmann 149ec6cbde6SDominik Eckelmann return false; 150ec6cbde6SDominik Eckelmann } 151ec6cbde6SDominik Eckelmann 152bbe70520SAndreas Gohr /** 153bbe70520SAndreas Gohr * Hook Callback. Make sure the JavaScript is translation dependent 154bbe70520SAndreas Gohr * 155bbe70520SAndreas Gohr * @param $event 156bbe70520SAndreas Gohr * @param $args 157bbe70520SAndreas Gohr */ 1585aa700abSGerry Weißbach function translation_jscache(Doku_Event $event, $args) { 159db7c51b4SAndreas Gohr if(!isset($_GET['lang'])) return; 1605e1f71acSGuillaume Turri if(!in_array($_GET['lang'], $this->helper->translations)) return; 161db7c51b4SAndreas Gohr 162db7c51b4SAndreas Gohr $lang = $_GET['lang']; 163db7c51b4SAndreas Gohr // reuse the constructor to reinitialize the cache key 164ba82fb96SAndreas Gohr if(method_exists($event->data, '__construct')) { 165ba82fb96SAndreas Gohr // New PHP 5 style constructor 16600e50232SAndreas Gohr $event->data->__construct( 167db7c51b4SAndreas Gohr $event->data->key . $lang, 168db7c51b4SAndreas Gohr $event->data->ext 169db7c51b4SAndreas Gohr ); 170ba82fb96SAndreas Gohr } else { 171ba82fb96SAndreas Gohr // Old PHP 4 style constructor - deprecated 172ba82fb96SAndreas Gohr $event->data->cache( 173ba82fb96SAndreas Gohr $event->data->key . $lang, 174ba82fb96SAndreas Gohr $event->data->ext 175ba82fb96SAndreas Gohr ); 176ba82fb96SAndreas Gohr } 177ec6cbde6SDominik Eckelmann } 178ec6cbde6SDominik Eckelmann 179bbe70520SAndreas Gohr /** 180bbe70520SAndreas Gohr * Hook Callback. Translate the AJAX loaded media manager 181bbe70520SAndreas Gohr * 182bbe70520SAndreas Gohr * @param $event 183bbe70520SAndreas Gohr * @param $args 184bbe70520SAndreas Gohr */ 1855aa700abSGerry Weißbach function translate_media_manager(Doku_Event $event, $args) { 186ec6cbde6SDominik Eckelmann global $conf; 187ec6cbde6SDominik Eckelmann if(isset($_REQUEST['ID'])) { 188ec6cbde6SDominik Eckelmann $id = getID(); 189c54240efSGuillaume Turri $lc = $this->helper->getLangPart($id); 190ec6cbde6SDominik Eckelmann } elseif(isset($_SESSION[DOKU_COOKIE]['translationlc'])) { 191ec6cbde6SDominik Eckelmann $lc = $_SESSION[DOKU_COOKIE]['translationlc']; 192ec6cbde6SDominik Eckelmann } else { 193db7c51b4SAndreas Gohr return; 194ec6cbde6SDominik Eckelmann } 195e5e7e41dSAndreas Gohr if(!$lc) return; 196e5e7e41dSAndreas Gohr 197ec6cbde6SDominik Eckelmann $conf['lang'] = $lc; 198ec6cbde6SDominik Eckelmann $event->data = $lc; 199ec6cbde6SDominik Eckelmann } 200ec6cbde6SDominik Eckelmann 2010a7415d3SAndreas Gohr /** 202bbe70520SAndreas Gohr * Hook Callback. Change the UI language in foreign language namespaces 2030a7415d3SAndreas Gohr */ 2045aa700abSGerry Weißbach function translation_hook(Doku_Event $event, $args) { 2050a7415d3SAndreas Gohr global $ID; 2060a7415d3SAndreas Gohr global $lang; 2070a7415d3SAndreas Gohr global $conf; 2087053cd66SAndreas Gohr global $ACT; 2097053cd66SAndreas Gohr // redirect away from start page? 2107053cd66SAndreas Gohr if($this->conf['redirectstart'] && $ID == $conf['start'] && $ACT == 'show') { 211c54240efSGuillaume Turri $lc = $this->helper->getBrowserLang(); 2127053cd66SAndreas Gohr if(!$lc) $lc = $conf['lang']; 213a4491becSGerry Weißbach $this->_redirect($lc.':'.$conf['start']); 2147053cd66SAndreas Gohr exit; 2157053cd66SAndreas Gohr } 2160a7415d3SAndreas Gohr 217a4491becSGerry Weißbach // Check if we can redirect 218a4491becSGerry Weißbach if($this->getConf('redirectlocalized')){ 219a4491becSGerry Weißbach $this->translation_redirect_localized(); 220a4491becSGerry Weißbach } 221a4491becSGerry Weißbach 2220a7415d3SAndreas Gohr // check if we are in a foreign language namespace 223c54240efSGuillaume Turri $lc = $this->helper->getLangPart($ID); 224a526927fSAndreas Gohr 225f2279247SAndreas Gohr // store language in session (for page related views only) 226f2279247SAndreas Gohr if(in_array($ACT, array('show', 'recent', 'diff', 'edit', 'preview', 'source', 'subscribe'))) { 227f2279247SAndreas Gohr $_SESSION[DOKU_COOKIE]['translationlc'] = $lc; 228f2279247SAndreas Gohr } 229a526927fSAndreas Gohr if(!$lc) $lc = $_SESSION[DOKU_COOKIE]['translationlc']; 230a526927fSAndreas Gohr if(!$lc) return; 23134591120SDominik Eckelmann $this->locale = $lc; 23234591120SDominik Eckelmann 23334591120SDominik Eckelmann if(!$this->getConf('translateui')) { 23434591120SDominik Eckelmann return true; 23534591120SDominik Eckelmann } 2360a7415d3SAndreas Gohr 2370a7415d3SAndreas Gohr if(file_exists(DOKU_INC . 'inc/lang/' . $lc . '/lang.php')) { 2380a7415d3SAndreas Gohr require(DOKU_INC . 'inc/lang/' . $lc . '/lang.php'); 2390a7415d3SAndreas Gohr } 2400a7415d3SAndreas Gohr $conf['lang_before_translation'] = $conf['lang']; //store for later access in syntax plugin 2410a7415d3SAndreas Gohr $conf['lang'] = $lc; 2420a7415d3SAndreas Gohr 2430a7415d3SAndreas Gohr return true; 2440a7415d3SAndreas Gohr } 245af1904f9SAndreas Gohr 246af1904f9SAndreas Gohr /** 247bbe70520SAndreas Gohr * Hook Callback. Resort page match results so that results are ordered by translation, having the 248af1904f9SAndreas Gohr * default language first 249af1904f9SAndreas Gohr */ 2505aa700abSGerry Weißbach function translation_search(Doku_Event $event, $args) { 251d75e50bcSAndreas Gohr 252d75e50bcSAndreas Gohr if($event->data['has_titles']) { 253d75e50bcSAndreas Gohr // sort into translation slots 254d75e50bcSAndreas Gohr $res = array(); 255d75e50bcSAndreas Gohr foreach($event->result as $r => $t) { 256c54240efSGuillaume Turri $tr = $this->helper->getLangPart($r); 257d75e50bcSAndreas Gohr if(!is_array($res["x$tr"])) $res["x$tr"] = array(); 258d75e50bcSAndreas Gohr $res["x$tr"][] = array($r, $t); 259d75e50bcSAndreas Gohr } 260d75e50bcSAndreas Gohr // sort by translations 261d75e50bcSAndreas Gohr ksort($res); 262d75e50bcSAndreas Gohr // combine 263d75e50bcSAndreas Gohr $event->result = array(); 264d75e50bcSAndreas Gohr foreach($res as $r) { 265d75e50bcSAndreas Gohr foreach($r as $l) { 266d75e50bcSAndreas Gohr $event->result[$l[0]] = $l[1]; 267d75e50bcSAndreas Gohr } 268d75e50bcSAndreas Gohr } 269d75e50bcSAndreas Gohr } else { 270d75e50bcSAndreas Gohr # legacy support for old DokuWiki hooks 271d75e50bcSAndreas Gohr 272af1904f9SAndreas Gohr // sort into translation slots 273af1904f9SAndreas Gohr $res = array(); 274af1904f9SAndreas Gohr foreach($event->result as $r) { 275c54240efSGuillaume Turri $tr = $this->helper->getLangPart($r); 276af1904f9SAndreas Gohr if(!is_array($res["x$tr"])) $res["x$tr"] = array(); 277af1904f9SAndreas Gohr $res["x$tr"][] = $r; 278af1904f9SAndreas Gohr } 279af1904f9SAndreas Gohr // sort by translations 280af1904f9SAndreas Gohr ksort($res); 281af1904f9SAndreas Gohr // combine 282af1904f9SAndreas Gohr $event->result = array(); 283af1904f9SAndreas Gohr foreach($res as $r) { 284af1904f9SAndreas Gohr $event->result = array_merge($event->result, $r); 285af1904f9SAndreas Gohr } 286af1904f9SAndreas Gohr } 287d75e50bcSAndreas Gohr } 288af1904f9SAndreas Gohr 289a4491becSGerry Weißbach /** 290a4491becSGerry Weißbach * Redirects to the localized version of the page when showing and browser says so and translation was explicitly requested 291a4491becSGerry Weißbach **/ 292a4491becSGerry Weißbach function translation_redirect_localized() { 293a4491becSGerry Weißbach global $ID; 294a4491becSGerry Weißbach global $conf; 295a4491becSGerry Weißbach global $ACT; 296a4491becSGerry Weißbach 297a4491becSGerry Weißbach // redirect to localized page? 298a4491becSGerry Weißbach if( $ACT != 'show' ) { return; } 299a4491becSGerry Weißbach 300a4491becSGerry Weißbach $override = isset($_REQUEST['tns']); // override enabled - comes from the bottom bar. 30143ffc77dSGerry Weißbach $lang = !empty($conf['lang_before_translation']) ? $conf['lang_before_translation'] : $conf['lang']; // Check for original language 302a4491becSGerry Weißbach 303a4491becSGerry Weißbach // get current page language - if empty then default; 304a4491becSGerry Weißbach $currentSessionLanguage = $_SESSION[DOKU_COOKIE]['translationcur']; 3054e6ef383SGerry Weißbach $pageLang = $this->helper->getLangPart($ID); 306a4491becSGerry Weißbach 307a4491becSGerry Weißbach if ( empty($pageLang) ) { 308a4491becSGerry Weißbach $pageLang = $lang; 309a4491becSGerry Weißbach } 310a4491becSGerry Weißbach 311a4491becSGerry Weißbach // If both match, we're fine. 312a4491becSGerry Weißbach if ( $currentSessionLanguage == $pageLang ) { 313a4491becSGerry Weißbach return; 314a4491becSGerry Weißbach } 315a4491becSGerry Weißbach 316a4491becSGerry Weißbach // check current translation 317a4491becSGerry Weißbach if ( empty( $currentSessionLanguage ) && !$override ) { 318a4491becSGerry Weißbach 319a4491becSGerry Weißbach // If not set - we must just have entered - set the browser language 3204e6ef383SGerry Weißbach $currentSessionLanguage = $this->helper->getBrowserLang(); 321a4491becSGerry Weißbach 322a4491becSGerry Weißbach // if no browser Language set, take entered namespace language - empty for default. 323a4491becSGerry Weißbach if ( !$currentSessionLanguage ) { 324a4491becSGerry Weißbach $currentSessionLanguage = $pageLang; 325a4491becSGerry Weißbach } 326a4491becSGerry Weißbach 327a4491becSGerry Weißbach // Set new Language 328a4491becSGerry Weißbach $_SESSION[DOKU_COOKIE]['translationcur'] = $currentSessionLanguage; 329a4491becSGerry Weißbach 330a4491becSGerry Weißbach // Write Language back 331a4491becSGerry Weißbach $pageLang = $currentSessionLanguage; 332a4491becSGerry Weißbach } 333a4491becSGerry Weißbach 334a4491becSGerry Weißbach 335a4491becSGerry Weißbach if ( $override && $pageLang != $currentSessionLanguage ) { 336a4491becSGerry Weißbach // Set new Language 337a4491becSGerry Weißbach $currentSessionLanguage = $pageLang; 338a4491becSGerry Weißbach $_SESSION[DOKU_COOKIE]['translationcur'] = $currentSessionLanguage; 339a4491becSGerry Weißbach } else if ( !$override ) { 340a4491becSGerry Weißbach // Write Language back 341a4491becSGerry Weißbach $pageLang = $currentSessionLanguage; 342a4491becSGerry Weißbach } 343a4491becSGerry Weißbach 344a4491becSGerry Weißbach // If this is the default language, make empty 345a4491becSGerry Weißbach if ( $pageLang == $lang ) { 346a4491becSGerry Weißbach $pageLang = ''; 347a4491becSGerry Weißbach } 348a4491becSGerry Weißbach 349a4491becSGerry Weißbach // Generate new Page ID 3504e6ef383SGerry Weißbach list($newPage,$name) = $this->helper->buildTransID($pageLang,$this->helper->getIDPart($ID)); 351a4491becSGerry Weißbach $newPage = cleanID($newPage); 352a4491becSGerry Weißbach 353a4491becSGerry Weißbach // Check if Page exists 354a4491becSGerry Weißbach if ( $newPage != $ID && page_exists($newPage, '', false) ) { 355a4491becSGerry Weißbach // $newPage redirect 356a4491becSGerry Weißbach 357a4491becSGerry Weißbach if ( auth_quickaclcheck($newPage) < AUTH_READ ) { return; } 358a4491becSGerry Weißbach 359a4491becSGerry Weißbach session_write_close(); 360a4491becSGerry Weißbach $this->_redirect($newPage); 361a4491becSGerry Weißbach } 362a4491becSGerry Weißbach else 363a4491becSGerry Weißbach if ( $override ) { 364a4491becSGerry Weißbach // cleanup redirect 365a4491becSGerry Weißbach session_write_close(); 366a4491becSGerry Weißbach 367a4491becSGerry Weißbach if ( auth_quickaclcheck($newPage) < AUTH_READ ) { return; } 368a4491becSGerry Weißbach 369a4491becSGerry Weißbach $this->_redirect($ID); 370a4491becSGerry Weißbach } 371a4491becSGerry Weißbach 372a4491becSGerry Weißbach // no redirect; 373a4491becSGerry Weißbach } 374a4491becSGerry Weißbach 375a4491becSGerry Weißbach 376a4491becSGerry Weißbach function _redirect($url) 377a4491becSGerry Weißbach { 378a4491becSGerry Weißbach unset($_GET['id']); 379a4491becSGerry Weißbach $more = array(); 380a4491becSGerry Weißbach 381a4491becSGerry Weißbach if ( !empty($_GET) ) { 382a4491becSGerry Weißbach $params = ''; 383a4491becSGerry Weißbach foreach( $_GET as $key => $value ) { 384a4491becSGerry Weißbach // Possible multiple encodings. 385a4491becSGerry Weißbach $more[$key] = $value; 386a4491becSGerry Weißbach } 387a4491becSGerry Weißbach } 388a4491becSGerry Weißbach 389a4491becSGerry Weißbach if ( wl( $url, $more, true, '&') != DOKU_URL . substr($_SERVER['REQUEST_URI'], 1) ) { 390a4491becSGerry Weißbach header('Location: ' . wl( $url, $more, true, '&'), 302); 391a4491becSGerry Weißbach exit; 392a4491becSGerry Weißbach } 393a4491becSGerry Weißbach } 3940a7415d3SAndreas Gohr} 3950a7415d3SAndreas Gohr 396ec6cbde6SDominik Eckelmann//Setup VIM: ex: et ts=4 : 397