Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Fixes #1955: Some validators used to cause warnings or errors in case non-scalar array typed values being checked. #2186

Merged
merged 4 commits into from

5 participants

resurtm Alexander Makarov Maurizio Domba Cerin Carsten Brandt Qiang Xue
resurtm
Collaborator

Fixes #1955: Some validators used to cause warnings or errors in case non-scalar array typed values being checked.

Alexander Makarov
Collaborator

Looks good to me. The only thing I think may be wrong are messages.

Alexander Makarov samdark was assigned
resurtm
Collaborator

There is another moment: even if we'll change validators, calling CActiveForm's or CHtml's methods in a views would cause array to string conversion errors. In my opinion this case should be handled here.

resurtm
Collaborator

The only thing I think may be wrong are messages.

What's wrong with them? Do you mean they should be customizable from validator configuration?
(But generally they work fine.)

Maurizio Domba Cerin
Collaborator

The error mesage of a validator should always the "[custom] validator message" (like "username is not right") not the one you put "array not allowed"

resurtm
Collaborator

I changed error messages (they became human friendly), but let me explain each validator separately:

CExistValidator:
Default error message string: '{attribute} "{value}" is invalid.'
My error message string: '{attribute} is invalid.'
Default error message string won't fit, so i decided to introduce new message.

CNumberValidator:
Default error message string: '{attribute} must be a number.'
This message is acceptable so i used it for array value case.

CRegularExpressionValidator:
Default error message string: '{attribute} is invalid.'
I left it unchanged too.

CStringValidator:
Default error message string: '{attribute} is of the wrong length (should be {length} characters).'
My error message string: '{attribute} is invalid.'
Default message won't fit too.

CUniqueValidator:
Default error messge string: '{attribute} "{value}" has already been taken.'
My error message string: '{attribute} is invalid.'
Default message won't fit too.

Alexander Makarov samdark merged commit 1e3a178 into from
Alexander Makarov
Collaborator

Merged. Thanks for working on this one.

resurtm
Collaborator

Though i'll test it more before 1.1.14 release.

Alexander Makarov
Collaborator

We plan doing RC like last time. As I can see, unit tests are covering the cases I'd test very well.

Maurizio Domba Cerin
Collaborator

@samdark you are too fast with the merge :D

Problem is that here we are now forcing a message that is not customized. If a custom validator message is set it would be expected to get that message and not a different now.

As it's pointed before, this "array error" can happen only when someone mess with the URL... I think that in that case we should throw an exception and not set a fixed message.

resurtm
Collaborator

I think that in that case we should throw an exception and not set a fixed message.

I thought about exceptions in the beginning, but purely subjectively stopped on usual error messages (i was wondering what you will think about it). But yes, i share your opinion on throwing exceptions, since it's no doubt far more an exceptional situation rather than usual (some validators are not intended to be used with arrays).

@samdark, do you agree?

(However i'm preparing fixing PR.)

Alexander Makarov
Collaborator

I'm against throwing exceptions in validators. Any value passed should either generate an error or be considered as valid. As for messages, I think array case is special and there's no point in customizing this message that only "too smart" people will see.

Maurizio Domba Cerin
Collaborator

@samdark I will stress this again... this "error" happens only if someone mess with the URL, so I don't see your point why would we just return the error message and continue the application as nothing was wrong. Note that this could later give some other nasty problems in the user app.

Because of all that and because this is not an expected value, exception is more than needed IMO.

Also note that we are already throwing different exceptions in the validators like for example the invalid operator in the CCompareValidator so why would be different for invalid value?

Alexander Makarov
Collaborator

Which nasty problems exactly? Value will not be valid.

We're throwing exceptions for not valid programmer input, not for not valid user import.

Maurizio Domba Cerin
Collaborator

I wrote "this could" not "this will"... it all depends on what the developer does with the parameters in his code.

Alexander Makarov
Collaborator

Validators aren't generally filtering values so if developer uses not valid or not validated values he'll get into trouble anyway.

Exception is probably OK as well since it's a special case not achievable by regular users. Personally either exception or validator error is OK for me.

Carsten Brandt
Collaborator

I agree that validator should not throw exception for an input value as he is ment to be used to detect any value for beeing valid or not.
But I also see the point of @mdomba that the validator message should not complain about array type but simply say it is invalid as this is what a users sees and he does not care what is going on in the background.
Haven't looked into the code, but I think messages that are ment for end users should not contain technical terms even if this is a case which someone might only get by manipulating urls...

Qiang Xue qiangxue commented on the diff
framework/web/helpers/CHtml.php
@@ -1574,6 +1574,11 @@ public static function activeTextArea($model,$attribute,$htmlOptions=array())
}
else
$text=self::resolveValue($model,$attribute);
+
+ // https://github.com/yiisoft/yii/issues/1955
+ if(is_array($text))
+ $text='';
+
Qiang Xue Owner

