1

私はCakePHPの翻訳可能な振る舞いを使用しています。いくつかの既存のフィールドが正常に機能していますが、モデルに新しい翻訳可能なフィールドを追加するのに問題があります。

CakePHPは、INNER JOINを使用して、データベースからすべての翻訳可能なフィールドをフェッチします。

ここで、モデルに翻訳可能なフィールドを追加すると、そのフィールドのすべての翻訳レコードがデータベースに存在しなくなります。また、内部結合のため、データベースから既存のレコードをフェッチしようとすると、空白が返されます。これは、新しいフィールドのINNER JOINが失敗し、クエリ全体が何も返さないためです。

確かに、人々は以前にこの状況に遭遇したに違いありません。簡単な解決策はありますか?

1つの解決策は、コアを編集/オーバーライドして、すべてのINNERJOINをLEFTOUTERJOINにすることです。何か問題がありますか?

別の解決策は、新しい翻訳可能なフィールドを追加するたびに、translationsテーブルで更新を実行して、新しいフィールドのすべての追加レコードを作成することですが、その解決策は嫌いです。

より良い解決策はありますか?他の人はこの問題にどのように対処しましたか?

前もって感謝します。

4

1 に答える 1

0

OK、これは、新しい翻訳可能なフィールドを追加するたびにレコードが存在することを確認する方法です。より良い答えがあれば、それを追加してください。正解としてマークします。

PS-これは私の目的のためにテストされています。複数の翻訳テーブルを使用しています(http://book.cakephp.org/2.0/en/core-libraries/behaviors/translate.html#multiple-translation-tables)。ほとんどの状況で機能するはずですが、そうでない場合は、少なくとも出発点としては適切です。

モデル(Translatableとして機能するモデル)に、次のメソッドを追加します。ロケールの配列を取得し、テーブル内のすべてのレコード、すべての翻訳可能なフィールド、およびすべてのロケール(つまり、3つのループ)に対して、翻訳レコードが存在することを確認します。翻訳が存在しない場合は、空白の翻訳が追加されるため、少なくともINNERJOINは失敗しません。

追加したすべてのレコードの配列が返されるので、それらを調べて確認したり、コンテンツを変更したりできます。

モデルメソッドは次のとおりです。

function ensureTranslationIntegrity($localesToCheck){
    $allRows = $this->find('all', array('fields' => array('id')));
    $fieldsToCheck = array();

    $translatableFields = $this->actsAs['Translate'];
    foreach($translatableFields as $key => $value){
        // actsAs Translatabe can take field names only, or Key => Value pairs - see http://book.cakephp.org/2.0/en/core-libraries/behaviors/translate.html#retrieve-all-translation-records-for-a-field
        if(is_numeric($key)){
            $field = $value;
        } else {
            $field = $key;
        }
        array_push($fieldsToCheck, $field);
    }

    $translateModel = $this->translateModel();
    $addedRows = array(); // This will contain all the rows we have to add

    foreach ($allRows as $row){
        foreach($fieldsToCheck as $field){
            foreach($localesToCheck as $locale){
                $conditions = array(
                    'model' => $this->name,
                    'foreign_key' => $row[$this->name]['id'],
                    'field' => $field,
                    'locale' => $locale
                );
                $translation = $translateModel->find('first',array('conditions' => $conditions));

                if(!$translation){
                    $data = $conditions; // The data we want to insert will mostly just match the conditions of the failed find
                    $data['content'] = ''; // add it as empty

                    $translateModel->create();
                    $translateModel->save($data);

                    array_push($addedRows, $data);
                }
            } // END foreach($localesToCheck as $locale){
        } // END foreach($fieldsToCheck as $field){
    } // END foreach ($allRows as $row){

    return $addedRows;
}

そして、コントローラーでは、次のように呼びます。

public function ensure_translation_integrity(){
    $locales = array('en_au','en_gb','en_nz','pt_br','xh_za');
    $addedRows = $this->YourModel->ensureTranslationIntegrity($locales);
    debug($addedRows);
}

それが誰かを助けることを願っていますが、私が言ったように、誰かがそれを持っているなら、私はより良い解決策を見たいと思っています。

于 2012-11-06T10:38:07.973 に答える