Zend_Translateオブジェクトの生成
Zend_Translateオブジェクトを生成します。
$translate = new Zend_Translate('Wings_Translate_Adapter_MySqlite',
'../languages/db/ja/trans_ja.db',
'ja');
$translate->addTranslation('../languages/db/en/trans_en.db', 'en');
$translate->addTranslation('../languages/db/fr/trans_fr.db', 'fr');
[1]第1引数
第1引数において、自作アダプタを指定します。今回は「Wings_Translate_Adapter_MySqlite」としています。これはアダプタのクラス名であり、かつ、このクラスを記載しているphpファイル(/ZendFramework1.7.0/library/Wings/Translate/Adapter/MySqlite.php)の箇所も指定しています(「/ZendFramework1.7.0/library/」にinclude_pathが通っていることを前提としています)。
また、先頭が「Zend」となるようなクラス名をつけることは禁止されています。先頭が「Zend」となるのを許しているのは、Zend Framework標準で提供されているもののみとなります。
[2]第2引数
第2引数には翻訳ソースとなるファイルを指定します。前半で自動検出を学習したばかりですが、理解のためこちらの原始的な方法で行います。
[3]第3引数
第2引数で指定した翻訳ソースに対応する言語情報(ロケール)となります。
[4]第4引数
オプションを指定する箇所となります。今回は何も指定していませんが、前回の「多言語対応サイトの作成- Zend_Translate(前編)-」を参照し、必要なオプションを指定してください。また、実はオプション自体も自作することができますが、今回は触れません。
Zend_Translateクラスから自作アダプタ呼び出し
次に、Zend_Translateクラス内で、生成時に引数「Wings_Translate_Adapter_Sqlite」を指定された場合に、Wings_Translate_Adapter_Sqliteオブジェクトをアダプタとして生成するように、改造を加えます。対象のファイルは「/ZendFramwork1.7.0/library/Zend/Translate/Translate.php」です。必ずバックアップをとりましょう。
class Zend_Translate {
/**
* Adapter names constants
*/
const AN_ARRAY = 'array';
const AN_CSV = 'csv';
const AN_GETTEXT = 'gettext';
const AN_INI = 'ini';
const AN_QT = 'qt';
const AN_TBX = 'tbx';
const AN_TMX = 'tmx';
const AN_XLIFF = 'xliff';
const AN_XMLTM = 'xmltm';
//[1]自作アダプタ用定数を定義する
const AN_WINGS_SQLITE = 'Wings_Translate_Adapter_MySqlite';
(省略)
public function setAdapter($adapter, $data, $locale = null, array $options = array())
{
//[2]第1引数が自作アダプタ名だった場合、自作アダプタクラスをアダプタとして指定する
if($adapter == AN_WINGS_SQLITE) {
if(Zend_Loader::isReadable($adapter . '.php')) {
$adapter = $adapter;
}
} else {
if (Zend_Loader::isReadable('Zend/Translate/Adapter/' . ucfirst($adapter). '.php')) {
$adapter = 'Zend_Translate_Adapter_' . ucfirst($adapter);
}
}
//[3]アダプタ呼び出し
Zend_Loader::loadClass($adapter);
(省略)
[1]自作アダプタ用定数を定義する
他のアダプタにならって、自作アダプタ用定数を定義します。前バージョンまでは、Zend_Translate生成時の第1引数がこれらのアダプタ名定数に当てはまる場合は、それに対応するアダプタクラスを呼び出す、という処理に使用されていました。1.7.0ではこの定数は実は使われていません。本稿では前バージョンのような場合分けをするために定数を定義しました。
[2]第1引数が自作アダプタ名だった場合、自作アダプタクラスをアダプタとして指定する
setAdapterメソッドに改造を加えます。この関数はZend_Translateクラスのコンストラクタから呼び出されています。
Zend_Translateオブジェクト生成時の第1引数$adapterが自作アダプタ名だったら、自作アダプタクラスの記載されているファイルの存在を確認してから$adapterを自作アダプタとします。もし自作アダプタ名以外が第1引数に指定されていたら、既存の処理を行います。
[3]アダプタ呼び出し
$adapterに指定されたアダプタを呼び出します。loadClassメソッドでは引数に指定されたクラスを呼び出します。その際、クラス名の「_(アンダースコア)」をパスの区切りとして、最後に「.php」をつけたファイルがそのクラスの定義ファイルとして検索されます。
自作アダプタクラスを作成する
いよいよ、自作アダプタクラスを作成します。自作アダプタはZend_Translate_Adapterのサブクラスとなりますが、Zend_Translate_Adapterは抽象クラスです。どのように定義されているのかソース(/ZendFramework1.7.0/library/Zend/Translate/Adapter.php)を見てみましょう。
abstract class Zend_Translate_Adapter {
(中略)
/**
* Translation table
* @var array
*/
protected $_translate = array();
(中略)
/**
* Load translation data
*
* @param mixed $data
* @param string|Zend_Locale $locale
* @param array $options (optional)
* @return void
*/
abstract protected function _loadTranslationData($data, $locale, array $options = array());
(中略)
/**
* Returns the adapter name
*
* @return string
*/
abstract public function toString();
}
abstractのついているメソッド(抽象メソッド)が2つあると思います。1つは翻訳データをarray型の翻訳テーブル($_translate)に格納する動作を行う「_loadTranslationData」、もう1つがアダプタクラス名を返すtoString()です。要するにこれから作成する自作アダプタクラスでは、この2つのメソッドの定義のみ行えばよいということになります。
今回作成した自作アダプタクラス「Wings_Translate_Adapter_MySqlite」は以下です。
<?php
/** Zend_Locale */
require_once 'Zend/Locale.php';
/** Zend_Translate_Adapter */
require_once 'Zend/Translate/Adapter.php';
//[1]DB接続するためZend_Dbを呼び出す
/** Zend_DB_Adapter_Sqlite */
require_once 'Zend/Db.php';
/* SQLite Adapter Class for Zend Translate */
class Wings_Translate_Adapter_MySqlite extends Zend_Translate_Adapter {
/**
* Generates the adapter
*
* @param string $data Translation data
* @param string|Zend_Locale $locale OPTIONAL Locale/Language to set, identical with locale identifier,
* see Zend_Locale for more information
* @param array $options Options for this adapter
*/
public function __construct($data, $locale = null, array $options = array())
{
// 独自のオプションを設定した場合はここに次のように記載
// $this->_options['オプション名'] = デフォルト値;
parent::__construct($data, $locale, $options);
}
/**
* Load translation data
*
* @param string|array $filename Filename and full path to the translation source
* @param string $locale Locale/Language to add data for, identical with locale identifier,
* see Zend_Locale for more information
* @param array $option OPTIONAL Options to use
*/
//[2]_loadTranslationDataを定義する
protected function _loadTranslationData($filename, $locale, array $options = array())
{
//オプションclearが指定されている、もしくは
//翻訳データ格納arrayが初期化されていない場合
//翻訳データ格納arrayを初期化する
$options = $options + $this->_options;
if ($options['clear'] || !isset($this->_translate[$locale])) {
$this->_translate[$locale] = array();
}
//[3]データベースに接続する
$db = Zend_DB::factory('Pdo_Sqlite', array('dbname' => $filename));
try{
$db->getConnection();
} catch (Zend_Exception $e) {
require_once 'Zend/Translate/Exception.php';
throw new Zend_Translate_Exception($e->getMessage());
}
//[4]テーブル情報を取得する
$strquery = 'select * from tbl_trans';
$result = $db->fetchAll($strquery);
//[5]取得したtrans_keyとtrans_wordを対にして_translateのarrayに格納する
foreach ($result as $row){
$key = $row['trans_key'];
$word = $row['trans_word'];
$this->_translate[$locale][$key] = $word;
}
}
/**
* returns the adapters name
*
* @return string
*/
//[6]toStringメソッド定義
public function toString()
{
return "Wings_Translate_Adapter_MySqlite";
}
}
[1]DB接続するためZend_Dbを呼び出す
データベースSQLiteを使用するため、Zend_Dbクラスを使用することを宣言します。
[2]_loadTranslationDataを定義する
抽象メソッドである_loadTranslationDataを定義します。
_loadTranslationData(string/array $filename, string $locale, array $options = array())
各々の引数については以下のとおりです。
| 引数名 | 型 | 内容 |
| $filename | string / array | 翻訳ソースファイルのパス |
| $local | string | 翻訳すべき言語(ロケール) |
| $options | array | オプション |
[3]データベースに接続する
まずはデータベースに接続します。データベースに接続する構文については「Zend Framework入門(6):抽象化レイヤによるデータベースアクセス手法 - Zend_Db(前編) -」を参考にしてください。
$db = Zend_DB::factory('Pdo_Sqlite', array('dbname' => $filename));
try{
$db->getConnection();
} catch (Zend_Exception $e) {
require_once 'Zend/Translate/Exception.php';
throw new Zend_Translate_Exception($e->getMessage());
}
[4]テーブル情報を取得する
接続したデータベースのtbl_transの情報をすべて取得します。
$strquery = 'select * from tbl_trans'; $result = $db->fetchAll($strquery);
[5]取得したtrans_keyとtrans_wordを対にして_translateのarrayに格納する
$_translateが翻訳データを格納するarrayとなっています。
SQLiteから取得したテーブルのデータを1行ずつ処理します。$locale(ロケール)とtrans_keyフィールドの値をインデックスとして、値がtrans_wordの値となるように$_translateに格納していきます。tbl_transにおいて、trans_keyフィールドはPRIMARY KEYとなっているため、翻訳キーインデックスが重複する心配はありません。
foreach ($result as $row){
$key = $row['trans_key'];
$word = $row['trans_word'];
$this->_translate[$locale][$key] = $word;
}
[6]toStringメソッド定義
クラス名である「Wings_Translate_Adapter_MySqlite」を文字列として返します。
以上で自作アダプタの作成は完了です。