There is no need to check array here. The developer is responsible to make sure the type is proper. By doing so, it would mean we should do similar for nearly everywhere, which is simply too much for the framework.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Qiang Xue
Owner

I prefer to error messages here because it does fail the validation.

@mdomba made a point by saying that "this could later give some other nasty problems in the user app." However, it is not the responsibility of a single validator to stop the execution of the application because a user inputs an invalid value. A validator is responsible to check if an input value is valid or not and give back appropriate error messages. It should not stop the execution. What if there is some code after the validator who wants to detect such user attempts? (just an artificial example). The situation here is different from throwing exception in CCompareValidator because of invalid operator. In that case, the error is caused by developers, and the exception is used to warn the developer.

Maurizio Domba Cerin
Collaborator

Yes I understood that exceptions should be thrown only for developers error, I guess @samdark was thinking the same but I did not "get it"...

So, message it is, but currently there is a new fixed message used, shouldn't we check for the custom message even here?

Qiang Xue
Owner

Since this error normally does not appear to normal users, I think it is fine we don't offer customization.
In Yii 2, I am planning to introduce a property named allowArray in the base validator class and perform check there, which would avoid the duplicated array check in every validator.

resurtm resurtm referenced this pull request from a commit in resurtm/yii
resurtm resurtm Changes introduced in #2186 reverted. e67f7c1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Mar 9, 2013
  1. resurtm

    Some validators used to cause warnings or errors in case non-scalar a…

    resurtm authored
    …rray typed values being checked.
  2. resurtm
Commits on Mar 10, 2013
  1. resurtm

    CHtml::activeInputField() and CHtml::activeTextField() is not intende…

    resurtm authored
    …d to display array values.
  2. resurtm
