1<?php 2/** 3 * Translation Plugin: Simple multilanguage plugin 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @author Andreas Gohr <andi@splitbrain.org> 7 * @author Guy Brand <gb@isis.u-strasbg.fr> 8 */ 9 10// must be run within Dokuwiki 11if(!defined('DOKU_INC')) die(); 12 13if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 14require_once(DOKU_PLUGIN.'action.php'); 15 16class action_plugin_translation extends DokuWiki_Action_Plugin { 17 18 /** 19 * for th helper plugin 20 */ 21 var $hlp = null; 22 23 var $locale; 24 25 /** 26 * Constructor. Load helper plugin 27 */ 28 function action_plugin_translation(){ 29 $this->hlp =& plugin_load('helper', 'translation'); 30 } 31 32 /** 33 * Registe the events 34 */ 35 function register(&$controller) { 36 // should the lang be applied to UI? 37 $scriptName = basename($_SERVER['PHP_SELF']); 38 if($this->getConf('translateui')){ 39 switch ($scriptName) { 40 case 'js.php': 41 $controller->register_hook('INIT_LANG_LOAD', 'BEFORE', $this, 'translation_js'); 42 $controller->register_hook('JS_CACHE_USE', 'BEFORE', $this, 'translation_jscache'); 43 break; 44 45 case 'ajax.php': 46 $controller->register_hook('INIT_LANG_LOAD', 'BEFORE', $this, 'translate_media_manager'); 47 break; 48 49 case 'mediamanager.php': 50 $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'setJsCacheKey'); 51 break; 52 53 default: 54 $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'setJsCacheKey'); 55 } 56 } 57 58 if ($scriptName !== 'js.php' && $scriptName !== 'ajax.php') { 59 $controller->register_hook('DOKUWIKI_STARTED', 'BEFORE', $this, 'translation_hook'); 60 $controller->register_hook('MEDIAMANAGER_STARTED', 'BEFORE', $this, 'translation_hook'); 61 } 62 63 $controller->register_hook('SEARCH_QUERY_PAGELOOKUP', 'AFTER', $this, 'translation_search'); 64 } 65 66 function setJsCacheKey(&$event, $args) { 67 if (!isset($this->locale)) return false; 68 $count = count($event->data['script']); 69 for ($i = 0; $i<$count; $i++) { 70 if (strpos($event->data['script'][$i]['src'], '/lib/exe/js.php') !== false) { 71 $event->data['script'][$i]['src'] .= '&lang='.hsc($this->locale); 72 } 73 } 74 75 return false; 76 } 77 78 function translation_js(&$event, $args) { 79 global $conf; 80 if(!isset($_GET['lang'])) return; 81 if(!in_array($_GET['lang'],$this->hlp->trans)) return; 82 $lang = $_GET['lang']; 83 $event->data = $lang; 84 $conf['lang'] = $lang; 85 } 86 87 function translation_jscache(&$event, $args) { 88 if (!isset($_GET['lang'])) return; 89 if(!in_array($_GET['lang'],$this->hlp->trans)) return; 90 91 $lang = $_GET['lang']; 92 // reuse the constructor to reinitialize the cache key 93 $event->data->cache( 94 $event->data->key . $lang, 95 $event->data->ext 96 ); 97 } 98 99 function translate_media_manager(&$event, $args) { 100 global $conf; 101 if (isset($_REQUEST['ID'])) { 102 $id = getID(); 103 $lc = $this->hlp->getLangPart($id); 104 } elseif (isset($_SESSION[DOKU_COOKIE]['translationlc'])) { 105 $lc = $_SESSION[DOKU_COOKIE]['translationlc']; 106 } else { 107 return; 108 } 109 $conf['lang'] = $lc; 110 $event->data = $lc; 111 } 112 113 /** 114 * Change the UI language in foreign language namespaces 115 */ 116 function translation_hook(&$event, $args) { 117 global $ID; 118 global $lang; 119 global $conf; 120 global $ACT; 121 // redirect away from start page? 122 if($this->conf['redirectstart'] && $ID == $conf['start'] && $ACT == 'show'){ 123 $lc = $this->hlp->getBrowserLang(); 124 if(!$lc) $lc = $conf['lang']; 125 header('Location: '.wl($lc.':'.$conf['start'],'',true,'&')); 126 exit; 127 } 128 129 // check if we are in a foreign language namespace 130 $lc = $this->hlp->getLangPart($ID); 131 132 // store language in session (for page related views only) 133 if(in_array($ACT,array('show','recent','diff','edit','preview','source','subscribe'))){ 134 $_SESSION[DOKU_COOKIE]['translationlc'] = $lc; 135 } 136 if(!$lc) $lc = $_SESSION[DOKU_COOKIE]['translationlc']; 137 if(!$lc) return; 138 $this->locale = $lc; 139 140 if (!$this->getConf('translateui')) { 141 return true; 142 } 143 144 if(file_exists(DOKU_INC.'inc/lang/'.$lc.'/lang.php')) { 145 require(DOKU_INC.'inc/lang/'.$lc.'/lang.php'); 146 } 147 $conf['lang_before_translation'] = $conf['lang']; //store for later access in syntax plugin 148 $conf['lang'] = $lc; 149 150 return true; 151 } 152 153 /** 154 * Resort page match results so that results are ordered by translation, having the 155 * default language first 156 */ 157 function translation_search(&$event, $args) { 158 159 if($event->data['has_titles']){ 160 // sort into translation slots 161 $res = array(); 162 foreach($event->result as $r => $t){ 163 $tr = $this->hlp->getLangPart($r); 164 if(!is_array($res["x$tr"])) $res["x$tr"] = array(); 165 $res["x$tr"][] = array($r,$t); 166 } 167 // sort by translations 168 ksort($res); 169 // combine 170 $event->result = array(); 171 foreach($res as $r){ 172 foreach($r as $l){ 173 $event->result[$l[0]] = $l[1]; 174 } 175 } 176 }else{ 177 # legacy support for old DokuWiki hooks 178 179 // sort into translation slots 180 $res = array(); 181 foreach($event->result as $r){ 182 $tr = $this->hlp->getLangPart($r); 183 if(!is_array($res["x$tr"])) $res["x$tr"] = array(); 184 $res["x$tr"][] = $r; 185 } 186 // sort by translations 187 ksort($res); 188 // combine 189 $event->result = array(); 190 foreach($res as $r){ 191 $event->result = array_merge($event->result,$r); 192 } 193 } 194 } 195 196} 197 198//Setup VIM: ex: et ts=4 : 199