Symfonyでembed18nを使う

Symfonyで多言語対応する予定があるけど、とりあえず日本語だけ使いたかったときのメモです。embedI18nを自在に使う参考に。例によってSymfony 1.4+Doctrine。

// HogeForm.class.php
public HogeForm extends BaseHogeForm
{

    public function configure()
    {
        parent::configure();
        
        $this->embedI18n(array('ja'));
        
        // 二次元配列でembedしたフォームにアクセスできる
        $this->validatorSchema['ja']['name']->setOption('required', true);
        
        $this->useFields(array('ja', 'foo', 'bar'));
    }

}

このままテンプレートで$form->render()とかしてしまうと、入れ子表示になってしまうのでrenderRowでそれぞれ表示するようにしてやれば、useFieldsでembedされたフォームの順番がいじれないという問題も解決。

// hogeCreateSuccess.php
$form['ja']['name']->renderRow();
$form['foo']->renderRow();
$form['bar']->renderRow();

ちなみにsfFormDoctrine::getI18nFormClass()とかあるのですが、クラス名が取れるだけです。

追記

SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry ’19-ja’ for key ‘PRIMARY’

フォームをsaveしたら上記のエラーが出ました。

updateObject後にobject->toArray()をすると見覚えのない、「ja_JP」というキーが。

Array
(
    [id] => 
    [foo] => hoge
    [bar] => moge
    [Translation] => Array
        (
            [ja] => Array
                (
                    [id] => 
                    [name] => someone
                    [lang] => ja
                )
            [ja_JP] => Array
                (
                    [id] => 
                    [name] => 
                    [lang] => ja_JP
                )
        )
)

色々調べた結果、原因は

  • langがchar(2)なので、jaとja_JPの区別がつかないこと
  • sfDoctrineRecord::getDefaultCulture()がja_JPなこと

恐らく、

http://www.symfony-project.org/jobeet/1_4/Doctrine/ja/19

このページを参考にしているとハマるのではないかと…

ちなみにlangがchar(2)なのは、Doctrine_I18nの中で定義されています。

対策として考えられるのは以下のパターン。

  • sfDoctrineRecord::setDefaultCulture(‘ja’)をコールする
  • langをchar(5)にしてja_JPの形式で扱う
  • settings.ymlのdefault_cultureをjaにする
  • embedI18nにja_JPを渡す

sfDoctrineRecordのカルチャをセットするのは、sfUserのカルチャをセットすることでイベントが駆動して同時にセットできます。なので、$this->getUser()->setCulture(‘ja’)とかしておけばOK。

langをchar(5)にするのは、I18nビヘイビアのオプションにlength:5を指定すればできます。この場合、カルチャをすべて5文字で扱うようにしないとlangがマッチしなくなります。length:2の場合は暗黙的に先頭2文字だけにマッチさせることで5文字のカルチャを許容していたので。

# schema.yml
Sample:
  actAs:
    Timestampable: ~
    I18n:
      fields: [name]
      length: 5

settings.ymlのdefault_cultureをjaにするのが一番簡単です。en_USとen_GBはどうするんだという話ですけど…

formクラスに$this->embedI18n(array(‘ja_JP’))とすることでも対応できます。

気になる方はsfDoctrineRecordI18nFilterクラスのfilterSet関数を見てください。

カタログファイルとかにも影響しそうなのでsettings.ymlに2文字カルチャをセットするのがベターかなぁ。


タグ: , ,

新しく会社作りました!

コメントをどうぞ