1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
26:
27: 28: 29: 30: 31:
32: class Mage_Core_Model_Locale
33: {
34: 35: 36:
37: const DEFAULT_LOCALE = 'en_US';
38: const DEFAULT_TIMEZONE = 'UTC';
39: const DEFAULT_CURRENCY = 'USD';
40:
41: 42: 43:
44: const XML_PATH_DEFAULT_LOCALE = 'general/locale/code';
45: const XML_PATH_DEFAULT_TIMEZONE = 'general/locale/timezone';
46: 47: 48:
49: const XML_PATH_DEFAULT_COUNTRY = 'general/country/default';
50: const XML_PATH_ALLOW_CODES = 'global/locale/allow/codes';
51: const XML_PATH_ALLOW_CURRENCIES = 'global/locale/allow/currencies';
52: const XML_PATH_ALLOW_CURRENCIES_INSTALLED = 'system/currency/installed';
53:
54: 55: 56:
57: const FORMAT_TYPE_FULL = 'full';
58: const FORMAT_TYPE_LONG = 'long';
59: const FORMAT_TYPE_MEDIUM= 'medium';
60: const FORMAT_TYPE_SHORT = 'short';
61:
62: 63: 64: 65: 66:
67: protected $_defaultLocale;
68:
69: 70: 71: 72: 73:
74: protected $_locale;
75:
76: 77: 78: 79: 80:
81: protected $_localeCode;
82:
83: 84: 85: 86: 87:
88: protected $_emulatedLocales = array();
89:
90: protected static $_currencyCache = array();
91:
92: public function __construct($locale = null)
93: {
94: $this->setLocale($locale);
95: }
96:
97: 98: 99: 100: 101: 102:
103: public function setDefaultLocale($locale)
104: {
105: $this->_defaultLocale = $locale;
106: return $this;
107: }
108:
109: 110: 111: 112: 113:
114: public function getDefaultLocale()
115: {
116: if (!$this->_defaultLocale) {
117: $locale = Mage::getStoreConfig(self::XML_PATH_DEFAULT_LOCALE);
118: if (!$locale) {
119: $locale = self::DEFAULT_LOCALE;
120: }
121: $this->_defaultLocale = $locale;
122: }
123: return $this->_defaultLocale;
124: }
125:
126: 127: 128: 129: 130: 131:
132: public function setLocale($locale = null)
133: {
134: if (($locale !== null) && is_string($locale)) {
135: $this->_localeCode = $locale;
136: } else {
137: $this->_localeCode = $this->getDefaultLocale();
138: }
139: Mage::dispatchEvent('core_locale_set_locale', array('locale'=>$this));
140: return $this;
141: }
142:
143: 144: 145: 146: 147:
148: public function getTimezone()
149: {
150: return self::DEFAULT_TIMEZONE;
151: }
152:
153: 154: 155: 156: 157:
158: public function getCurrency()
159: {
160: return self::DEFAULT_CURRENCY;
161: }
162:
163: 164: 165: 166: 167:
168: public function getLocale()
169: {
170: if (!$this->_locale) {
171: Zend_Locale_Data::setCache(Mage::app()->getCache());
172: $this->_locale = new Zend_Locale($this->getLocaleCode());
173: } elseif ($this->_locale->__toString() != $this->_localeCode) {
174: $this->setLocale($this->_localeCode);
175: }
176:
177: return $this->_locale;
178: }
179:
180: 181: 182: 183: 184:
185: public function getLocaleCode()
186: {
187: if ($this->_localeCode === null) {
188: $this->setLocale();
189: }
190: return $this->_localeCode;
191: }
192:
193: 194: 195: 196: 197: 198:
199: public function setLocaleCode($code)
200: {
201: $this->_localeCode = $code;
202: $this->_locale = null;
203: return $this;
204: }
205:
206: 207: 208: 209: 210:
211: public function getOptionLocales()
212: {
213: return $this->_getOptionLocales();
214: }
215:
216: 217: 218: 219: 220:
221: public function getTranslatedOptionLocales()
222: {
223: return $this->_getOptionLocales(true);
224: }
225:
226: 227: 228: 229: 230: 231:
232: protected function _getOptionLocales($translatedName=false)
233: {
234: $options = array();
235: $locales = $this->getLocale()->getLocaleList();
236: $languages = $this->getLocale()->getTranslationList('language', $this->getLocale());
237: $countries = $this->getCountryTranslationList();
238:
239: $allowed = $this->getAllowLocales();
240: foreach ($locales as $code=>$active) {
241: if (strstr($code, '_')) {
242: if (!in_array($code, $allowed)) {
243: continue;
244: }
245: $data = explode('_', $code);
246: if (!isset($languages[$data[0]]) || !isset($countries[$data[1]])) {
247: continue;
248: }
249: if ($translatedName) {
250: $label = ucwords($this->getLocale()->getTranslation($data[0], 'language', $code))
251: . ' (' . $this->getLocale()->getTranslation($data[1], 'country', $code) . ') / '
252: . $languages[$data[0]] . ' (' . $countries[$data[1]] . ')';
253: } else {
254: $label = $languages[$data[0]] . ' (' . $countries[$data[1]] . ')';
255: }
256: $options[] = array(
257: 'value' => $code,
258: 'label' => $label
259: );
260: }
261: }
262: return $this->_sortOptionArray($options);
263: }
264:
265: 266: 267: 268: 269:
270: public function getOptionTimezones()
271: {
272: $options= array();
273: $zones = $this->getTranslationList('windowstotimezone');
274: ksort($zones);
275: foreach ($zones as $code=>$name) {
276: $name = trim($name);
277: $options[] = array(
278: 'label' => empty($name) ? $code : $name . ' (' . $code . ')',
279: 'value' => $code,
280: );
281: }
282: return $this->_sortOptionArray($options);
283: }
284:
285: 286: 287: 288: 289:
290: public function getOptionWeekdays()
291: {
292: $options= array();
293: $days = $this->getTranslationList('days');
294: foreach (array_values($days['format']['wide']) as $code => $name) {
295: $options[] = array(
296: 'label' => $name,
297: 'value' => $code,
298: );
299: }
300: return $options;
301: }
302:
303: 304: 305: 306: 307:
308: public function getOptionCountries()
309: {
310: $options = array();
311: $countries = $this->getCountryTranslationList();
312:
313: foreach ($countries as $code=>$name) {
314: $options[] = array(
315: 'label' => $name,
316: 'value' => $code,
317: );
318: }
319: return $this->_sortOptionArray($options);
320: }
321:
322: 323: 324: 325: 326:
327: public function getOptionCurrencies()
328: {
329: $currencies = $this->getTranslationList('currencytoname');
330: $options = array();
331: $allowed = $this->getAllowCurrencies();
332:
333: foreach ($currencies as $name=>$code) {
334: if (!in_array($code, $allowed)) {
335: continue;
336: }
337:
338: $options[] = array(
339: 'label' => $name,
340: 'value' => $code,
341: );
342: }
343: return $this->_sortOptionArray($options);
344: }
345:
346: 347: 348: 349: 350:
351: public function getOptionAllCurrencies()
352: {
353: $currencies = $this->getTranslationList('currencytoname');
354: $options = array();
355: foreach ($currencies as $name=>$code) {
356: $options[] = array(
357: 'label' => $name,
358: 'value' => $code,
359: );
360: }
361: return $this->_sortOptionArray($options);
362: }
363:
364: protected function _sortOptionArray($option)
365: {
366: $data = array();
367: foreach ($option as $item) {
368: $data[$item['value']] = $item['label'];
369: }
370: asort($data);
371: $option = array();
372: foreach ($data as $key => $label) {
373: $option[] = array(
374: 'value' => $key,
375: 'label' => $label
376: );
377: }
378: return $option;
379: }
380:
381: 382: 383: 384: 385:
386: public function getAllowLocales()
387: {
388: return Mage::getSingleton('core/locale_config')->getAllowedLocales();
389: }
390:
391: 392: 393: 394: 395:
396: public function getAllowCurrencies()
397: {
398: $data = array();
399: if (Mage::isInstalled()) {
400: $data = Mage::app()->getStore()->getConfig(self::XML_PATH_ALLOW_CURRENCIES_INSTALLED);
401: return explode(',', $data);
402: } else {
403: $data = Mage::getSingleton('core/locale_config')->getAllowedCurrencies();
404: }
405: return $data;
406: }
407:
408: 409: 410: 411: 412: 413:
414: public function getDateFormat($type=null)
415: {
416: return $this->getTranslation($type, 'date');
417: }
418:
419: 420: 421: 422: 423:
424: public function getDateFormatWithLongYear()
425: {
426: return preg_replace('/(?<!y)yy(?!y)/', 'yyyy',
427: $this->getTranslation(Mage_Core_Model_Locale::FORMAT_TYPE_SHORT, 'date'));
428: }
429:
430:
431: 432: 433: 434: 435: 436:
437: public function getTimeFormat($type=null)
438: {
439: return $this->getTranslation($type, 'time');
440: }
441:
442: 443: 444: 445: 446: 447:
448: public function getDateTimeFormat($type)
449: {
450: return $this->getDateFormat($type) . ' ' . $this->getTimeFormat($type);
451: }
452:
453: 454: 455: 456: 457: 458:
459: public function getDateStrFormat($type)
460: {
461: return Varien_Date::convertZendToStrftime($this->getDateFormat($type), true, false);
462: }
463:
464: 465: 466: 467: 468: 469:
470: public function getTimeStrFormat($type)
471: {
472: return Varien_Date::convertZendToStrftime($this->getTimeFormat($type), false, true);
473: }
474:
475: 476: 477: 478: 479: 480: 481: 482: 483:
484: public function date($date = null, $part = null, $locale = null, $useTimezone = true)
485: {
486: if (is_null($locale)) {
487: $locale = $this->getLocale();
488: }
489:
490: if (empty($date)) {
491:
492: $date = null;
493: }
494: $date = new Zend_Date($date, $part, $locale);
495: if ($useTimezone) {
496: if ($timezone = Mage::app()->getStore()->getConfig(self::XML_PATH_DEFAULT_TIMEZONE)) {
497: $date->setTimezone($timezone);
498: }
499: }
500:
501: return $date;
502: }
503:
504: 505: 506: 507: 508: 509: 510: 511:
512: public function storeDate($store=null, $date=null, $includeTime=false)
513: {
514: $timezone = Mage::app()->getStore($store)->getConfig(self::XML_PATH_DEFAULT_TIMEZONE);
515: $date = new Zend_Date($date, null, $this->getLocale());
516: $date->setTimezone($timezone);
517: if (!$includeTime) {
518: $date->setHour(0)
519: ->setMinute(0)
520: ->setSecond(0);
521: }
522: return $date;
523: }
524:
525: 526: 527: 528: 529: 530: 531: 532: 533: 534: 535:
536: public function utcDate($store=null, $date, $includeTime = false, $format = null)
537: {
538: $dateObj = $this->storeDate($store, $date, $includeTime);
539: $dateObj->set($date, $format);
540: $dateObj->setTimezone(Mage_Core_Model_Locale::DEFAULT_TIMEZONE);
541: return $dateObj;
542: }
543:
544: 545: 546: 547: 548: 549: 550:
551: public function storeTimeStamp($store=null)
552: {
553: $timezone = Mage::app()->getStore($store)->getConfig(self::XML_PATH_DEFAULT_TIMEZONE);
554: $currentTimezone = @date_default_timezone_get();
555: @date_default_timezone_set($timezone);
556: $date = date('Y-m-d H:i:s');
557: @date_default_timezone_set($currentTimezone);
558: return strtotime($date);
559: }
560:
561: 562: 563: 564: 565: 566:
567: public function currency($currency)
568: {
569: Varien_Profiler::start('locale/currency');
570: if (!isset(self::$_currencyCache[$this->getLocaleCode()][$currency])) {
571: $options = array();
572: try {
573: $currencyObject = new Zend_Currency($currency, $this->getLocale());
574: } catch (Exception $e) {
575: $currencyObject = new Zend_Currency($this->getCurrency(), $this->getLocale());
576: $options['name'] = $currency;
577: $options['currency'] = $currency;
578: $options['symbol'] = $currency;
579: }
580:
581: $options = new Varien_Object($options);
582: Mage::dispatchEvent('currency_display_options_forming', array(
583: 'currency_options' => $options,
584: 'base_code' => $currency
585: ));
586:
587: $currencyObject->setFormat($options->toArray());
588: self::$_currencyCache[$this->getLocaleCode()][$currency] = $currencyObject;
589: }
590: Varien_Profiler::stop('locale/currency');
591: return self::$_currencyCache[$this->getLocaleCode()][$currency];
592: }
593:
594: 595: 596: 597: 598: 599: 600: 601: 602: 603: 604: 605: 606: 607: 608: 609: 610:
611: public function getNumber($value)
612: {
613: if (is_null($value)) {
614: return null;
615: }
616:
617: if (!is_string($value)) {
618: return floatval($value);
619: }
620:
621:
622: $value = str_replace(array('\'', ' '), '', $value);
623:
624: $separatorComa = strpos($value, ',');
625: $separatorDot = strpos($value, '.');
626:
627: if ($separatorComa !== false && $separatorDot !== false) {
628: if ($separatorComa > $separatorDot) {
629: $value = str_replace('.', '', $value);
630: $value = str_replace(',', '.', $value);
631: }
632: else {
633: $value = str_replace(',', '', $value);
634: }
635: }
636: elseif ($separatorComa !== false) {
637: $value = str_replace(',', '.', $value);
638: }
639:
640: return floatval($value);
641: }
642:
643: 644: 645: 646: 647: 648:
649: public function getJsPriceFormat()
650: {
651: $format = Zend_Locale_Data::getContent($this->getLocaleCode(), 'currencynumber');
652: $symbols = Zend_Locale_Data::getList($this->getLocaleCode(), 'symbols');
653:
654: $pos = strpos($format, ';');
655: if ($pos !== false){
656: $format = substr($format, 0, $pos);
657: }
658: $format = preg_replace("/[^0\#\.,]/", "", $format);
659: $totalPrecision = 0;
660: $decimalPoint = strpos($format, '.');
661: if ($decimalPoint !== false) {
662: $totalPrecision = (strlen($format) - (strrpos($format, '.')+1));
663: } else {
664: $decimalPoint = strlen($format);
665: }
666: $requiredPrecision = $totalPrecision;
667: $t = substr($format, $decimalPoint);
668: $pos = strpos($t, '#');
669: if ($pos !== false){
670: $requiredPrecision = strlen($t) - $pos - $totalPrecision;
671: }
672: $group = 0;
673: if (strrpos($format, ',') !== false) {
674: $group = ($decimalPoint - strrpos($format, ',') - 1);
675: } else {
676: $group = strrpos($format, '.');
677: }
678: $integerRequired = (strpos($format, '.') - strpos($format, '0'));
679:
680: $result = array(
681: 'pattern' => Mage::app()->getStore()->getCurrentCurrency()->getOutputFormat(),
682: 'precision' => $totalPrecision,
683: 'requiredPrecision' => $requiredPrecision,
684: 'decimalSymbol' => $symbols['decimal'],
685: 'groupSymbol' => $symbols['group'],
686: 'groupLength' => $group,
687: 'integerRequired' => $integerRequired
688: );
689:
690: return $result;
691: }
692:
693: 694: 695: 696: 697: 698:
699: public function emulate($storeId)
700: {
701: if ($storeId) {
702: $this->_emulatedLocales[] = clone $this->getLocale();
703: $this->_locale = new Zend_Locale(Mage::getStoreConfig(self::XML_PATH_DEFAULT_LOCALE, $storeId));
704: $this->_localeCode = $this->_locale->toString();
705: Mage::getSingleton('core/translate')->setLocale($this->_locale)->init('frontend', true);
706: }
707: else {
708: $this->_emulatedLocales[] = false;
709: }
710: }
711:
712: 713: 714: 715:
716: public function revert()
717: {
718: if ($locale = array_pop($this->_emulatedLocales)) {
719: $this->_locale = $locale;
720: $this->_localeCode = $this->_locale->toString();
721: Mage::getSingleton('core/translate')->setLocale($this->_locale)->init('adminhtml', true);
722: }
723: }
724:
725: 726: 727: 728: 729: 730: 731: 732: 733:
734: public function getTranslationList($path = null, $value = null)
735: {
736: return $this->getLocale()->getTranslationList($path, $this->getLocale(), $value);
737: }
738:
739: 740: 741: 742: 743: 744: 745: 746:
747: public function getTranslation($value = null, $path = null)
748: {
749: return $this->getLocale()->getTranslation($value, $path, $this->getLocale());
750: }
751:
752: 753: 754: 755: 756: 757:
758: public function getCountryTranslation($value)
759: {
760: return $this->getLocale()->getTranslation($value, 'country', $this->getLocale());
761: }
762:
763: 764: 765: 766: 767:
768: public function getCountryTranslationList()
769: {
770: return $this->getLocale()->getTranslationList('territory', $this->getLocale(), 2);
771: }
772:
773: 774: 775: 776: 777: 778: 779: 780:
781: public function isStoreDateInInterval($store, $dateFrom = null, $dateTo = null)
782: {
783: if (!$store instanceof Mage_Core_Model_Store) {
784: $store = Mage::app()->getStore($store);
785: }
786:
787: $storeTimeStamp = $this->storeTimeStamp($store);
788: $fromTimeStamp = strtotime($dateFrom);
789: $toTimeStamp = strtotime($dateTo);
790: if ($dateTo) {
791:
792: $toTimeStamp += 86400;
793: }
794:
795: $result = false;
796: if (!is_empty_date($dateFrom) && $storeTimeStamp < $fromTimeStamp) {
797: }
798: elseif (!is_empty_date($dateTo) && $storeTimeStamp > $toTimeStamp) {
799: }
800: else {
801: $result = true;
802: }
803:
804: return $result;
805: }
806: }
807: