Currently there are non-validation validators in Yii:
default that is setting default value if there’s no value.
filter that converts value from one format to another.
url can auto-prefix http:// or https:// if it’s missing.
Common sense tells us that validation should not modify data but check it for errors so these above do not quite match the concept. Still, they proved to be handy in both Yii 1 and Yii 2.
We have multiple options:
Keep these as is i.e. allow validators to modify values validated.
Remove these.
Move these to a conceptually different mechanism. That is likely to complicate configuration but may not.
I think that filter and url can be replaced with custom getter, I never used them. I have used sometimes default to fill property values, but we can init them in constructor.
I forgot to tell about models… New validation would not be tied to them and will be able to work with any object implementing an interface (if it provides rules itself) or any object (if rules are defined elsewhere). This way it will be possible to validate plain objects, ARs, Doctrine entities etc.
I’m think Option 3 will fit best choice.
A good example IMHO would be localized date and number transformations in beforeValidation and beforeSearch and afterSearch (looking at yii1, no real exp with newer). Events based would be my best bet.
@Piemol I usually add custom getters and setters directly inside the model (or its subclass) to handle date localization, without passing through event and validation, in model subclass.
This avoid to add extra code in search or validation functions, and automatically date model properties are filled from localized version
This is the model:
namespace backend\models;
use common\models\MyModel;
class MyModelForm extends MyModel
{
/**
* Rules
*/
public function rules()
{
return array_merge(parent::rules(), [
[['startTimeLocalized'], 'required'],
]);
}
/**
* Start Time
*/
public function getStartTimeLocalized()
{
$retOut = null;
if($this->start_time!=null)
{
$dt = new \DateTime($this-> start_time);
$retOut = $dt->format('d/m/Y H:i');
}
return $retOut;
}
public function setStartTimeLocalized($v)
{
$this-> start_time = null;
if($v!=null)
{
$dt = date_create_from_format('d/m/Y H:i', $v);
$this->start_time = $dt->format('Y-m-d H:i');
}
}