1: <?php
2:
3: /**
4: * This is a modified version of the default Yii class. The only change that has
5: * been made is the inclusion of "common.php" as a shared source of translation
6: * messages. Ctrl + F for "X2CHANGE" to find the exact location of this customization.
7: */
8: class X2MessageSource extends CMessageSource {
9:
10: const CACHE_KEY_PREFIX = 'Yii.CPhpMessageSource.';
11:
12: /**
13: * @var integer the time in seconds that the messages can remain valid in cache.
14: * Defaults to 0, meaning the caching is disabled.
15: */
16: public $cachingDuration = 0;
17:
18: /**
19: * @var string the ID of the cache application component that is used to cache the messages.
20: * Defaults to 'cache' which refers to the primary cache application component.
21: * Set this property to false if you want to disable caching the messages.
22: */
23: public $cacheID = 'cache';
24:
25: /**
26: * @var string the base path for all translated messages. Defaults to null, meaning
27: * the "messages" subdirectory of the application directory (e.g. "protected/messages").
28: */
29: public $basePath;
30:
31: /**
32: * @var array the message paths for extensions that do not have a base class to use as category prefix.
33: * The format of the array should be:
34: * <pre>
35: * array(
36: * 'ExtensionName' => 'ext.ExtensionName.messages',
37: * )
38: * </pre>
39: * Where the key is the name of the extension and the value is the alias to the path
40: * of the "messages" subdirectory of the extension.
41: * When using Yii::t() to translate an extension message, the category name should be
42: * set as 'ExtensionName.categoryName'.
43: * Defaults to an empty array, meaning no extensions registered.
44: * @since 1.1.13
45: */
46: public $extensionPaths = array();
47:
48: /**
49: * @var boolean Whether or not to log a missing translation if the index is found
50: * in the messages file, but the translation message is blank. For example,
51: * 'X2Engine'=>'' would trigger an onMissingTranslation event if this parameter
52: * is set to true, but will not trigger if it is set to false.
53: */
54: public $logBlankMessages = true;
55: private $_files = array();
56: private $_messages = array();
57:
58: /**
59: * Initializes the application component.
60: * This method overrides the parent implementation by preprocessing
61: * the user request data.
62: */
63: public function init(){
64: parent::init();
65: if($this->basePath === null)
66: $this->basePath = Yii::getPathOfAlias('application.messages');
67: }
68:
69: /**
70: * Translates the specified message.
71: * If the message is not found, an {@link onMissingTranslation}
72: * event will be raised.
73: * @param string $category the category that the message belongs to
74: * @param string $message the message to be translated
75: * @param string $language the target language
76: * @return string the translated message
77: */
78: protected function translateMessage($category, $message, $language){
79: $key = $language.'.'.$category;
80: // X2CHANGE The customization occurs here, see comments below.
81: if(!isset($this->_messages[$key]))
82: $this->_messages[$key] = $this->loadMessages($category, $language); // Load the messages for the chosen language.
83: if(isset($this->_messages[$key][$message]) && $this->_messages[$key][$message] !== ''){
84: return $this->_messages[$key][$message]; // If we find the message in the translation files, return the translated version.
85: }elseif(!isset($this->_messages[$key][$message]) || $this->_messages[$key][$message] == ''){
86: if(!isset($this->_messages['common'])){ // Otherwise, lookup the common file to see if the translation is saved there.
87: $this->_messages['common'] = $this->loadMessages('common', $language);
88: }
89: if(isset($this->_messages['common'][$message])){
90: if($this->_messages['common'][$message] !== ''){
91: return $this->_messages['common'][$message]; // If we find the message in common, return the translated version.
92: }elseif($this->logBlankMessages && $this->hasEventHandler('onMissingTranslation')){
93: $event = new CMissingTranslationEvent($this, $category, $message, $language);
94: $this->onMissingTranslation($event); // If we find the index but not the message
95: return $event->message; // and we're logging blank messages, log the translation issue.
96: }else{
97: return $message; // Otherwise return the starting text.
98: }
99: }
100: if(!Yii::app()->params->noSession && (!isset($this->_messages[$key][$message]) || ($this->_messages[$key][$message] == '' && $this->logBlankMessages)) && $this->hasEventHandler('onMissingTranslation')){
101: $event = new CMissingTranslationEvent($this, $category, $message, $language);
102: $this->onMissingTranslation($event);
103: return $event->message; // Same as above logging, but if we never found anything in common.
104: }else{
105: return $message;
106: }
107: }else
108: return $message;
109: }
110:
111: /**
112: * Determines the message file name based on the given category and language.
113: * If the category name contains a dot, it will be split into the module class name and the category name.
114: * In this case, the message file will be assumed to be located within the 'messages' subdirectory of
115: * the directory containing the module class file.
116: * Otherwise, the message file is assumed to be under the {@link basePath}.
117: * @param string $category category name
118: * @param string $language language ID
119: * @return string the message file path
120: */
121: protected function getMessageFile($category, $language){
122: if(!isset($this->_files[$category][$language])){
123: if(($pos = strpos($category, '.')) !== false){
124: $extensionClass = substr($category, 0, $pos);
125: $extensionCategory = substr($category, $pos + 1);
126: // First check if there's an extension registered for this class.
127: if(isset($this->extensionPaths[$extensionClass]))
128: $this->_files[$category][$language] = Yii::getPathOfAlias($this->extensionPaths[$extensionClass]).DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.$extensionCategory.'.php';
129: else{
130: // No extension registered, need to find it.
131: $class = new ReflectionClass($extensionClass);
132: $this->_files[$category][$language] = dirname($class->getFileName()).DIRECTORY_SEPARATOR.'messages'.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.$extensionCategory.'.php';
133: }
134: } else {
135: if(file_exists('custom'.DIRECTORY_SEPARATOR.'protected'.DIRECTORY_SEPARATOR.'messages'.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.$category.'.php')){
136: $this->_files[$category][$language] = 'custom'.DIRECTORY_SEPARATOR.'protected'.DIRECTORY_SEPARATOR.'messages'.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.$category.'.php';
137: }else{
138: $this->_files[$category][$language] = $this->basePath.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.$category.'.php';
139: }
140: }
141: }
142: return $this->_files[$category][$language];
143: }
144:
145: /**
146: * Loads the message translation for the specified language and category.
147: * @param string $category the message category
148: * @param string $language the target language
149: * @return array the loaded messages
150: */
151: protected function loadMessages($category, $language){
152: $messageFile = $this->getMessageFile($category, $language);
153:
154: if($this->cachingDuration > 0 && $this->cacheID !== false && ($cache = Yii::app()->getComponent($this->cacheID)) !== null){
155: $key = self::CACHE_KEY_PREFIX.$messageFile;
156: if(($data = $cache->get($key)) !== false)
157: return unserialize($data);
158: }
159:
160: if(is_file($messageFile)){
161: $messages = include($messageFile);
162: if(!is_array($messages))
163: $messages = array();
164: if(isset($cache)){
165: $dependency = new CFileCacheDependency($messageFile);
166: $cache->set($key, serialize($messages), $this->cachingDuration, $dependency);
167: }
168: return $messages;
169: }
170: else
171: return array();
172: }
173:
174: }
175:
176: ?>
177: