Development

/branches/1.2/lib/plugins/sfPropelPlugin/lib/form/sfFormFilterPropel.class.php

You must first sign up to be able to contribute.

root/branches/1.2/lib/plugins/sfPropelPlugin/lib/form/sfFormFilterPropel.class.php

Revision 14499, 6.9 kB (checked in by Jonathan.Wage, 5 years ago)

[1.2] Fixes form filters to perform a stricter check (closes #5548)

  • Property svn:mime-type set to text/x-php
  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1 <?php
2
3 /*
4  * This file is part of the symfony package.
5  * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
6  *
7  * For the full copyright and license information, please view the LICENSE
8  * file that was distributed with this source code.
9  */
10
11 /**
12  * sfFormFilterPropel is the base class for filter forms based on Propel objects.
13  *
14  * @package    symfony
15  * @subpackage form
16  * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
17  * @version    SVN: $Id$
18  */
19 abstract class sfFormFilterPropel extends sfFormFilter
20 {
21   /**
22    * Returns the current model name.
23    *
24    * @return string The model class name
25    */
26   abstract public function getModelName();
27
28   /**
29    * Returns the fields and their filter type.
30    *
31    * @return array An array of fields with their filter type
32    */
33   abstract public function getFields();
34
35   /**
36    * Returns a Propel Criteria based on the current values form the form.
37    *
38    * @return Criteria A Propel Criteria object
39    */
40   public function getCriteria()
41   {
42     if (!$this->isValid())
43     {
44       throw $this->getErrorSchema();
45     }
46
47     return $this->buildCriteria($this->getValues());
48   }
49
50   /**
51    * Processes cleaned up values with user defined methods.
52    *
53    * To process a value before it is used by the buildCriteria() method,
54    * you need to define an convertXXXValue() method where XXX is the PHP name
55    * of the column.
56    *
57    * The method must return the processed value or false to remove the value
58    * from the array of cleaned up values.
59    *
60    * @param  array An array of cleaned up values to process
61    *
62    * @return array An array of cleaned up values processed by the user defined methods
63    */
64   public function processValues($values)
65   {
66     // see if the user has overridden some column setter
67     $originalValues = $values;
68     foreach ($originalValues as $field => $value)
69     {
70       try
71       {
72         $method = sprintf('convert%sValue', call_user_func(array(constant($this->getModelName().'::PEER'), 'translateFieldName'), $field, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_PHPNAME));
73       }
74       catch (Exception $e)
75       {
76         // no a "real" column of this object
77         continue;
78       }
79
80       if (method_exists($this, $method))
81       {
82         if (false === $ret = $this->$method($value))
83         {
84           unset($values[$field]);
85         }
86         else
87         {
88           $values[$field] = $ret;
89         }
90       }
91     }
92
93     return $values;
94   }
95
96   /**
97    * Builds a Propel Criteria based on the passed values.
98    *
99    * @param  array    An array of parameters to build the Criteria object
100    *
101    * @return Criteria A Propel Criteria object
102    */
103   public function buildCriteria(array $values)
104   {
105     $values = $this->processValues($values);
106
107     $criteria = new Criteria();
108
109     $peer = constant($this->getModelName().'::PEER');
110     foreach ($this->getFields() as $field => $type)
111     {
112       if (!isset($values[$field]) || is_null($values[$field]) || '' === $values[$field])
113       {
114         continue;
115       }
116
117       try
118       {
119         $method = sprintf('add%sColumnCriteria', call_user_func(array($peer, 'translateFieldName'), $field, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_PHPNAME));
120       }
121       catch (Exception $e)
122       {
123         // not a "real" column
124         if (!method_exists($this, $method = sprintf('add%sColumnCriteria', self::camelize($field))))
125         {
126           throw new LogicException(sprintf('You must define a "%s" method to be able to filter with the "%s" field.', $method, $field));
127         }
128       }
129
130       if (method_exists($this, $method))
131       {
132         $this->$method($criteria, $field, $values[$field]);
133       }
134       else
135       {
136         if (!method_exists($this, $method = sprintf('add%sCriteria', $type)))
137         {
138           throw new LogicException(sprintf('Unable to filter for the "%s" type.', $type));
139         }
140
141         $this->$method($criteria, $field, $values[$field]);
142       }
143     }
144
145     return $criteria;
146   }
147
148   protected function addForeignKeyCriteria(Criteria $criteria, $field, $value)
149   {
150     $colname = $this->getColname($field);
151
152     if (is_array($value))
153     {
154       $values = $value;
155       $value = array_pop($values);
156       $criterion = $criteria->getNewCriterion($colname, $value);
157
158       foreach ($values as $value)
159       {
160         $criterion->addOr($criteria->getNewCriterion($colname, $value));
161       }
162
163       $criteria->add($criterion);
164     }
165     else
166     {
167       $criteria->add($colname, $value);
168     }
169   }
170
171   protected function addTextCriteria(Criteria $criteria, $field, $values)
172   {
173     $colname = $this->getColname($field);
174
175     if (is_array($values) && isset($values['is_empty']) && $values['is_empty'])
176     {
177       $criterion = $criteria->getNewCriterion($colname, '');
178       $criterion->addOr($criteria->getNewCriterion($colname, null, Criteria::ISNULL));
179       $criteria->add($criterion);
180     }
181     else if (is_array($values) && isset($values['text']) && '' != $values['text'])
182     {
183       $criteria->add($colname, '%'.$values['text'].'%', Criteria::LIKE);
184     }
185   }
186
187   protected function addNumberCriteria(Criteria $criteria, $field, $values)
188   {
189     $colname = $this->getColname($field);
190
191     if (is_array($values) && isset($values['is_empty']) && $values['is_empty'])
192     {
193       $criterion = $criteria->getNewCriterion($colname, '');
194       $criterion->addOr($criteria->getNewCriterion($colname, null, Criteria::ISNULL));
195       $criteria->add($criterion);
196     }
197     else if (is_array($values) && isset($values['text']) && '' != $values['text'])
198     {
199       $criteria->add($colname, $values['text']);
200     }
201   }
202
203   protected function addBooleanCriteria(Criteria $criteria, $field, $value)
204   {
205     $criteria->add($this->getColname($field), $value);
206   }
207
208   protected function addDateCriteria(Criteria $criteria, $field, $values)
209   {
210     $colname = $this->getColname($field);
211
212     if (isset($values['is_empty']) && $values['is_empty'])
213     {
214       $criteria->add($colname, null, Criteria::ISNULL);
215     }
216     else
217     {
218       $criterion = null;
219       if (!is_null($values['from']) && !is_null($values['to']))
220       {
221         $criterion = $criteria->getNewCriterion($colname, $values['from'], Criteria::GREATER_EQUAL);
222         $criterion->addAnd($criteria->getNewCriterion($colname, $values['to'], Criteria::LESS_EQUAL));
223       }
224       else if (!is_null($values['from']))
225       {
226         $criterion = $criteria->getNewCriterion($colname, $values['from'], Criteria::GREATER_EQUAL);
227       }
228       else if (!is_null($values['to']))
229       {
230         $criterion = $criteria->getNewCriterion($colname, $values['to'], Criteria::LESS_EQUAL);
231       }
232
233       if (!is_null($criterion))
234       {
235         $criteria->add($criterion);
236       }
237     }
238   }
239
240   protected function getColName($field)
241   {
242     return call_user_func(array(constant($this->getModelName().'::PEER'), 'translateFieldName'), $field, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_COLNAME);
243   }
244
245   protected function camelize($text)
246   {
247     return sfToolkit::pregtr($text, array('#/(.?)#e' => "'::'.strtoupper('\\1')", '/(^|_|-)+(.)/e' => "strtoupper('\\2')"));
248   }
249 }
250
Note: See TracBrowser for help on using the browser.