CakePHP翻译行为和分页计数

时间:2011-12-07 11:51:18

标签: cakephp internationalization pagination

我有一个模型,其中Translate行为附加了两个字段:title和description。 我在可翻译领域添加了一些条件。 像往常一样,CakePHP首先进行计数,然后获取所有记录。 获取查询的总记录时:

SELECT COUNT(DISTINCT( `product`.`id` )) AS COUNT
FROM   `products` AS `product`
   INNER JOIN `i18n` AS `i18nmodel`
     ON ( `product`.`id` = `i18nmodel`.`foreign_key`
          AND `i18nmodel`.`model` = 'Product'
          AND `i18nmodel`.`locale` = 'eng' )
   LEFT JOIN `categories` AS `category`
     ON ( `product`.`category_id` = `category`.`id` )
   LEFT JOIN `vats` AS `vat`
     ON ( `product`.`vat_id` = `vat`.`id` )
   LEFT JOIN `availables` AS `available`
     ON ( `product`.`available_id` = `available`.`id` )
WHERE  ( ( `i18n__description`.`content` LIKE '%test%' )
      OR ( `i18n__title`.`content` LIKE '%test%' )
      OR ( `product`.`code` LIKE '%test%' ) )  

我明白了:

1054: Unknown column 'I18n__description.content' in 'where clause'

因为i18n表没有作为i18n_ title或i18n _description加入,而是作为i18nmodel加入

但是,当分页尝试检索查询的行(而不是总记录)时,一切正常。这有什么解决方案吗?

控制器代码如下所示:

$condition = array();
foreach ($search as $word) {
if (strlen($word) > 0)
 $condition[] = array('OR' => array('I18n__description.content LIKE' => '%' . $word . '%','I18n__title.content LIKE' => '%' . $word . '%',
                        'Product.code LIKE' => '%' . $word . '%'));
}

$conditions = array('AND' => $condition);
$products = $this->paginate($conditions);

2 个答案:

答案 0 :(得分:2)

可以通过在要分页的模型中创建自定义paginateCount方法来简单地处理此案例。

function paginateCount($conditions = array(), $recursive = null, $extra = array()) {
    return count($this->find('all', array('conditions' => $conditions)))
}

答案 1 :(得分:1)

paginator计数器不使用翻译连接,因此您必须在查找之前手动连接。 FindAll不是那么好的解决方案,因为它运行复杂的查询,并占用服务器资源。

https://github.com/cakephp/cakephp/issues/1753

解决方案。它不适用于SmoothTranslate行为,但对上面的代码稍加修改,它可能是有效的。 覆盖之前的查找。

 function beforeFind($queryData){
     if(!empty($this->actsAs['SmoothTranslate']['fields'])){
        foreach($this->actsAs['SmoothTranslate']['fields'] as $trkey=>$trval){
          if(!is_string($trkey))  $trkey=$trval;

          $joinFound=false;
          foreach($queryData['joins'] as $join){
            if($join['alias']=='I18n__'.$trkey){
              $joinFound=true;  break;
            }
          }
          if(!$joinFound){
            $newJoin = array(
              'type'=>'LEFT',
              'table'=>'i18n',
              'alias'=>'I18n__'.$trkey,
              'conditions'=>array(
                $this->alias.'.id'=>Set::map(array(
                  'type'=>'identifier',
                  'value'=>'I18n__'.$trkey.'.foreign_key',
                )),
                'I18n__'.$trkey.'.model'=>$this->alias,
                'I18n__'.$trkey.'.locale'=>$this->locale,
                'I18n__'.$trkey.'.field'=>$trkey,
              ),
            );
            array_push($queryData['joins'], $newJoin);
          }
        }

    }
    return $queryData;
  }
}