My favorites | Sign in
yii
Project Home Downloads Issues Source
Checkout   Browse   Changes    
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
<?php
/**
* CUniqueValidator class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright Copyright &copy; 2008-2011 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/

/**
* CUniqueValidator validates that the attribute value is unique in the corresponding database table.
*
* When using the {@link message} property to define a custom error message, the message
* may contain additional placeholders that will be replaced with the actual content. In addition
* to the "{attribute}" placeholder, recognized by all validators (see {@link CValidator}),
* CUniqueValidator allows for the following placeholders to be specified:
* <ul>
* <li>{value}: replaced with current value of the attribute.</li>
* </ul>
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id$
* @package system.validators
* @since 1.0
*/
class CUniqueValidator extends CValidator
{
/**
* @var boolean whether the comparison is case sensitive. Defaults to true.
* Note, by setting it to false, you are assuming the attribute type is string.
*/
public $caseSensitive=true;
/**
* @var boolean whether the attribute value can be null or empty. Defaults to true,
* meaning that if the attribute is empty, it is considered valid.
*/
public $allowEmpty=true;
/**
* @var string the ActiveRecord class name that should be used to
* look for the attribute value being validated. Defaults to null, meaning using
* the class of the object currently being validated.
* You may use path alias to reference a class name here.
* @see attributeName
*/
public $className;
/**
* @var string the ActiveRecord class attribute name that should be
* used to look for the attribute value being validated. Defaults to null,
* meaning using the name of the attribute being validated.
* @see className
*/
public $attributeName;
/**
* @var array additional query criteria. This will be combined with the condition
* that checks if the attribute value exists in the corresponding table column.
* This array will be used to instantiate a {@link CDbCriteria} object.
*/
public $criteria=array();
/**
* @var string the user-defined error message. The placeholders "{attribute}" and "{value}"
* are recognized, which will be replaced with the actual attribute name and value, respectively.
*/
public $message;
/**
* @var boolean whether this validation rule should be skipped if when there is already a validation
* error for the current attribute. Defaults to true.
* @since 1.1.1
*/
public $skipOnError=true;


/**
* Validates the attribute of the object.
* If there is any error, the error message is added to the object.
* @param CModel $object the object being validated
* @param string $attribute the attribute being validated
*/
protected function validateAttribute($object,$attribute)
{
$value=$object->$attribute;
if($this->allowEmpty && $this->isEmpty($value))
return;

$className=$this->className===null?get_class($object):Yii::import($this->className);
$attributeName=$this->attributeName===null?$attribute:$this->attributeName;
$finder=CActiveRecord::model($className);
$table=$finder->getTableSchema();
if(($column=$table->getColumn($attributeName))===null)
throw new CException(Yii::t('yii','Table "{table}" does not have a column named "{column}".',
array('{column}'=>$attributeName,'{table}'=>$table->name)));

$columnName=$column->rawName;
$criteria=new CDbCriteria(array(
'condition'=>$this->caseSensitive ? "$columnName=:value" : "LOWER($columnName)=LOWER(:value)",
'params'=>array(':value'=>$value),
));
if($this->criteria!==array())
$criteria->mergeWith($this->criteria);

if(!$object instanceof CActiveRecord || $object->isNewRecord || $object->tableName()!==$finder->tableName())
$exists=$finder->exists($criteria);
else
{
$criteria->limit=2;
$objects=$finder->findAll($criteria);
$n=count($objects);
if($n===1)
{
if($column->isPrimaryKey) // primary key is modified and not unique
$exists=$object->getOldPrimaryKey()!=$object->getPrimaryKey();
else
{
// non-primary key, need to exclude the current record based on PK
$exists=array_shift($objects)->getPrimaryKey()!=$object->getOldPrimaryKey();
}
}
else
$exists=$n>1;
}

if($exists)
{
$message=$this->message!==null?$this->message:Yii::t('yii','{attribute} "{value}" has already been taken.');
$this->addError($object,$attribute,$message,array('{value}'=>$value));
}
}
}

Change log

r3527 by qiang.xue on Dec 31, 2011   Diff
1.1.9 release.
Go to: 
Sign in to write a code review

Older revisions

r3515 by mdomba on Dec 28, 2011   Diff
removed 1.0.x reference from
documentation
r3491 by jefftulsa on Dec 16, 2011   Diff
adding documentation about
placeholders in different validator
custom error messages - addressing
 Issue 2152 
r3260 by alexander.makarow on Jun 13, 2011   Diff
Error when using CUniqueValidator with
models indexed by specific field
All revisions of this file

File info

Size: 4577 bytes, 129 lines

File properties

svn:keywords
Id
Powered by Google Project Hosting