我正在使用cakephp的可翻译行为。我有一些现有的字段正常工作,但是在我的模型中添加一个新的可翻译字段很难。
cakephp使用内部联接来获取数据库中的所有可翻译字段。
现在,如果我在模型中添加了一个额外的可翻译字段,则该字段的所有翻译记录都不存在。而且由于内部联接,每当尝试从数据库中获取任何现有记录时,它将返回空白 - 因为新字段上的内部加入失败,因此整个查询都没有返回。
肯定人们必须遇到这种情况。有简单的解决方案吗?
一种解决方案是编辑/覆盖核心,并将所有内在的联接到左外连接中。有什么问题吗?
另一个解决方案是在翻译表上运行更新,以创建新字段的所有额外记录,每次添加新的可翻译字段时 - 但是我讨厌该解决方案。
有更好的解决方案吗?其他人如何处理这个问题?
预先感谢。
好的,这是确保每次添加新的可翻译字段之后记录存在的一种方法。如果您有更好的答案,请添加它,我将您的正确答案标记为正确。
ps-为我的目的进行了测试。我使用多个翻译表(http://book.cakephp.org/2.0/en/core-libraries/behaviors/translate.html#multiple-translation-translation-tables)。我认为它应该在大多数情况下都有效,但是如果没有,至少应该是一个很好的起点。
在您的模型(可翻译的模型)中,添加以下方法。它的作用是占用一系列位置,然后使用表中的每个记录,对于每个可翻译的字段,对于每个语言环境(即3个循环),它检查是否存在翻译记录。如果不存在翻译,它会添加一个空白,因此至少内部连接不会失败。
它返回添加的所有记录的数组,因此您可以通过检查或更改其内容或其他内容。
这是模型方法:
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);
}
希望对某人有帮助,但就像我说的那样,如果某人有一个,我很想看到一个更好的解决方案。