CDbMessageSource.php
4.39 KB
1
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
<?php
/**
* CDbMessageSource class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright Copyright © 2008-2011 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
/**
* CDbMessageSource represents a message source that stores translated messages in database.
*
* The database must contain the following two tables:
* <pre>
* CREATE TABLE SourceMessage
* (
* id INTEGER PRIMARY KEY,
* category VARCHAR(32),
* message TEXT
* );
* CREATE TABLE Message
* (
* id INTEGER,
* language VARCHAR(16),
* translation TEXT,
* PRIMARY KEY (id, language),
* CONSTRAINT FK_Message_SourceMessage FOREIGN KEY (id)
* REFERENCES SourceMessage (id) ON DELETE CASCADE ON UPDATE RESTRICT
* );
* </pre>
* The 'SourceMessage' table stores the messages to be translated, and the 'Message' table
* stores the translated messages. The name of these two tables can be customized by setting
* {@link sourceMessageTable} and {@link translatedMessageTable}, respectively.
*
* When {@link cachingDuration} is set as a positive number, message translations will be cached.
*
* @property CDbConnection $dbConnection The DB connection used for the message source.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id$
* @package system.i18n
* @since 1.0
*/
class CDbMessageSource extends CMessageSource
{
const CACHE_KEY_PREFIX='Yii.CDbMessageSource.';
/**
* @var string the ID of the database connection application component. Defaults to 'db'.
*/
public $connectionID='db';
/**
* @var string the name of the source message table. Defaults to 'SourceMessage'.
*/
public $sourceMessageTable='SourceMessage';
/**
* @var string the name of the translated message table. Defaults to 'Message'.
*/
public $translatedMessageTable='Message';
/**
* @var integer the time in seconds that the messages can remain valid in cache.
* Defaults to 0, meaning the caching is disabled.
*/
public $cachingDuration=0;
/**
* @var string the ID of the cache application component that is used to cache the messages.
* Defaults to 'cache' which refers to the primary cache application component.
* Set this property to false if you want to disable caching the messages.
*/
public $cacheID='cache';
/**
* Loads the message translation for the specified language and category.
* @param string $category the message category
* @param string $language the target language
* @return array the loaded messages
*/
protected function loadMessages($category,$language)
{
if($this->cachingDuration>0 && $this->cacheID!==false && ($cache=Yii::app()->getComponent($this->cacheID))!==null)
{
$key=self::CACHE_KEY_PREFIX.'.messages.'.$category.'.'.$language;
if(($data=$cache->get($key))!==false)
return unserialize($data);
}
$messages=$this->loadMessagesFromDb($category,$language);
if(isset($cache))
$cache->set($key,serialize($messages),$this->cachingDuration);
return $messages;
}
private $_db;
/**
* Returns the DB connection used for the message source.
* @return CDbConnection the DB connection used for the message source.
* @since 1.1.5
*/
public function getDbConnection()
{
if($this->_db===null)
{
$this->_db=Yii::app()->getComponent($this->connectionID);
if(!$this->_db instanceof CDbConnection)
throw new CException(Yii::t('yii','CDbMessageSource.connectionID is invalid. Please make sure "{id}" refers to a valid database application component.',
array('{id}'=>$this->connectionID)));
}
return $this->_db;
}
/**
* Loads the messages from database.
* You may override this method to customize the message storage in the database.
* @param string $category the message category
* @param string $language the target language
* @return array the messages loaded from database
* @since 1.1.5
*/
protected function loadMessagesFromDb($category,$language)
{
$sql=<<<EOD
SELECT t1.message AS message, t2.translation AS translation
FROM {$this->sourceMessageTable} t1, {$this->translatedMessageTable} t2
WHERE t1.id=t2.id AND t1.category=:category AND t2.language=:language
EOD;
$command=$this->getDbConnection()->createCommand($sql);
$command->bindValue(':category',$category);
$command->bindValue(':language',$language);
$messages=array();
foreach($command->queryAll() as $row)
$messages[$row['message']]=$row['translation'];
return $messages;
}
}