symfony自動生成的Filter有一些侷限性,比如不能過濾關聯表的特定字段,過濾的表單只有input和select兩種,
下面介紹處理上面兩個問題的解決方案。
1. 關聯表字段查詢
假設我們有Order和User兩張表,Order中有user_id和User關聯,Syfmony默認可以通過user_id來過濾,現在想通過User的name字段模糊查詢獲得用戶的所有訂單。
在[b]sfFormFilterDoctrine[/b]中有方法doBuildQuery,
if ($this->getTable()->hasField($field))
{
$method = sprintf('add%sColumnQuery', self::camelize($this->getFieldName($field)));
}
else if (!method_exists($this, $method = sprintf('add%sColumnQuery', self::camelize($field))) && null !== $type)
{
throw new LogicException(sprintf('You must define a "%s" method to be able to filter with the "%s" field.', $method, $field));
}
從上面的代碼可以看出只要增加一個add%FiledName%ColumnQuery方法即可以自定義每個字段的查詢,所以只要添加如下代碼
[code]
public function addUsernameColumnQuery(Doctrine_Query $query, $field, $value)
{
$query->leftJoin('r.User u');
if(!empty($value)){
$query->andWhere('u.name like ?', "%$value%");
}
}
[/code]
2. 自定義Filter表單字段類型
假設我們有一張商品表Product, 其中有一個字段status,我們需要使用checkbox選擇多個狀態來過濾商品
首先在ProductFormFilter的configure函數中添加
$this->widgetSchema['status'] = new sfWidgetFormChoice(array(
'choices' => self::$STATUS_TEXT,
'multiple' => true,
'expanded' => true,
));
$this->validatorSchema['status'] = new sfValidatorChoice(array(
'required' => false,
'multiple' => true,
'choices' => array_keys(self::$STATUS_TEXT),
));
這和定義Form的widget一樣,但是如果這樣的還不行, 因爲涉及到多選,但默認status是input的類型,所以我們需要讓symfony知道我們現在傳過來的參數可能是數組,在filter中重載getFields方法,把status字段設爲ForeignKey類型
public function getFields()
{
$fields = parent::getFields();
$fields["status"] = "ForeignKey";
return $fields;
}