00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 class Mage_Core_Model_Translate
00033 {
00034 const CSV_SEPARATOR = ',';
00035 const SCOPE_SEPARATOR = '::';
00036 const CACHE_TAG = 'translate';
00037
00038 const CONFIG_KEY_AREA = 'area';
00039 const CONFIG_KEY_LOCALE = 'locale';
00040 const CONFIG_KEY_STORE = 'store';
00041 const CONFIG_KEY_DESIGN_PACKAGE = 'package';
00042 const CONFIG_KEY_DESIGN_THEME = 'theme';
00043
00044
00045
00046
00047
00048
00049 protected $_locale;
00050
00051
00052
00053
00054
00055
00056 protected $_translate;
00057
00058
00059
00060
00061
00062
00063 protected $_config;
00064
00065 protected $_useCache = true;
00066
00067
00068
00069
00070
00071
00072 protected $_cacheId;
00073
00074
00075
00076
00077
00078
00079 protected $_data = array();
00080
00081
00082
00083
00084
00085
00086 protected $_dataScope;
00087
00088
00089
00090
00091
00092
00093 protected $_translateInline;
00094
00095
00096
00097
00098
00099
00100 protected $_canUseInline = true;
00101
00102 public function __construct()
00103 {
00104 }
00105
00106
00107
00108
00109
00110
00111
00112 public function init($area, $forceReload = false)
00113 {
00114 $this->setConfig(array(self::CONFIG_KEY_AREA=>$area));
00115
00116 $this->_translateInline = Mage::getSingleton('core/translate_inline')
00117 ->isAllowed($area=='adminhtml' ? 'admin' : null);
00118
00119 if (!$forceReload) {
00120 if ($this->_canUseCache()) {
00121 $this->_data = $this->_loadCache();
00122 if ($this->_data !== false) {
00123 return $this;
00124 }
00125 }
00126 Mage::app()->removeCache($this->getCacheId());
00127 }
00128
00129 $this->_data = array();
00130
00131 foreach ($this->getModulesConfig() as $moduleName=>$info) {
00132 $info = $info->asArray();
00133 $this->_loadModuleTranslation($moduleName, $info['files'], $forceReload);
00134 }
00135
00136 $this->_loadThemeTranslation($forceReload);
00137 $this->_loadDbTranslation($forceReload);
00138
00139 if (!$forceReload && $this->_canUseCache()) {
00140 $this->_saveCache();
00141 }
00142
00143 return $this;
00144 }
00145
00146
00147
00148
00149
00150
00151 public function getModulesConfig()
00152 {
00153 if (!Mage::getConfig()->getNode($this->getConfig(self::CONFIG_KEY_AREA).'/translate/modules')) {
00154 return array();
00155 }
00156
00157 $config = Mage::getConfig()->getNode($this->getConfig(self::CONFIG_KEY_AREA).'/translate/modules')->children();
00158 if (!$config) {
00159 return array();
00160 }
00161 return $config;
00162 }
00163
00164
00165
00166
00167
00168
00169
00170 public function setConfig($config)
00171 {
00172 $this->_config = $config;
00173 if (!isset($this->_config[self::CONFIG_KEY_LOCALE])) {
00174 $this->_config[self::CONFIG_KEY_LOCALE] = $this->getLocale();
00175 }
00176 if (!isset($this->_config[self::CONFIG_KEY_STORE])) {
00177 $this->_config[self::CONFIG_KEY_STORE] = Mage::app()->getStore()->getId();
00178 }
00179 if (!isset($this->_config[self::CONFIG_KEY_DESIGN_PACKAGE])) {
00180 $this->_config[self::CONFIG_KEY_DESIGN_PACKAGE] = Mage::getDesign()->getPackageName();
00181 }
00182 if (!isset($this->_config[self::CONFIG_KEY_DESIGN_THEME])) {
00183 $this->_config[self::CONFIG_KEY_DESIGN_THEME] = Mage::getDesign()->getTheme('locale');
00184 }
00185 return $this;
00186 }
00187
00188
00189
00190
00191
00192
00193
00194 public function getConfig($key)
00195 {
00196 if (isset($this->_config[$key])) {
00197 return $this->_config[$key];
00198 }
00199 return null;
00200 }
00201
00202
00203
00204
00205
00206
00207
00208
00209 protected function _loadModuleTranslation($moduleName, $files, $forceReload=false)
00210 {
00211 foreach ($files as $file) {
00212 $file = $this->_getModuleFilePath($moduleName, $file);
00213 $this->_addData($this->_getFileData($file), $moduleName, $forceReload);
00214 }
00215 return $this;
00216 }
00217
00218
00219
00220
00221
00222
00223
00224
00225 protected function _addData($data, $scope, $forceReload=false)
00226 {
00227 foreach ($data as $key => $value) {
00228 if ($key === $value) {
00229 continue;
00230 }
00231 $key = $this->_prepareDataString($key);
00232 $value = $this->_prepareDataString($value);
00233 if ($scope && isset($this->_dataScope[$key]) && !$forceReload ) {
00234
00235
00236
00237 $scopeKey = $this->_dataScope[$key] . self::SCOPE_SEPARATOR . $key;
00238 if (!isset($this->_data[$scopeKey])) {
00239 if (isset($this->_data[$key])) {
00240 $this->_data[$scopeKey] = $this->_data[$key];
00241
00242
00243
00244 if (Mage::getIsDeveloperMode()) {
00245 unset($this->_data[$key]);
00246 }
00247 }
00248 }
00249 $scopeKey = $scope . self::SCOPE_SEPARATOR . $key;
00250 $this->_data[$scopeKey] = $value;
00251 }
00252 else {
00253 $this->_data[$key] = $value;
00254 $this->_dataScope[$key]= $scope;
00255 }
00256 }
00257 return $this;
00258 }
00259
00260 protected function _prepareDataString($string)
00261 {
00262 return str_replace('""', '"', $string);
00263 }
00264
00265
00266
00267
00268
00269
00270 protected function _loadThemeTranslation($forceReload = false)
00271 {
00272 $file = Mage::getDesign()->getLocaleFileName('translate.csv');
00273 $this->_addData($this->_getFileData($file), false, $forceReload);
00274 return $this;
00275 }
00276
00277
00278
00279
00280
00281
00282 protected function _loadDbTranslation($forceReload = false)
00283 {
00284 $arr = $this->getResource()->getTranslationArray();
00285 $this->_addData($arr, $this->getConfig(self::CONFIG_KEY_STORE), $forceReload);
00286 return $this;
00287 }
00288
00289
00290
00291
00292
00293
00294
00295 protected function _getModuleFilePath($module, $fileName)
00296 {
00297
00298 $file = Mage::getBaseDir('locale');
00299 $file.= DS.$this->getLocale().DS.$fileName;
00300 return $file;
00301 }
00302
00303
00304
00305
00306
00307
00308
00309 protected function _getFileData($file)
00310 {
00311 $data = array();
00312 if (file_exists($file)) {
00313 $parser = new Varien_File_Csv();
00314 $parser->setDelimiter(self::CSV_SEPARATOR);
00315 $data = $parser->getDataPairs($file);
00316 }
00317 return $data;
00318 }
00319
00320
00321
00322
00323
00324
00325 public function getData()
00326 {
00327 if (is_null($this->_data)) {
00328 return array();
00329
00330 }
00331 return $this->_data;
00332 }
00333
00334
00335
00336
00337
00338
00339 public function getLocale()
00340 {
00341 if (is_null($this->_locale)) {
00342 $this->_locale = Mage::app()->getLocale()->getLocaleCode();
00343 }
00344 return $this->_locale;
00345 }
00346
00347 public function setLocale( $locale )
00348 {
00349 $this->_locale = $locale;
00350 return $this;
00351 }
00352
00353
00354
00355
00356
00357
00358 public function getResource()
00359 {
00360 return Mage::getResourceSingleton('core/translate');
00361 }
00362
00363
00364
00365
00366
00367
00368 public function getTranslate()
00369 {
00370 if (is_null($this->_translate)) {
00371 $this->_translate = new Zend_Translate('array', $this->getData(), $this->getLocale());
00372 }
00373 return $this->_translate;
00374 }
00375
00376
00377
00378
00379
00380
00381
00382 public function translate($args)
00383 {
00384 $text = array_shift($args);
00385
00386 if (is_string($text) && ''==$text
00387 || is_null($text)
00388 || is_bool($text) && false===$text
00389 || is_object($text) && ''==$text->getText()) {
00390 return '';
00391 }
00392 if ($text instanceof Mage_Core_Model_Translate_Expr) {
00393 $code = $text->getCode(self::SCOPE_SEPARATOR);
00394 $module = $text->getModule();
00395 $text = $text->getText();
00396 $translated = $this->_getTranslatedString($text, $code);
00397 }
00398 else {
00399 if (!empty($_REQUEST['theme'])) {
00400 $module = 'frontend/default/'.$_REQUEST['theme'];
00401 } else {
00402 $module = 'frontend/default/default';
00403 }
00404 $code = $module.self::SCOPE_SEPARATOR.$text;
00405 $translated = $this->_getTranslatedString($text, $code);
00406 }
00407
00408
00409
00410
00411 $result = @vsprintf($translated, $args);
00412 if ($result === false) {
00413 $result = $translated;
00414 }
00415
00416 if ($result === false){
00417 $result = $translated;
00418 }
00419
00420 if ($this->_translateInline && $this->getTranslateInline()) {
00421 if (strpos($result, '{{{')===false || strpos($result, '}}}')===false || strpos($result, '}}{{')===false) {
00422 $result = '{{{'.$result.'}}{{'.$translated.'}}{{'.$text.'}}{{'.$module.'}}}';
00423 }
00424 }
00425
00426 return $result;
00427 }
00428
00429
00430
00431
00432
00433
00434
00435 public function setTranslateInline($flag=null)
00436 {
00437 $this->_canUseInline = (bool) $flag;
00438 return $this;
00439 }
00440
00441
00442
00443
00444
00445
00446 public function getTranslateInline()
00447 {
00448 return $this->_canUseInline;
00449 }
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459 public function getTemplateFile($file, $type, $localeCode=null)
00460 {
00461 if (is_null($localeCode) || preg_match('/[^a-zA-Z_]/', $localeCode)) {
00462 $localeCode = $this->getLocale();
00463 }
00464
00465 $filePath = Mage::getBaseDir('locale') . DS
00466 . $localeCode . DS . 'template' . DS . $type . DS . $file;
00467
00468 if (!file_exists($filePath)) {
00469 $filePath = Mage::getBaseDir('locale') . DS
00470 . Mage::app()->getLocale()->getDefaultLocale()
00471 . DS . 'template' . DS . $type . DS . $file;
00472 }
00473
00474 if (!file_exists($filePath)) {
00475 $filePath = Mage::getBaseDir('locale') . DS
00476 . Mage_Core_Model_Locale::DEFAULT_LOCALE
00477 . DS . 'template' . DS . $type . DS . $file;
00478 }
00479
00480 $ioAdapter = new Varien_Io_File();
00481 $ioAdapter->open(array('path' => Mage::getBaseDir('locale')));
00482
00483 return (string) $ioAdapter->read($filePath);
00484 }
00485
00486
00487
00488
00489
00490
00491 public function getCacheId()
00492 {
00493 if (is_null($this->_cacheId)) {
00494 $this->_cacheId = 'translate';
00495 if (isset($this->_config[self::CONFIG_KEY_LOCALE])) {
00496 $this->_cacheId.= '_'.$this->_config[self::CONFIG_KEY_LOCALE];
00497 }
00498 if (isset($this->_config[self::CONFIG_KEY_AREA])) {
00499 $this->_cacheId.= '_'.$this->_config[self::CONFIG_KEY_AREA];
00500 }
00501 if (isset($this->_config[self::CONFIG_KEY_STORE])) {
00502 $this->_cacheId.= '_'.$this->_config[self::CONFIG_KEY_STORE];
00503 }
00504 if (isset($this->_config[self::CONFIG_KEY_DESIGN_PACKAGE])) {
00505 $this->_cacheId.= '_'.$this->_config[self::CONFIG_KEY_DESIGN_PACKAGE];
00506 }
00507 if (isset($this->_config[self::CONFIG_KEY_DESIGN_THEME])) {
00508 $this->_cacheId.= '_'.$this->_config[self::CONFIG_KEY_DESIGN_THEME];
00509 }
00510 }
00511 return $this->_cacheId;
00512 }
00513
00514
00515
00516
00517
00518
00519
00520 protected function _loadCache()
00521 {
00522 if (!$this->_canUseCache()) {
00523 return false;
00524 }
00525 $data = Mage::app()->loadCache($this->getCacheId());
00526 $data = unserialize($data);
00527 return $data;
00528 }
00529
00530
00531
00532
00533
00534
00535
00536 protected function _saveCache()
00537 {
00538 if (!$this->_canUseCache()) {
00539 return $this;
00540 }
00541 Mage::app()->saveCache(serialize($this->getData()), $this->getCacheId(), array(self::CACHE_TAG), null);
00542 return $this;
00543 }
00544
00545
00546
00547
00548
00549
00550 protected function _canUseCache()
00551 {
00552 return Mage::app()->useCache('translate');
00553 }
00554
00555
00556
00557
00558
00559
00560
00561
00562 protected function _getTranslatedString($text, $code)
00563 {
00564 $translated = '';
00565 if (array_key_exists($code, $this->getData())) {
00566 $translated = $this->_data[$code];
00567 }
00568 elseif (array_key_exists($text, $this->getData())) {
00569 $translated = $this->_data[$text];
00570 }
00571 else {
00572 $translated = $text;
00573 }
00574 return $translated;
00575 }
00576 }