This page is out of date. Refresh to see the latest.
1  CHANGELOG
View
@@ -12,6 +12,7 @@ Version 1.1.14 work in progress
- Bug #1941: yiiactiveform.js form reset now uses CHtml::errorCss instead of a hardcoded value (mdomba)
- Bug #1942: CActiveForm client/ajax validation will now remove error class from server side validation (mdomba)
- Bug #1945: Reference to undefined variable $column in CDbMigration::dropPrimaryKey (paystey)
+- Bug #1955: Some validators used to cause warnings or errors in case non-scalar array typed values being checked (resurtm)
- Bug #1984: CDbMigration: fix of undeclared variable usage in debug information in dropPrimaryKey (papulovskiy)
- Bug #1996: Using yiic help for commands with parameters with array as default value resulted in PHP error with latest PHP versions (dInGd0nG, samdark)
- Bug #1997: Cache key in CGettextMessageSource::loadMessages wasn't specific enough (odevyatkov)
3  framework/validators/CCaptchaValidator.php
View
@@ -47,7 +47,8 @@ protected function validateAttribute($object,$attribute)
if($this->allowEmpty && $this->isEmpty($value))
return;
$captcha=$this->getCaptchaAction();
- if(!$captcha->validate($value,$this->caseSensitive))
+ // reason of array checking is explained here: https://github.com/yiisoft/yii/issues/1955
+ if(is_array($value) || !$captcha->validate($value,$this->caseSensitive))
{
$message=$this->message!==null?$this->message:Yii::t('yii','The verification code is incorrect.');
$this->addError($object,$attribute,$message);
21 framework/validators/CDateValidator.php
View
@@ -52,17 +52,22 @@ protected function validateAttribute($object,$attribute)
if($this->allowEmpty && $this->isEmpty($value))
return;
- $formats=is_string($this->format) ? array($this->format) : $this->format;
$valid=false;
- foreach($formats as $format)
+
+ // reason of array checking is explained here: https://github.com/yiisoft/yii/issues/1955
+ if(!is_array($value))
{
- $timestamp=CDateTimeParser::parse($value,$format,array('month'=>1,'day'=>1,'hour'=>0,'minute'=>0,'second'=>0));
- if($timestamp!==false)
+ $formats=is_string($this->format) ? array($this->format) : $this->format;
+ foreach($formats as $format)
{
- $valid=true;
- if($this->timestampAttribute!==null)
- $object->{$this->timestampAttribute}=$timestamp;
- break;
+ $timestamp=CDateTimeParser::parse($value,$format,array('month'=>1,'day'=>1,'hour'=>0,'minute'=>0,'second'=>0));
+ if($timestamp!==false)
+ {
+ $valid=true;
+ if($this->timestampAttribute!==null)
+ $object->{$this->timestampAttribute}=$timestamp;
+ break;
+ }
}
}
4 framework/validators/CEmailValidator.php
View
@@ -87,7 +87,7 @@ protected function validateAttribute($object,$attribute)
*/
public function validateValue($value)
{
- if($this->validateIDN)
+ if(is_string($value) && $this->validateIDN)
$value=$this->encodeIDN($value);
// make sure string length is limited to avoid DOS attacks
$valid=is_string($value) && strlen($value)<=254 && (preg_match($this->pattern,$value) || $this->allowName && preg_match($this->fullPattern,$value));
@@ -182,7 +182,7 @@ protected function mxSort($a, $b)
/**
* Converts given IDN to the punycode.
- * @param $value IDN to be converted.
+ * @param string $value IDN to be converted.
* @return string resulting punycode.
* @since 1.1.13
*/
7 framework/validators/CExistValidator.php
View
@@ -73,6 +73,13 @@ protected function validateAttribute($object,$attribute)
if($this->allowEmpty && $this->isEmpty($value))
return;
+ if(is_array($value))
+ {
+ // https://github.com/yiisoft/yii/issues/1955
+ $this->addError($object,$attribute,Yii::t('yii','{attribute} is invalid.'));
+ return;
+ }
+
$className=$this->className===null?get_class($object):Yii::import($this->className);
$attributeName=$this->attributeName===null?$attribute:$this->attributeName;
$finder=CActiveRecord::model($className);
7 framework/validators/CNumberValidator.php
View
@@ -78,6 +78,13 @@ protected function validateAttribute($object,$attribute)
$value=$object->$attribute;
if($this->allowEmpty && $this->isEmpty($value))
return;
+ if(is_array($value))
+ {
+ // https://github.com/yiisoft/yii/issues/1955
+ $message=$this->message!==null?$this->message:Yii::t('yii','{attribute} must be a number.');
+ $this->addError($object,$attribute,$message);
+ return;
+ }
if($this->integerOnly)
{
if(!preg_match($this->integerPattern,"$value"))
5 framework/validators/CRegularExpressionValidator.php
View
@@ -48,7 +48,10 @@ protected function validateAttribute($object,$attribute)
return;
if($this->pattern===null)
throw new CException(Yii::t('yii','The "pattern" property must be specified with a valid regular expression.'));
- if((!$this->not && !preg_match($this->pattern,$value)) || ($this->not && preg_match($this->pattern,$value)))
+ // reason of array checking explained here: https://github.com/yiisoft/yii/issues/1955
+ if(is_array($value) ||
+ (!$this->not && !preg_match($this->pattern,$value)) ||
+ ($this->not && preg_match($this->pattern,$value)))
{
$message=$this->message!==null?$this->message:Yii::t('yii','{attribute} is invalid.');
$this->addError($object,$attribute,$message);
7 framework/validators/CStringValidator.php
View
@@ -80,6 +80,13 @@ protected function validateAttribute($object,$attribute)
if($this->allowEmpty && $this->isEmpty($value))
return;
+ if(is_array($value))
+ {
+ // https://github.com/yiisoft/yii/issues/1955
+ $this->addError($object,$attribute,Yii::t('yii','{attribute} is invalid.'));
+ return;
+ }
+
if(function_exists('mb_strlen') && $this->encoding!==false)
$length=mb_strlen($value, $this->encoding ? $this->encoding : Yii::app()->charset);
else
7 framework/validators/CUniqueValidator.php
View
@@ -83,6 +83,13 @@ protected function validateAttribute($object,$attribute)
if($this->allowEmpty && $this->isEmpty($value))
return;
+ if(is_array($value))
+ {
+ // https://github.com/yiisoft/yii/issues/1955
+ $this->addError($object,$attribute,Yii::t('yii','{attribute} is invalid.'));
+ return;
+ }
+
$className=$this->className===null?get_class($object):Yii::import($this->className);
$attributeName=$this->attributeName===null?$attribute:$this->attributeName;
$finder=CActiveRecord::model($className);
2  framework/validators/CUrlValidator.php
View
@@ -72,7 +72,7 @@ protected function validateAttribute($object,$attribute)
* Validates a static value to see if it is a valid URL.
* Note that this method does not respect {@link allowEmpty} property.
* This method is provided so that you can call it directly without going through the model validation rule mechanism.
- * @param mixed $value the value to be validated
+ * @param string $value the value to be validated
* @return mixed false if the the value is not a valid URL, otherwise the possibly modified value ({@see defaultScheme})
* @since 1.1.1
*/
10 framework/web/helpers/CHtml.php
View
@@ -1574,6 +1574,11 @@ public static function activeTextArea($model,$attribute,$htmlOptions=array())
}
else
$text=self::resolveValue($model,$attribute);
+
+ // https://github.com/yiisoft/yii/issues/1955
+ if(is_array($text))
+ $text='';
+
Qiang Xue Owner

There is no need to check array here. The developer is responsible to make sure the type is proper. By doing so, it would mean we should do similar for nearly everywhere, which is simply too much for the framework.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
return self::tag('textarea',$htmlOptions,isset($htmlOptions['encode']) && !$htmlOptions['encode'] ? $text : self::encode($text));
}
@@ -2137,6 +2142,11 @@ protected static function activeInputField($type,$model,$attribute,$htmlOptions)
unset($htmlOptions['value']);
elseif(!isset($htmlOptions['value']))
$htmlOptions['value']=self::resolveValue($model,$attribute);
+
+ // https://github.com/yiisoft/yii/issues/1955
+ if(is_array($htmlOptions['value']))
+ $htmlOptions['value']='';
+
if($model->hasErrors($attribute))
self::addErrorCss($htmlOptions);
return self::tag('input',$htmlOptions);
15 tests/framework/validators/CBooleanValidatorTest.php
View
@@ -61,6 +61,21 @@ public function testValidationUsingStrict()
$model->foo = '1';
$this->assertTrue($model->hasErrors('foo'));
}
+
+ /**
+ * Test array typed value
+ * https://github.com/yiisoft/yii/issues/1955
+ *
+ * @return null
+ */
+ public function testValidateArrayValue()
+ {
+ $model = $this->getModelMock();
+ $model->foo = array(1);
+ $this->assertFalse($model->validate());
+ $this->assertTrue($model->hasErrors('foo'));
+ $this->assertSame(array('Foo must be either 1 or 0.'), $model->getErrors('foo'));
+ }
/**
* Mocks up an object to test with
5 tests/framework/validators/CCompareValidatorTest.php
View
@@ -25,6 +25,11 @@ public function testValidationErrorsWithEquals()
$model->bar = 'foo';
$this->assertTrue($model->validate());
+ // https://github.com/yiisoft/yii/issues/1955
+ $model->foo = array('foo');
+ $this->assertFalse($model->validate());
+ $this->assertTrue($model->hasErrors('foo'));
+
// client validation
$validator = new CCompareValidator;
$validator->operator = '=';
4 tests/framework/validators/CDateValidatorTest.php
View
@@ -44,6 +44,10 @@ public function testFormatOption()
$this->assertTrue($model->validate());
$model->foo = '01-24-2011';
$this->assertFalse($model->validate());
+
+ // array value, https://github.com/yiisoft/yii/issues/1955
+ $model->foo = array('01-01-2011');
+ $this->assertFalse($model->validate());
}
/**
12 tests/framework/validators/CEmailValidatorTest.php
View
@@ -60,4 +60,16 @@ public function testIDNUrl($email, $validateIDN, $assertion)
$result = $emailValidator->validateValue($email);
$this->assertEquals($assertion, $result);
}
+
+ /**
+ * https://github.com/yiisoft/yii/issues/1955
+ */
+ public function testArrayValue()
+ {
+ $model=new ValidatorTestModel('CEmailValidatorTest');
+ $model->email=array('user@domain.tld');
+ $model->validate(array('email'));
+ $this->assertTrue($model->hasErrors('email'));
+ $this->assertEquals(array('Email is not a valid email address.'),$model->getErrors('email'));
+ }
}
12 tests/framework/validators/CExistValidatorTest.php
View
@@ -127,4 +127,16 @@ public function testValidateWithCriteria()
$model->name = $name;
$this->assertFalse($model->validate(),'Unable to validate model with custom criteria!');
}
+
+ /**
+ * https://github.com/yiisoft/yii/issues/1955
+ */
+ public function testArrayValue()
+ {
+ $modelClassName = $this->_arModelName;
+ $model = new $modelClassName('simple');
+ $model->name = array('test_name');
+ $this->assertFalse($model->validate());
+ $this->assertTrue($model->hasErrors('name'));
+ }
}
98 tests/framework/validators/CStringValidatorTest.php
View
@@ -0,0 +1,98 @@
+<?php
+
+class CStringValidatorTest extends CTestCase
+{
+ public function testMin()
+ {
+ // null value
+ $model1=new ValidatorTestModel('CStringValidatorTest');
+ $model1->validate(array('string1'));
+ $this->assertTrue($model1->hasErrors('string1'));
+ $this->assertSame(array('Too short message.'),$model1->getErrors('string1'));
+
+ // 9 characters length value
+ $model2=new ValidatorTestModel('CStringValidatorTest');
+ $model2->string1='123456789';
+ $model2->validate(array('string1'));
+ $this->assertTrue($model2->hasErrors('string1'));
+ $this->assertSame(array('Too short message.'),$model2->getErrors('string1'));
+
+ // 10 characters length value
+ $model3=new ValidatorTestModel('CStringValidatorTest');
+ $model3->string1='1234567890';
+ $model3->validate(array('string1'));
+ $this->assertFalse($model3->hasErrors('string1'));
+ $this->assertNotSame(array('Too short message.'),$model3->getErrors('string1'));
+
+ // array value: https://github.com/yiisoft/yii/issues/1955
+ $model4=new ValidatorTestModel('CStringValidatorTest');
+ $model4->string1=array('1234567890');
+ $model4->validate(array('string1'));
+ $this->assertTrue($model4->hasErrors('string1'));
+ }
+
+ public function testMax()
+ {
+ // null value
+ $model1=new ValidatorTestModel('CStringValidatorTest');
+ $model1->validate(array('string2'));
+ $this->assertFalse($model1->hasErrors('string2'));
+ $this->assertNotSame(array('Too long message.'),$model1->getErrors('string2'));
+
+ // 11 characters length value
+ $model2=new ValidatorTestModel('CStringValidatorTest');
+ $model2->string2='12345678901';
+ $model2->validate(array('string2'));
+ $this->assertTrue($model2->hasErrors('string2'));
+ $this->assertSame(array('Too long message.'),$model2->getErrors('string2'));
+
+ // 10 characters length value
+ $model3=new ValidatorTestModel('CStringValidatorTest');
+ $model3->string2='1234567890';
+ $model3->validate(array('string2'));
+ $this->assertFalse($model3->hasErrors('string2'));
+ $this->assertNotSame(array('Too long message.'),$model3->getErrors('string2'));
+
+ // array value: https://github.com/yiisoft/yii/issues/1955
+ $model4=new ValidatorTestModel('CStringValidatorTest');
+ $model4->string2=array('1234567890');
+ $model4->validate(array('string2'));
+ $this->assertTrue($model4->hasErrors('string2'));
+ }
+
+ public function testIs()
+ {
+ // null value
+ $model1=new ValidatorTestModel('CStringValidatorTest');
+ $model1->validate(array('string3'));
+ $this->assertTrue($model1->hasErrors('string3'));
+ $this->assertSame(array('Error message.'),$model1->getErrors('string3'));
+
+ // 9 characters length value
+ $model2=new ValidatorTestModel('CStringValidatorTest');
+ $model2->string3='123456789';
+ $model2->validate(array('string3'));
+ $this->assertTrue($model2->hasErrors('string3'));
+ $this->assertSame(array('Error message.'),$model2->getErrors('string3'));
+
+ // 11 characters length value
+ $model3=new ValidatorTestModel('CStringValidatorTest');
+ $model3->string3='12345678901';
+ $model3->validate(array('string3'));
+ $this->assertTrue($model3->hasErrors('string3'));
+ $this->assertSame(array('Error message.'),$model3->getErrors('string3'));
+
+ // 10 characters length value
+ $model4=new ValidatorTestModel('CStringValidatorTest');
+ $model4->string3='1234567890';
+ $model4->validate(array('string3'));
+ $this->assertFalse($model4->hasErrors('string3'));
+ $this->assertNotSame(array('Error message.'),$model4->getErrors('string3'));
+
+ // array value: https://github.com/yiisoft/yii/issues/1955
+ $model5=new ValidatorTestModel('CStringValidatorTest');
+ $model5->string3=array('1234567890');
+ $model5->validate(array('string3'));
+ $this->assertTrue($model5->hasErrors('string3'));
+ }
+}
12 tests/framework/validators/CUniqueValidatorTest.php
View
@@ -127,4 +127,16 @@ public function testValidateWithCriteria()
$model->name = $name;
$this->assertTrue($model->validate(),'Unable to validate model with custom criteria!');
}
+
+ /**
+ * https://github.com/yiisoft/yii/issues/1955
+ */
+ public function testArrayValue()
+ {
+ $modelClassName = $this->_arModelName;
+ $model = new $modelClassName('simple');
+ $model->name = array('test_name');
+ $this->assertFalse($model->validate());
+ $this->assertTrue($model->hasErrors('name'));
+ }
}
16 tests/framework/validators/CUrlValidatorTest.php
View
@@ -10,10 +10,10 @@ public function testEmpty()
$this->assertArrayHasKey('url', $model->getErrors());
}
- public function testArbitaryUrl()
+ public function testArbitraryUrl()
{
$urlValidator = new CUrlValidator();
- $url = 'http://testing-arbitary-domain.com/';
+ $url = 'http://testing-arbitrary-domain.com/';
$result = $urlValidator->validateValue($url);
$this->assertEquals($url, $result);
}
@@ -173,4 +173,16 @@ public function testAllowEmpty($url, $allowEmpty, $assertion)
$result = $urlValidator->validateValue($url);
$this->assertEquals($assertion, $result);
}
+
+ /**
+ * https://github.com/yiisoft/yii/issues/1955
+ */
+ public function testArrayValue()
+ {
+ $model=new ValidatorTestModel('CUrlValidatorTest');
+ $model->url=array('http://yiiframework.com/');
+ $model->validate(array('url'));
+ $this->assertTrue($model->hasErrors('url'));
+ $this->assertEquals(array('Url is not a valid URL.'),$model->getErrors('url'));
+ }
}
17 tests/framework/validators/ValidatorTestModel.php
View
@@ -1,14 +1,27 @@
<?php
class ValidatorTestModel extends CFormModel
{
+ public $string1;
+ public $string2;
+ public $string3;
+
public $email;
+
public $url;
public function rules()
{
return array(
- array('email', 'email', 'allowEmpty' => false, 'on' => 'CEmailValidatorTest'),
- array('url', 'url', 'allowEmpty' => false, 'on' => 'CUrlValidatorTest'),
+ array('string1', 'length', 'min'=>10, 'tooShort'=>'Too short message.', 'allowEmpty'=>false,
+ 'on'=>'CStringValidatorTest'),
+ array('string2', 'length', 'max'=>10, 'tooLong'=>'Too long message.', 'allowEmpty'=>false,
+ 'on'=>'CStringValidatorTest'),
+ array('string3', 'length', 'is'=>10, 'message'=>'Error message.', 'allowEmpty'=>false,
+ 'on'=>'CStringValidatorTest'),
+
+ array('email', 'email', 'allowEmpty'=>false, 'on'=>'CEmailValidatorTest'),
+
+ array('url', 'url', 'allowEmpty'=>false, 'on'=>'CUrlValidatorTest'),
);
}
}
Something went wrong with that request. Please try again.