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
 * @author       Werner v.d.Decken <wkl@isteam.de>
26
 * @copyright    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 1860 darkviper
/**
46
 * Constructor
47
 * @param string relative pathname of the Addon (i.e. '' || 'modules/myAddon/')
48 1864 darkviper
 * @param string System language code ( 2*3ALPHA[[_2ALPHA]_2*4ALNUM] )
49
 * @param string Default language code ( 2*3ALPHA[[_2ALPHA]_2*4ALNUM] )
50
 * @param string User language code ( 2*3ALPHA[[_2ALPHA]_2*4ALNUM] )
51 1860 darkviper
 */
52 1864 darkviper
	public function __construct($sAddon,
53
	                            $sSystemLanguage, $sDefaultLanguage, $sUserLanguage,
54
	                            $bUseCache = Translate::CACHE_ENABLED)
55 1860 darkviper
	{
56 1864 darkviper
		$this->bUseCache             = $bUseCache;
57
		$this->sSystemLang           = $sSystemLanguage;
58
		$this->sDefaultLang          = $sDefaultLanguage;
59
		$this->sUserLang             = $sUserLanguage;
60
		$this->sAddon                = $sAddon;
61
		if(class_exists('WbAdaptor')) {
62
			$this->sTempPath         = WbAdaptor::getInstance()->TempPath;
63
			$this->iDirMode          = WbAdaptor::getInstance()->OctalDirMode;
64
		}else {
65
			$this->sTempPath         = dirname(dirname(__FILE__)).'/temp/';
66
		}
67
		$this->aLanguages['system']  = array();
68
		$this->aLanguages['default'] = array();
69
		$this->aLanguages['user']    = array();
70 1860 darkviper
	}
71
/**
72
 * Load language definitions
73
 * @return TranslationTable a valid translation table object
74
 * @throws TranslationException
75
 */
76
	public function load($sAdaptor)
77
	{
78 1864 darkviper
		$sCachePath	= $this->getCachePath();
79
		$sCacheFile = $sCachePath.md5($this->sAddon.$this->sSystemLang.
80
		                              $this->sDefaultLang.$this->sUserLang).'.php';
81
		if($this->bUseCache && is_readable($sCacheFile)) {
82
			$this->aTranslations = $this->loadCacheFile($sCacheFile);
83
		}else {
84
			$bLanguageFound = false;
85
			$oAdaptor= new $sAdaptor($this->sAddon);
86 1866 Luisehahne
			if(!$oAdaptor instanceof TranslateAdaptorInterface) {
87 1864 darkviper
				$sMsg = 'Class ['.$sAdaptor.'] does not implement the '
88
				      . 'interface [TranslateAdaptorInterface]';
89
				throw new TranslationException($sMsg);
90 1860 darkviper
			}
91 1864 darkviper
		// load system language first
92
			if(($aResult = $this->loadLanguageSegments($this->sSystemLang, $oAdaptor)) !== false) {
93
			// load system language
94
				$this->aLanguages['system'] = $aResult;
95
				$bLanguageFound = true;
96 1860 darkviper
			}
97 1864 darkviper
			if($this->sDefaultLang != $this->sSystemLang) {
98
			// load default language if it's not equal system language
99
				if(($aResult = $this->loadLanguageSegments($this->sDefaultLang, $oAdaptor)) !== false) {
100
					$this->aLanguages['default'] = $aResult;
101
					$bLanguageFound = true;
102
				}
103
			}else {
104
			// copy system language
105
				$this->aLanguages['default'] = $this->aLanguages['system'];
106 1860 darkviper
			}
107 1864 darkviper
			if($this->sUserLang != $this->sDefaultLang
108
			   && $this->sUserLang != $this->sSystemLang) {
109
			// load user language if it's not equal default language or system language
110
				if(($aResult = $this->loadLanguageSegments($this->sUserLang, $oAdaptor)) !== false) {
111
					$this->aLanguages['user'] = $aResult;
112
					$bLanguageFound = true;
113
				}
114
			}elseif($this->sUserLang == $this->sDefaultLang) {
115
			// copy default language
116
				$this->aLanguages['user'] = $this->aLanguages['default'];
117
			}elseif($this->sUserLang == $this->sSystemLang) {
118
			// copy system language
119
				$this->aLanguages['user'] = $this->aLanguages['system'];
120
			}
121
			if($bLanguageFound) {
122
			// copy user into default if default is missing
123
				if(sizeof($this->aLanguages['user']) && !sizeof($this->aLanguages['default'])) {
124
					$this->aLanguages['default'] = $this->aLanguages['user'];
125
				}
126
			// copy default into system if system is missing
127
				if(sizeof($this->aLanguages['default']) && !sizeof($this->aLanguages['system'])) {
128
					$this->aLanguages['system'] = $this->aLanguages['default'];
129
				}
130
			}
131
		// if absolutely no requested language found, simply get the first available language
132
			if(!$bLanguageFound) {
133
				$sFirstLanguage = $oAdaptor->findFirstLanguage();
134
			// load first found language if its not already loaded
135
				if(($aResult = $this->loadLanguageSegments($sFirstLanguage, $oAdaptor)) !== false) {
136
					$this->aLanguages['system'] = $aResult;
137
					$bLanguageFound = true;
138
				}
139
			}
140
			if($bLanguageFound) {
141
				$this->aTranslations = array_merge($this->aTranslations,
142
				                                    $this->aLanguages['system'],
143
				                                    $this->aLanguages['default'],
144
				                                    $this->aLanguages['user']);
145
				if($this->bUseCache) {
146
					$this->writeCacheFile($sCacheFile);
147
				}
148
			}
149 1860 darkviper
		}
150
		return $this;
151
	}
