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 1893 Luisehahne
		$sCacheFile = '';
84
		if($this->bUseCache) {
85
			$sCachePath	= $this->getCachePath();
86
			$sCacheFile = $sCachePath.md5($this->sAddon.$this->sSystemLang.
87
										  $this->sDefaultLang.$this->sUserLang).'.php';
88
		}
89 1864 darkviper
		if($this->bUseCache && is_readable($sCacheFile)) {
90 1893 Luisehahne
				$this->aTranslations = $this->loadCacheFile($sCacheFile);
91 1864 darkviper
		}else {
92
			$bLanguageFound = false;
93 1902 darkviper
			if(!class_exists($sAdaptor)) {
94
				throw new TranslationException('unable to load adaptor: '.$sAdaptor);
95
			}
96 1864 darkviper
			$oAdaptor= new $sAdaptor($this->sAddon);
97 1866 Luisehahne
			if(!$oAdaptor instanceof TranslateAdaptorInterface) {
98 1864 darkviper
				$sMsg = 'Class ['.$sAdaptor.'] does not implement the '
99
				      . 'interface [TranslateAdaptorInterface]';
100
				throw new TranslationException($sMsg);
101 1860 darkviper
			}
102 1864 darkviper
		// load system language first
103
			if(($aResult = $this->loadLanguageSegments($this->sSystemLang, $oAdaptor)) !== false) {
104
			// load system language
105
				$this->aLanguages['system'] = $aResult;
106
				$bLanguageFound = true;
107 1860 darkviper
			}
108 1864 darkviper
			if($this->sDefaultLang != $this->sSystemLang) {
109
			// load default language if it's not equal system language
110
				if(($aResult = $this->loadLanguageSegments($this->sDefaultLang, $oAdaptor)) !== false) {
111
					$this->aLanguages['default'] = $aResult;
112
					$bLanguageFound = true;
113
				}
114
			}else {
115
			// copy system language
116
				$this->aLanguages['default'] = $this->aLanguages['system'];
117 1860 darkviper
			}
118 1864 darkviper
			if($this->sUserLang != $this->sDefaultLang
119
			   && $this->sUserLang != $this->sSystemLang) {
120
			// load user language if it's not equal default language or system language
121
				if(($aResult = $this->loadLanguageSegments($this->sUserLang, $oAdaptor)) !== false) {
122
					$this->aLanguages['user'] = $aResult;
123
					$bLanguageFound = true;
124
				}
125
			}elseif($this->sUserLang == $this->sDefaultLang) {
126
			// copy default language
127
				$this->aLanguages['user'] = $this->aLanguages['default'];
128
			}elseif($this->sUserLang == $this->sSystemLang) {
129
			// copy system language
130
				$this->aLanguages['user'] = $this->aLanguages['system'];
131
			}
132
			if($bLanguageFound) {
133
			// copy user into default if default is missing
134
				if(sizeof($this->aLanguages['user']) && !sizeof($this->aLanguages['default'])) {
135
					$this->aLanguages['default'] = $this->aLanguages['user'];
136
				}
137
			// copy default into system if system is missing
138
				if(sizeof($this->aLanguages['default']) && !sizeof($this->aLanguages['system'])) {
139
					$this->aLanguages['system'] = $this->aLanguages['default'];
140
				}
141
			}
142
		// if absolutely no requested language found, simply get the first available language
143
			if(!$bLanguageFound) {
144
				$sFirstLanguage = $oAdaptor->findFirstLanguage();
145
			// load first found language if its not already loaded
146
				if(($aResult = $this->loadLanguageSegments($sFirstLanguage, $oAdaptor)) !== false) {
147
					$this->aLanguages['system'] = $aResult;
148
					$bLanguageFound = true;
149
				}
150
			}
151
			if($bLanguageFound) {
152
				$this->aTranslations = array_merge($this->aTranslations,
153
				                                    $this->aLanguages['system'],
154
				                                    $this->aLanguages['default'],
155
				                                    $this->aLanguages['user']);
156 1893 Luisehahne
				$this->writeCacheFile($sCacheFile);
157 1864 darkviper
			}
158 1860 darkviper
		}
