So, here is my scenario. I have got a model called URL. URL has the following attributes: link
(required), scheme
(required, but not safe.scheme is parsed from the link) and a few other attributes as well, which are not in context to this question.
Now, I made a custom validator for the scheme, which is following:
public function validateScheme($attribute, $param) {
if(empty($this->scheme)){
$this->addError('link', Yii::t('app', 'This is an invalid URL.'));
}
if (!in_array($this->scheme, $this->allowedSchemes)) {
$this->addError('link', Yii::t('app', 'This is an invalid URL.'));
}
}
Rules for URL:
public function rules() {
return [
['link', 'required', 'message' => Yii::t('app', 'URL can\'t be blank.')],
[['link'], 'safe'],
[['link'], 'string'],
['scheme', 'validateScheme']
];
}
This works fine when an invalid scheme is encountered, for example like let's say ftp.
However, when a completely invalid URL is entered, the scheme
remains empty and the validateScheme
is never triggered as, attribute scheme
is not required. To verify, I called $model->validate()
and it returns true even if it should not (or should may be, because the attribute is not required anyway).
So, my question number 2 : Is there a way to force the validateScheme
be triggered no matter if the attribute is empty, or non empty? I do not seem to find a way to do this in documentation.
I then tried the other way around, and made scheme
a required field. The problem with that is the fact that scheme
field is not safe and not there in the form. So, the URL does not save, but no error is shown.
My question number 1, in that case would be: Is there a way to assign targetAttribute
for scheme
so that the error message is shown below link
?
P.S. I know I can do this in the controller. I do not want to do that. I want to use the model only.