Ok, it is a little bit difficult to full understanding the unsafe validator.
User inputs that have not at least one validator in model will be rejected
So why the 'unsafe' validator is useful and when ?
Suppose You have an attribute in Model (CActiveRecord) that has to be saved (in most cases)
So the rule for this attribute should be
array('text_user_input', 'safe'), //or any other usual validator
Suppose also you have a blacklist users whom you want to prevent to pass their inputs. How to achieve that? A solution is using the unsafe validator
array('text_user_input', 'unsafe', 'on'=>'blacklistuser'),
I give you an example with code to make it cleaner
model:
class Article extends CActiveRecord {
...
array('text_user_input', 'safe'),
array('text_user_input', 'unsafe', 'on'=>'blacklistuser'),
...
}
viewer: //nothing extra, gii generated all the stuffs
controller:
public function actionNewArticle() {
if (Yii::app()->user->id == '13' ) { //as example
$model = new Article('blacklistuser');
$isblacklist = true;
} else {
$model = new Article;
$isblacklist = false;
}
if (isset($_POST['Article'])) {
$model->attributes = $_POST['Article'];
if ($model->validate()) {
$model->save(false)
} else {
if ($isblacklist) $model->addError('text_user_input','Are you an ambitious hacker eh?');
}
}
$this->render('create',array('model'=>$model));
}
note: the first rule matches and save the attribute (for all cases even for blacklistuser scenario) but the second one overrides the first and assigns as unsaved this attribute. also κeep in mind the order of the rules is irrelevant.
this article is far from real explanation of safe/unsafe...
...first of all - all validators can be safe and unsafe. you can control it with 'safe' attribute, like:
... array( 'email_field', 'email', 'safe'=>false ), ...
'safe' and 'unsafe' VALIDATORS are just empty validators that already have this attribute set to true/false respectively. And now - what is the point of this attribute? You must imagine that rule() function which returns 'validators' is in fact called at least in two scenarios (not the Yii AR 'scenarios', but scenarios in general :) ):
they have much in common, so they are handled with this one function. Massive assignment is when you do:
$model->attributes = $_POST['Model'];
which assigns ALL attributes passed with POST array to proper $model attribute. It is assumed that massive assignment is secure only when there are validators for attribute, because they can somehow check if provided value is correct. This is why rules() method is used in massive assignment. But rules() are also required to do validation before saving model to database for example.
There are situations when you want validators that will check attribute value before saving it to database, but you do not want to expose such attribute for massive assignments for security reasons - this is when 'usafe' is handy. You can add 'usafe' validator for such attribute or mark validators for this field with 'safe'=>false. The result will be exactly the same.
'safe' validator on the other hand is used when you want to expose attribute for massive assignment but you do not care what value is passed (no other validation). It should be used with care as it may lead to vulnerabilities and security holes. Instead you should consider any other validator that will check passed value with 'safe'=>true flag.
RE: this article is far from real explanation of safe/unsafe...
Hi redgui and thanks for your correction
Your comment seems more complementary rather than contradictory :)
Right, all Validators extends CValidators that have the attribute $safe and it is correct that could be set custom as you said.
The above code works correctly (I copied-pasted something wrong and now I am going to correct - sorry for that!) so in general way $safe variable of 'safe' and 'unsafe' validators is set 'true' and 'false' respectively.
I just added $model->attributes = $_POST['Article'], post condition and replace 'ContactForm' with 'Article'
It is an extremely ugly code style
Never use this example in real life.
$validators = $this->getValidatorList();
$validators->add(CValidator::createValidator('unsafe', $this, 'text_user_input', array('on' => 'blablabla')));
RE: It is an extremely ugly code style
1) when the validator becomes complex enough, it is better to make your own validator and check by condition what you want to check
2) I agree with you
3) There are cases to have decline for that! There are micro-conception MVC architectures to writting code easier. Controller has to decide what will be the message error in this case, so there are declines to strictly MVC architecture pattern
http://www.yiiframework.com/forum/index.php/topic/43999-activate-a-captcha-after-of-several-times/
http://www.yiiframework.com/forum/index.php/topic/44724-better-way-to-have-different-rendering/
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.