159
		return $this;
160
	}
161
/**
162
 * Is key available
163
 * @param string Language key
164
 * @return bool
165
 */
166
	public function __isset($sKey)
167
	{
168 1864 darkviper
		return isset($this->aTranslations[$sKey]);
169 1860 darkviper
	}
170
/**
171
 * Get translation text
172
 * @param string Language key
173
 * @return string Translation text
174
 */
175
	public function __get($sKey)
176
	{
177 1864 darkviper
		if(isset($this->aTranslations[$sKey])) {
178
			return $this->aTranslations[$sKey];
179 1860 darkviper
		}else {
180
			return '';
181
		}
182
	}
183
/**
184
 * returns the whoole translation array
185
 * @return array
186
 * @deprecated for backward compatibility only. Will be removed shortly
187
 */
188
	public function getArray()
189
	{
190 1864 darkviper
		$aRetval = (is_array($this->aTranslations) ? $this->aTranslations : array());
191
		return $aRetval;
192 1860 darkviper
	}
193 1864 darkviper
/**
194
 * Load Language
195
 * @param string Language Code
196
 * @param object Adaptor object
197
 * @return bool|array
198
 */
199
	protected function loadLanguageSegments($sLangCode, $oAdaptor)
200
	{
201
		$aTranslations = array();
202
		// sanitize the language code
203
		$aLangCode = explode('_', preg_replace('/[^a-z0-9]/i', '_', strtolower($sLangCode)));
204
		$sConcatedLang = '';
205
		foreach($aLangCode as $sLang)
206
		{ // iterate all segments of the language code
207 1873 darkviper
			$sConcatedLang .= ($sConcatedLang == '' ? '' :  '_').$sLang;
208
			if( ($aResult = $oAdaptor->loadLanguage($sConcatedLang)) !== false ) {
209 1864 darkviper
				$aTranslations = array_merge($aTranslations, $aResult);
210
			}
211
		}
212
		return (sizeof($aTranslations) > 0 ? $aTranslations : false);
213
	}
214
/**
215
 * getCachePath
216
 * @return string a valid path for caching or null on error
217
 */
218
	protected function getCachePath()
219
	{
220
		$sCachePath = $this->sTempPath.__CLASS__.'/cache/';
221
		if(!file_exists($sCachePath) && is_writeable($this->sTempPath)) {
222
			$iOldUmask = umask(0);
223
			mkdir($sCachePath, $this->iDirMode, true);
224
			umask($iOldUmask);
225
		}
226
		if(is_writable($sCachePath)) {
227
			return $sCachePath;
228
		}else {
229
			return null;
230
		}
231
	}
232
/**
233
 * load cached translation table
234
 * @param string path/name of the cachefile
235
 * @return array list of translations
236
 */
237
	protected function loadCacheFile($sCacheFile)
238
	{
239
		$aTranslation = array();
240
		include($sCacheFile);
241
		return $aTranslation;
242
	}
243
/**
244
 * Write cache from translation
245
 * @param string path/name of the cachefile
246
 */
247
	protected function writeCacheFile($sCacheFile)
248
	{
249 1893 Luisehahne
		if($this->bUseCache) {
250
			$sOutput = '<?php'."\n".'/* autogenerated cachefile */'."\n";
251
			while (list($key, $value) = each($this->aTranslations)) {
252
				$sOutput .= '$aTranslation[\''.$key.'\'] = \''.addslashes($value).'\';'."\n";
253
			}
254
			file_put_contents($sCacheFile, $sOutput, LOCK_EX);
255 1864 darkviper
		}
256
	}
257 1860 darkviper
} // end of class TranslationTable