MessageSource.php 3.73 KB
Newer Older
Qiang Xue committed
1 2 3
<?php
/**
 * @link http://www.yiiframework.com/
Qiang Xue committed
4
 * @copyright Copyright (c) 2008 Yii Software LLC
Qiang Xue committed
5 6 7 8 9 10 11 12 13 14 15
 * @license http://www.yiiframework.com/license/
 */

namespace yii\i18n;

use Yii;
use yii\base\Component;

/**
 * MessageSource is the base class for message translation repository classes.
 *
Qiang Xue committed
16
 * A message source stores message translations in some persistent storage.
Qiang Xue committed
17
 *
Qiang Xue committed
18
 * Child classes should override [[loadMessages()]] to provide translated messages.
Qiang Xue committed
19 20 21 22
 *
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @since 2.0
 */
Qiang Xue committed
23
class MessageSource extends Component
Qiang Xue committed
24
{
Qiang Xue committed
25 26 27 28 29
	/**
	 * @event MissingTranslationEvent an event that is triggered when a message translation is not found.
	 */
	const EVENT_MISSING_TRANSLATION = 'missingTranslation';

Qiang Xue committed
30 31 32 33 34
	/**
	 * @var boolean whether to force message translation when the source and target languages are the same.
	 * Defaults to false, meaning translation is only performed when source and target languages are different.
	 */
	public $forceTranslation = false;
Qiang Xue committed
35 36 37 38
	/**
	 * @var string the language that the original messages are in. If not set, it will use the value of
	 * [[\yii\base\Application::sourceLanguage]].
	 */
Qiang Xue committed
39 40 41 42
	public $sourceLanguage;

	private $_messages = array();

Qiang Xue committed
43 44 45
	/**
	 * Initializes this component.
	 */
Qiang Xue committed
46 47 48 49
	public function init()
	{
		parent::init();
		if ($this->sourceLanguage === null) {
Qiang Xue committed
50
			$this->sourceLanguage = Yii::$app->sourceLanguage;
Qiang Xue committed
51 52 53 54 55
		}
	}

	/**
	 * Loads the message translation for the specified language and category.
Qiang Xue committed
56 57
	 * Child classes should override this method to return the message translations of
	 * the specified language and category.
Qiang Xue committed
58 59
	 * @param string $category the message category
	 * @param string $language the target language
Qiang Xue committed
60 61
	 * @return array the loaded messages. The keys are original messages, and the values
	 * are translated messages.
Qiang Xue committed
62
	 */
Qiang Xue committed
63 64 65 66
	protected function loadMessages($category, $language)
	{
		return array();
	}
Qiang Xue committed
67 68 69 70

	/**
	 * Translates a message to the specified language.
	 *
Qiang Xue committed
71 72 73
	 * Note that unless [[forceTranslation]] is true, if the target language
	 * is the same as the [[sourceLanguage|source language]], the message
	 * will NOT be translated.
Qiang Xue committed
74
	 *
Qiang Xue committed
75
	 * If a translation is not found, a [[missingTranslation]] event will be triggered.
Qiang Xue committed
76 77 78
	 *
	 * @param string $category the message category
	 * @param string $message the message to be translated
Qiang Xue committed
79
	 * @param string $language the target language
Qiang Xue committed
80 81 82 83 84 85 86 87 88 89 90 91 92
	 * @return string the translated message (or the original message if translation is not needed)
	 */
	public function translate($category, $message, $language)
	{
		if ($this->forceTranslation || $language !== $this->sourceLanguage) {
			return $this->translateMessage($category, $message, $language);
		} else {
			return $message;
		}
	}

	/**
	 * Translates the specified message.
Qiang Xue committed
93 94
	 * If the message is not found, a [[missingTranslation]] event will be triggered
	 * and the original message will be returned.
Qiang Xue committed
95 96 97 98 99 100 101 102 103 104 105 106 107
	 * @param string $category the category that the message belongs to
	 * @param string $message the message to be translated
	 * @param string $language the target language
	 * @return string the translated message
	 */
	protected function translateMessage($category, $message, $language)
	{
		$key = $language . '/' . $category;
		if (!isset($this->_messages[$key])) {
			$this->_messages[$key] = $this->loadMessages($category, $language);
		}
		if (isset($this->_messages[$key][$message]) && $this->_messages[$key][$message] !== '') {
			return $this->_messages[$key][$message];
Qiang Xue committed
108 109 110 111 112 113 114 115
		} elseif ($this->hasEventHandlers('missingTranslation')) {
			$event = new MissingTranslationEvent(array(
				'category' => $category,
				'message' => $message,
				'language' => $language,
			));
			$this->trigger(self::EVENT_MISSING_TRANSLATION, $event);
			return $this->_messages[$key] = $event->message;
Qiang Xue committed
116 117 118 119 120
		} else {
			return $message;
		}
	}
}