Development

/branches/1.2/lib/plugins/sfDoctrinePlugin/lib/form/sfFormFilterDoctrine.class.php

You must first sign up to be able to contribute.

root/branches/1.2/lib/plugins/sfDoctrinePlugin/lib/form/sfFormFilterDoctrine.class.php

Revision 21145, 7.6 kB (checked in by Kris.Wallsmith, 5 years ago)

[1.2, 1.3] fixed doctine form filter when the table method returns a query with a different root alias

Line 
1 <?php
2
3 /*
4  * This file is part of the symfony package.
5  * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
6  * (c) Jonathan H. Wage <jonwage@gmail.com>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11
12 /**
13  * sfFormFilterDoctrine is the base class for filter forms based on Doctrine objects.
14  *
15  * @package    symfony
16  * @subpackage form
17  * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
18  * @author     Jonathan H. Wage <jonwage@gmail.com>
19  * @version    SVN: $Id: sfFormFilterDoctrine.class.php 11690 2008-09-20 19:50:03Z fabien $
20  */
21 abstract class sfFormFilterDoctrine extends sfFormFilter
22 {
23   protected
24     $tableMethodName       = null;
25
26   /**
27    * Returns the current model name.
28    *
29    * @return string The model class name
30    */
31   abstract public function getModelName();
32
33   /**
34    * Returns the fields and their filter type.
35    *
36    * @return array An array of fields with their filter type
37    */
38   abstract public function getFields();
39
40   /**
41    * Get the name of the table method used to retrieve the query object for the filter
42    *
43    * @return string $tableMethodName
44    */
45   public function getTableMethod()
46   {
47     return $this->tableMethodName;
48   }
49
50   /**
51    * Set the name of the table method used to retrieve the query object for the filter
52    *
53    * @param string $tableMethodName
54    * @return void
55    */
56   public function setTableMethod($tableMethodName)
57   {
58     $this->tableMethodName = $tableMethodName;
59   }
60
61   /**
62    * Returns a Doctrine Query based on the current values form the form.
63    *
64    * @return Query A Doctrine Query object
65    */
66   public function getQuery()
67   {
68     if (!$this->isValid())
69     {
70       throw $this->getErrorSchema();
71     }
72
73     return $this->buildQuery($this->getValues());
74   }
75
76   /**
77    * Processes cleaned up values with user defined methods.
78    *
79    * To process a value before it is used by the buildQuery() method,
80    * you need to define an convertXXXValue() method where XXX is the PHP name
81    * of the column.
82    *
83    * The method must return the processed value or false to remove the value
84    * from the array of cleaned up values.
85    *
86    * @param  array An array of cleaned up values to process
87    *
88    * @return array An array of cleaned up values processed by the user defined methods
89    */
90   public function processValues($values)
91   {
92     // see if the user has overridden some column setter
93     $originalValues = $values;
94     foreach ($originalValues as $field => $value)
95     {
96       try
97       {
98         $method = sprintf('convert%sValue', self::camelize($field));
99       }
100       catch (Exception $e)
101       {
102         // no a "real" column of this object
103         continue;
104       }
105
106       if (method_exists($this, $method))
107       {
108         if (false === $ret = $this->$method($value))
109         {
110           unset($values[$field]);
111         }
112         else
113         {
114           $values[$field] = $ret;
115         }
116       }
117     }
118
119     return $values;
120   }
121
122   /**
123    * Builds a Doctrine Query based on the passed values.
124    *
125    * @param  array    An array of parameters to build the Query object
126    *
127    * @return Query A Doctrine Query object
128    */
129   public function buildQuery(array $values)
130   {
131     $values = $this->processValues($values);
132
133     $query = $this->getTable()->createQuery('r');
134
135     if ($this->tableMethodName)
136     {
137       $method = $this->tableMethodName;
138       $query = $this->getTable()->$method($query);
139     }
140
141     foreach ($this->getFields() as $field => $type)
142     {
143       if (!isset($values[$field]) || is_null($values[$field]) || '' === $values[$field])
144       {
145         continue;
146       }
147
148       if ($this->getTable()->hasField($field))
149       {
150         $method = sprintf('add%sColumnQuery', self::camelize($this->getFieldName($field)));
151       } else {
152         // not a "real" column
153         if (!method_exists($this, $method = sprintf('add%sColumnQuery', self::camelize($field))))
154         {
155           throw new LogicException(sprintf('You must define a "%s" method to be able to filter with the "%s" field.', $method, $field));
156         } 
157       }
158
159       if (method_exists($this, $method))
160       {
161         $this->$method($query, $field, $values[$field]);
162       }
163       else
164       {
165         if (!method_exists($this, $method = sprintf('add%sQuery', $type)))
166         {
167           throw new LogicException(sprintf('Unable to filter for the "%s" type.', $type));
168         }
169
170         $this->$method($query, $field, $values[$field]);
171       }
172     }
173
174     return $query;
175   }
176
177   protected function addForeignKeyQuery(Doctrine_Query $query, $field, $value)
178   {
179     $fieldName = $this->getFieldName($field);
180
181     if (is_array($value))
182     {
183       $query->orWhereIn(sprintf('%s.%s', $query->getRootAlias(), $fieldName), $value);
184     }
185     else
186     {
187       $query->addWhere(sprintf('%s.%s = ?', $query->getRootAlias(), $fieldName), $value);
188     }
189   }
190
191   protected function addEnumQuery(Doctrine_Query $query, $field, $value)
192   {
193     $fieldName = $this->getFieldName($field);
194
195     $query->addWhere(sprintf('%s.%s = ?', $query->getRootAlias(), $fieldName), $value);
196   }
197
198   protected function addTextQuery(Doctrine_Query $query, $field, $values)
199   {
200     $fieldName = $this->getFieldName($field);
201
202     if (is_array($values) && isset($values['is_empty']) && $values['is_empty'])
203     {
204       $query->addWhere(sprintf('%s.%s IS NULL', $query->getRootAlias(), $fieldName));
205     }
206     else if (is_array($values) && isset($values['text']) && '' != $values['text'])
207     {
208       $query->addWhere(sprintf('%s.%s LIKE ?', $query->getRootAlias(), $fieldName), '%'.$values['text'].'%');
209     }
210   }
211
212   protected function addNumberQuery(Doctrine_Query $query, $field, $values)
213   {
214     $fieldName = $this->getFieldName($field);
215
216     if (is_array($values) && isset($values['is_empty']) && $values['is_empty'])
217     {
218       $query->addWhere(sprintf('%s.%s IS NULL', $query->getRootAlias(), $fieldName));
219     }
220     else if (is_array($values) && isset($values['text']) && '' != $values['text'])
221     {
222       $query->addWhere(sprintf('%s.%s = ?', $query->getRootAlias(), $fieldName), $values['text']);
223     }
224   }
225
226   protected function addBooleanQuery(Doctrine_Query $query, $field, $value)
227   {
228     $fieldName = $this->getFieldName($field);
229     $query->addWhere(sprintf('%s.%s = ?', $query->getRootAlias(), $fieldName), $value);
230   }
231
232   protected function addDateQuery(Doctrine_Query $query, $field, $values)
233   {
234     $fieldName = $this->getFieldName($field);
235
236     if (isset($values['is_empty']) && $values['is_empty'])
237     {
238       $query->addWhere(sprintf('%s.%s IS NULL', $query->getRootAlias(), $fieldName));
239     }
240     else
241     {
242       if (!is_null($values['from']) && !is_null($values['to']))
243       {
244         $query->andWhere(sprintf('%s.%s >= ?', $query->getRootAlias(), $fieldName), $values['from']);
245         $query->andWhere(sprintf('%s.%s <= ?', $query->getRootAlias(), $fieldName), $values['to']);
246       }
247       else if (!is_null($values['from']))
248       {
249         $query->andWhere(sprintf('%s.%s >= ?', $query->getRootAlias(), $fieldName), $values['from']);
250       }
251       else if (!is_null($values['to']))
252       {
253         $query->andWhere(sprintf('%s.%s <= ?', $query->getRootAlias(), $fieldName), $values['to']);
254       }
255     }
256   }
257
258   protected function getColName($field)
259   {
260     return $this->getTable()->getColumnName($field);
261   }
262
263   protected function getFieldName($colName)
264   {
265     return $this->getTable()->getFieldName($colName);
266   }
267
268   protected function camelize($text)
269   {
270     return sfToolkit::pregtr($text, array('#/(.?)#e' => "'::'.strtoupper('\\1')", '/(^|_|-)+(.)/e' => "strtoupper('\\2')"));
271   }
272
273   protected function getTable()
274   {
275     return Doctrine::getTable($this->getModelName());
276   }
277 }
Note: See TracBrowser for help on using the browser.