PageRenderTime 43ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/sbweb/sbweb_logica/lib/symfony/plugins/sfPropelPlugin/lib/validator/sfValidatorPropelUnique.class.php

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