Development

/branches/1.2/lib/plugins/sfPropelPlugin/lib/validator/sfValidatorPropelUnique.class.php

You must first sign up to be able to contribute.

root/branches/1.2/lib/plugins/sfPropelPlugin/lib/validator/sfValidatorPropelUnique.class.php

Revision 13249, 5.6 kB (checked in by fabien, 5 years ago)

[1.2] fixed a warning in sfValidatorPropelUnique

  • 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  * sfValidatorPropelUnique validates that the uniqueness of a column.
13  *
14  * Warning: sfValidatorPropelUnique is susceptible to race conditions.
15  * To avoid this issue, wrap the validation process and the model saving
16  * inside a transaction.
17  *
18  * @package    symfony
19  * @subpackage validator
20  * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
21  * @version    SVN: $Id$
22  */
23 class sfValidatorPropelUnique extends sfValidatorSchema
24 {
25   /**
26    * Constructor.
27    *
28    * @param array  $options   An array of options
29    * @param array  $messages  An array of error messages
30    *
31    * @see sfValidatorSchema
32    */
33   public function __construct($options = array(), $messages = array())
34   {
35     parent::__construct(null, $options, $messages);
36   }
37
38   /**
39    * Configures the current validator.
40    *
41    * Available options:
42    *
43    *  * model:              The model class (required)
44    *  * column:             The unique column name in Propel field name format (required)
45    *                        If the uniquess is for several columns, you can pass an array of field names
46    *  * field               Field name used by the form, other than the column name
47    *  * primary_key:        The primary key column name in Propel field name format (optional, will be introspected if not provided)
48    *                        You can also pass an array if the table has several primary keys
49    *  * connection:         The Propel connection to use (null by default)
50    *  * throw_global_error: Whether to throw a global error (false by default) or an error tied to the first field related to the column option array
51    *
52    * @see sfValidatorBase
53    */
54   protected function configure($options = array(), $messages = array())
55   {
56     $this->addRequiredOption('model');
57     $this->addRequiredOption('column');
58     $this->addOption('field', null);
59     $this->addOption('primary_key', null);
60     $this->addOption('connection', null);
61     $this->addOption('throw_global_error', false);
62
63     $this->setMessage('invalid', 'An object with the same "%column%" already exist.');
64   }
65
66   /**
67    * @see sfValidatorBase
68    */
69   protected function doClean($values)
70   {
71     if (!is_array($values))
72     {
73       throw new InvalidArgumentException('You must pass an array parameter to the clean() method (this validator can only be used as a post validator).');
74     }
75
76     if (!is_array($this->getOption('column')))
77     {
78       $this->setOption('column', array($this->getOption('column')));
79     }
80
81     if (!is_array($field = $this->getOption('field')))
82     {
83       $this->setOption('field', $field ? array($field) : array());
84     }
85     $fields = $this->getOption('field');
86
87     $criteria = new Criteria();
88     foreach ($this->getOption('column') as $i => $column)
89     {
90       $name = isset($fields[$i]) ? $fields[$i] : $column;
91       if (!array_key_exists($name, $values))
92       {
93         // one of the column has be removed from the form
94         return $values;
95       }
96
97       $colName = call_user_func(array(constant($this->getOption('model').'::PEER'), 'translateFieldName'), $column, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_COLNAME);
98
99       $criteria->add($colName, $values[$name]);
100     }
101
102     $object = call_user_func(array(constant($this->getOption('model').'::PEER'), 'doSelectOne'), $criteria, $this->getOption('connection'));
103
104     // if no object or if we're updating the object, it's ok
105     if (is_null($object) || $this->isUpdate($object, $values))
106     {
107       return $values;
108     }
109
110     $error = new sfValidatorError($this, 'invalid', array('column' => implode(', ', $this->getOption('column'))));
111
112     if ($this->getOption('throw_global_error'))
113     {
114       throw $error;
115     }
116
117     $columns = $this->getOption('column');
118
119     throw new sfValidatorErrorSchema($this, array($columns[0] => $error));
120   }
121
122   /**
123    * Returns whether the object is being updated.
124    *
125    * @param BaseObject  $object   A Propel object
126    * @param array       $values   An array of values
127    *
128    * @return Boolean     true if the object is being updated, false otherwise
129    */
130   protected function isUpdate(BaseObject $object, $values)
131   {
132     // check each primary key column
133     foreach ($this->getPrimaryKeys() as $column)
134     {
135       $columnPhpName = call_user_func(array(constant($this->getOption('model').'::PEER'), 'translateFieldName'), $column, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_PHPNAME);
136       $method = 'get'.$columnPhpName;
137       if (!isset($values[$column]) or $object->$method() != $values[$column])
138       {
139         return false;
140       }
141     }
142
143     return true;
144   }
145
146   /**
147    * Returns the primary keys for the model.
148    *
149    * @return array An array of primary keys
150    */
151   protected function getPrimaryKeys()
152   {
153     if (is_null($this->getOption('primary_key')))
154     {
155       $primaryKeys = array();
156       $tableMap = call_user_func(array(constant($this->getOption('model').'::PEER'), 'getTableMap'));
157       foreach ($tableMap->getColumns() as $column)
158       {
159         if (!$column->isPrimaryKey())
160         {
161           continue;
162         }
163
164         $primaryKeys[] = call_user_func(array(constant($this->getOption('model').'::PEER'), 'translateFieldName'), $column->getPhpName(), BasePeer::TYPE_PHPNAME, BasePeer::TYPE_FIELDNAME);
165       }
166
167       $this->setOption('primary_key', $primaryKeys);
168     }
169
170     if (!is_array($this->getOption('primary_key')))
171     {
172       $this->setOption('primary_key', array($this->getOption('primary_key')));
173     }
174
175     return $this->getOption('primary_key');
176   }
177 }
178
Note: See TracBrowser for help on using the browser.