152
/**
153
 * Is key available
154
 * @param string Language key
155
 * @return bool
156
 */
157
	public function __isset($sKey)
158
	{
159 1864 darkviper
		return isset($this->aTranslations[$sKey]);
160 1860 darkviper
	}
161
/**
162
 * Get translation text
163
 * @param string Language key
164
 * @return string Translation text
165
 */
166
	public function __get($sKey)
167
	{
168 1864 darkviper
		if(isset($this->aTranslations[$sKey])) {
169
			return $this->aTranslations[$sKey];
170 1860 darkviper
		}else {
171
			return '';
172
		}
173
	}
174
/**
175
 * returns the whoole translation array
176
 * @return array
177
 * @deprecated for backward compatibility only. Will be removed shortly
178
 */
179
	public function getArray()
180
	{
181 1864 darkviper
		$aRetval = (is_array($this->aTranslations) ? $this->aTranslations : array());
182
		return $aRetval;
183 1860 darkviper
	}
184 1864 darkviper
/**
185
 * Load Language
186
 * @param string Language Code
187
 * @param object Adaptor object
188
 * @return bool|array
189
 */
190
	protected function loadLanguageSegments($sLangCode, $oAdaptor)
191
	{
192
		$aTranslations = array();
193
		// sanitize the language code
194
		$aLangCode = explode('_', preg_replace('/[^a-z0-9]/i', '_', strtolower($sLangCode)));
195
		$sConcatedLang = '';
196
		foreach($aLangCode as $sLang)
197
		{ // iterate all segments of the language code
198
			if( ($aResult = $oAdaptor->loadLanguage($sConcatedLang.$sLang)) !== false ) {
199
				$aTranslations = array_merge($aTranslations, $aResult);
200
			}
201
		}
202
		return (sizeof($aTranslations) > 0 ? $aTranslations : false);
203
	}
204
/**
205
 * getCachePath
206
 * @return string a valid path for caching or null on error
207
 */
208
	protected function getCachePath()
209
	{
210
		$sCachePath = $this->sTempPath.__CLASS__.'/cache/';
211
		if(!file_exists($sCachePath) && is_writeable($this->sTempPath)) {
212
			$iOldUmask = umask(0);
213
			mkdir($sCachePath, $this->iDirMode, true);
214
			umask($iOldUmask);
215
		}
216
		if(is_writable($sCachePath)) {
217
			return $sCachePath;
218
		}else {
219
			return null;
220
		}
221
	}
222
/**
223
 * load cached translation table
224
 * @param string path/name of the cachefile
225
 * @return array list of translations
226
 */
227
	protected function loadCacheFile($sCacheFile)
228
	{
229
		$aTranslation = array();
230
		include($sCacheFile);
231
		return $aTranslation;
232
	}
233
/**
234
 * Write cache from translation
235
 * @param string path/name of the cachefile
236
 */
237
	protected function writeCacheFile($sCacheFile)
238
	{
239
		$sOutput = '<?php'."\n".'/* autogenerated cachefile */'."\n";
240
		while (list($key, $value) = each($this->aTranslations)) {
241
			$sOutput .= '$aTranslation[\''.$key.'\'] = \''.addslashes($value).'\';'."\n";
242
		}
243
		file_put_contents($sCacheFile, $sOutput, LOCK_EX);
244
	}
245 1860 darkviper
} // end of class TranslationTable