Project

General

Profile

1 1860 darkviper
<?php
2
3
/**
4
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
5
 *
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
 */
19
20
/**
21
 * TranslationTable.php
22
 *
23
 * @category     Core
24
 * @package      Core_Translation
25 1873 darkviper
 * @copyright    Werner v.d.Decken <wkl@isteam.de>
26 1860 darkviper
 * @author       Werner v.d.Decken <wkl@isteam.de>
27
 * @license      http://www.gnu.org/licenses/gpl.html   GPL License
28
 * @version      0.0.1
29
 * @revision     $Revision$
30
 * @link         $HeadURL$
31
 * @lastmodified $Date$
32
 * @since        File available since 12.01.2013
33
 */
34
class TranslationTable {
35
36 1864 darkviper
	protected $aTranslations = array();
37
	protected $aLanguages    = array();
38
	protected $sSystemLang   = 'en';
39
	protected $sDefaultLang  = 'en';
40
	protected $sUserLang     = 'en';
41
	protected $sAddon        = '';
42
	protected $oReg          = null;
43
	protected $sTempPath     = '';
44
	protected $iDirMode      = 0777;
45 1873 darkviper
	protected $bUseCache     = true;
46
47
	/**
48 1860 darkviper
 * Constructor
49
 * @param string relative pathname of the Addon (i.e. '' || 'modules/myAddon/')
50 1864 darkviper
 * @param string System language code ( 2*3ALPHA[[_2ALPHA]_2*4ALNUM] )
51
 * @param string Default language code ( 2*3ALPHA[[_2ALPHA]_2*4ALNUM] )
52
 * @param string User language code ( 2*3ALPHA[[_2ALPHA]_2*4ALNUM] )
53 1873 darkviper
 * @param boolean true if caching is enabled
54 1860 darkviper
 */
55 1864 darkviper
	public function __construct($sAddon,
56 1873 darkviper
	                            $sSystemLanguage,
57
	                            $sDefaultLanguage,
58
	                            $sUserLanguage,
59
	                            $bUseCache = true)
60 1860 darkviper
	{
61 1864 darkviper
		$this->bUseCache             = $bUseCache;
62
		$this->sSystemLang           = $sSystemLanguage;
63
		$this->sDefaultLang          = $sDefaultLanguage;
64
		$this->sUserLang             = $sUserLanguage;
65
		$this->sAddon                = $sAddon;
66
		if(class_exists('WbAdaptor')) {
67
			$this->sTempPath         = WbAdaptor::getInstance()->TempPath;
68
			$this->iDirMode          = WbAdaptor::getInstance()->OctalDirMode;
69
		}else {
70
			$this->sTempPath         = dirname(dirname(__FILE__)).'/temp/';
71
		}
72
		$this->aLanguages['system']  = array();
73
		$this->aLanguages['default'] = array();
74
		$this->aLanguages['user']    = array();
75 1860 darkviper
	}
76
/**
77
 * Load language definitions
78
 * @return TranslationTable a valid translation table object
79
 * @throws TranslationException
80
 */
81
	public function load($sAdaptor)
82
	{
83 1864 darkviper
		$sCachePath	= $this->getCachePath();
84
		$sCacheFile = $sCachePath.md5($this->sAddon.$this->sSystemLang.
85
		                              $this->sDefaultLang.$this->sUserLang).'.php';
86
		if($this->bUseCache && is_readable($sCacheFile)) {
87
			$this->aTranslations = $this->loadCacheFile($sCacheFile);
88
		}else {
89
			$bLanguageFound = false;
90
			$oAdaptor= new $sAdaptor($this->sAddon);
91 1866 Luisehahne
			if(!$oAdaptor instanceof TranslateAdaptorInterface) {
92 1864 darkviper
				$sMsg = 'Class ['.$sAdaptor.'] does not implement the '
93
				      . 'interface [TranslateAdaptorInterface]';
94
				throw new TranslationException($sMsg);
95 1860 darkviper
			}
96 1864 darkviper
		// load system language first
97
			if(($aResult = $this->loadLanguageSegments($this->sSystemLang, $oAdaptor)) !== false) {
98
			// load system language
99
				$this->aLanguages['system'] = $aResult;
100
				$bLanguageFound = true;
101 1860 darkviper
			}
102 1864 darkviper
			if($this->sDefaultLang != $this->sSystemLang) {
103
			// load default language if it's not equal system language
104
				if(($aResult = $this->loadLanguageSegments($this->sDefaultLang, $oAdaptor)) !== false) {
105
					$this->aLanguages['default'] = $aResult;
106
					$bLanguageFound = true;
107
				}
108
			}else {
109
			// copy system language
110
				$this->aLanguages['default'] = $this->aLanguages['system'];
111 1860 darkviper
			}
112 1864 darkviper
			if($this->sUserLang != $this->sDefaultLang
113
			   && $this->sUserLang != $this->sSystemLang) {
114
			// load user language if it's not equal default language or system language
115
				if(($aResult = $this->loadLanguageSegments($this->sUserLang, $oAdaptor)) !== false) {
116
					$this->aLanguages['user'] = $aResult;
117
					$bLanguageFound = true;
118
				}
119
			}elseif($this->sUserLang == $this->sDefaultLang) {
120
			// copy default language
121
				$this->aLanguages['user'] = $this->aLanguages['default'];
122
			}elseif($this->sUserLang == $this->sSystemLang) {
123
			// copy system language
124
				$this->aLanguages['user'] = $this->aLanguages['system'];
125
			}
126
			if($bLanguageFound) {
127
			// copy user into default if default is missing
128
				if(sizeof($this->aLanguages['user']) && !sizeof($this->aLanguages['default'])) {
129
					$this->aLanguages['default'] = $this->aLanguages['user'];
130
				}
131
			// copy default into system if system is missing
132
				if(sizeof($this->aLanguages['default']) && !sizeof($this->aLanguages['system'])) {
133
					$this->aLanguages['system'] = $this->aLanguages['default'];
134
				}
135
			}
136
		// if absolutely no requested language found, simply get the first available language
137
			if(!$bLanguageFound) {
138
				$sFirstLanguage = $oAdaptor->findFirstLanguage();
139
			// load first found language if its not already loaded
140
				if(($aResult = $this->loadLanguageSegments($sFirstLanguage, $oAdaptor)) !== false) {
141
					$this->aLanguages['system'] = $aResult;
142
					$bLanguageFound = true;
143
				}
144
			}
145
			if($bLanguageFound) {
146
				$this->aTranslations = array_merge($this->aTranslations,
147
				                                    $this->aLanguages['system'],
148
				                                    $this->aLanguages['default'],
149
				                                    $this->aLanguages['user']);
150
				if($this->bUseCache) {
151
					$this->writeCacheFile($sCacheFile);
152
				}
153
			}
154 1860 darkviper
		}
155
		return $this;
156
	}
157
/**
158
 * Is key available
159
 * @param string Language key
160
 * @return bool
161
 */
162
	public function __isset($sKey)
163
	{
164 1864 darkviper
		return isset($this->aTranslations[$sKey]);
165 1860 darkviper
	}
166
/**
167
 * Get translation text
168
 * @param string Language key
169
 * @return string Translation text
170
 */
171
	public function __get($sKey)
172
	{
173 1864 darkviper
		if(isset($this->aTranslations[$sKey])) {
174
			return $this->aTranslations[$sKey];
175 1860 darkviper
		}else {
176
			return '';
177
		}
178
	}
179
/**
180
 * returns the whoole translation array
181
 * @return array
182
 * @deprecated for backward compatibility only. Will be removed shortly
183
 */
184
	public function getArray()
185
	{
186 1864 darkviper
		$aRetval = (is_array($this->aTranslations) ? $this->aTranslations : array());
187
		return $aRetval;
188 1860 darkviper
	}
189 1864 darkviper
/**
190
 * Load Language
191
 * @param string Language Code
192
 * @param object Adaptor object
193
 * @return bool|array
194
 */
195
	protected function loadLanguageSegments($sLangCode, $oAdaptor)
196
	{
197
		$aTranslations = array();
198
		// sanitize the language code
199
		$aLangCode = explode('_', preg_replace('/[^a-z0-9]/i', '_', strtolower($sLangCode)));
200
		$sConcatedLang = '';
201
		foreach($aLangCode as $sLang)
202
		{ // iterate all segments of the language code
203 1873 darkviper
			$sConcatedLang .= ($sConcatedLang == '' ? '' :  '_').$sLang;
204
			if( ($aResult = $oAdaptor->loadLanguage($sConcatedLang)) !== false ) {
205 1864 darkviper
				$aTranslations = array_merge($aTranslations, $aResult);
206
			}
207
		}
208
		return (sizeof($aTranslations) > 0 ? $aTranslations : false);
209
	}
210
/**
211
 * getCachePath
212
 * @return string a valid path for caching or null on error
213
 */
214
	protected function getCachePath()
215
	{
216
		$sCachePath = $this->sTempPath.__CLASS__.'/cache/';
217
		if(!file_exists($sCachePath) && is_writeable($this->sTempPath)) {
218
			$iOldUmask = umask(0);
219
			mkdir($sCachePath, $this->iDirMode, true);
220
			umask($iOldUmask);
221
		}
222
		if(is_writable($sCachePath)) {
223
			return $sCachePath;
224
		}else {
225
			return null;
226
		}
227
	}
228
/**
229
 * load cached translation table
230
 * @param string path/name of the cachefile
231
 * @return array list of translations
232
 */
233
	protected function loadCacheFile($sCacheFile)
234
	{
235
		$aTranslation = array();
236
		include($sCacheFile);
237
		return $aTranslation;
238
	}
239
/**
240
 * Write cache from translation
241
 * @param string path/name of the cachefile
242
 */
243
	protected function writeCacheFile($sCacheFile)
244
	{
245
		$sOutput = '<?php'."\n".'/* autogenerated cachefile */'."\n";
246
		while (list($key, $value) = each($this->aTranslations)) {
247
			$sOutput .= '$aTranslation[\''.$key.'\'] = \''.addslashes($value).'\';'."\n";
248
		}
249
		file_put_contents($sCacheFile, $sOutput, LOCK_EX);
250
	}
251 1860 darkviper
} // end of class TranslationTable