Development

/branches/1.2/lib/plugins/sfDoctrinePlugin/lib/validator/sfValidatorDoctrineUnique.class.php

You must first sign up to be able to contribute.

root/branches/1.2/lib/plugins/sfDoctrinePlugin/lib/validator/sfValidatorDoctrineUnique.class.php

Revision 17297, 4.8 kB (checked in by Kris.Wallsmith, 6 years ago)

[1.2] fixed throw_global_error default value noted in api doc to match the actual default

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  * sfValidatorDoctrineUnique validates that the uniqueness of a column.
14  *
15  * Warning: sfValidatorDoctrineUnique is susceptible to race conditions.
16  * To avoid this issue, wrap the validation process and the model saving
17  * inside a transaction.
18  *
19  * @package    symfony
20  * @subpackage doctrine
21  * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
22  * @author     Jonathan H. Wage <jonwage@gmail.com>
23  * @version    SVN: $Id: sfValidatorDoctrineUnique.class.php 8807 2008-05-06 14:12:28Z fabien $
24  */
25 class sfValidatorDoctrineUnique extends sfValidatorSchema
26 {
27   /**
28    * Constructor.
29    *
30    * @param array  An array of options
31    * @param array  An array of error messages
32    *
33    * @see sfValidatorSchema
34    */
35   public function __construct($options = array(), $messages = array())
36   {
37     parent::__construct(null, $options, $messages);
38   }
39
40   /**
41    * Configures the current validator.
42    *
43    * Available options:
44    *
45    *  * model:              The model class (required)
46    *  * column:             The unique column name in Doctrine field name format (required)
47    *                        If the uniquess is for several columns, you can pass an array of field names
48    *  * primary_key:        The primary key column name in Doctrine field name format (optional, will be introspected if not provided)
49    *                        You can also pass an array if the table has several primary keys
50    *  * connection:         The Doctrine connection to use (null by default)
51    *  * throw_global_error: Whether to throw a global error (true by default) or an error tied to the first field related to the column option array
52    *
53    * @see sfValidatorBase
54    */
55   protected function configure($options = array(), $messages = array())
56   {
57     $this->addRequiredOption('model');
58     $this->addRequiredOption('column');
59     $this->addOption('primary_key', null);
60     $this->addOption('connection', null);
61     $this->addOption('throw_global_error', true);
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     $originalValues = $values;
72     $table = Doctrine::getTable($this->getOption('model'));
73     if (!is_array($this->getOption('column')))
74     {
75       $this->setOption('column', array($this->getOption('column')));
76     }
77
78     //if $values isn't an array, make it one
79     if (!is_array($values))
80     {
81       //use first column for key
82       $columns = $this->getOption('column');
83       $values = array($columns[0] => $values);
84     }
85
86     $q = Doctrine_Query::create()
87           ->from($this->getOption('model') . ' a');
88
89     foreach ($this->getOption('column') as $column)
90     {
91       $colName = $table->getColumnName($column);
92       if (!array_key_exists($column, $values))
93       {
94         // one of the column has be removed from the form
95         return $originalValues;
96       }
97
98       $q->addWhere('a.' . $colName . ' = ?', $values[$column]);
99     }
100
101     $object = $q->fetchOne();
102
103     // if no object or if we're updating the object, it's ok
104     if (!$object || $this->isUpdate($object, $values))
105     {
106       return $originalValues;
107     }
108
109     $error = new sfValidatorError($this, 'invalid', array('column' => implode(', ', $this->getOption('column'))));
110
111     if ($this->getOption('throw_global_error'))
112     {
113       throw $error;
114     }
115
116     $columns = $this->getOption('column');
117
118     throw new sfValidatorErrorSchema($this, array($columns[0] => $error));
119   }
120
121   /**
122    * Returns whether the object is being updated.
123    *
124    * @param BaseObject  A Doctrine object
125    * @param array       An array of values
126    *
127    * @param Boolean     true if the object is being updated, false otherwise
128    */
129   protected function isUpdate(Doctrine_Record $object, $values)
130   {
131     // check each primary key column
132     foreach ($this->getPrimaryKeys() as $column)
133     {
134       if (!isset($values[$column]) || $object->$column != $values[$column])
135       {
136         return false;
137       }
138     }
139
140     return true;
141   }
142
143   /**
144    * Returns the primary keys for the model.
145    *
146    * @return array An array of primary keys
147    */
148   protected function getPrimaryKeys()
149   {
150     if (is_null($this->getOption('primary_key')))
151     {
152       $primaryKeys = Doctrine::getTable($this->getOption('model'))->getIdentifier();
153       $this->setOption('primary_key', $primaryKeys);
154     }
155
156     if (!is_array($this->getOption('primary_key')))
157     {
158       $this->setOption('primary_key', array($this->getOption('primary_key')));
159     }
160
161     return $this->getOption('primary_key');
162   }
163 }
Note: See TracBrowser for help on using the browser.