Yii2 trim everything on save
Asked Answered
C

2

5

Yii2 framework. The idea to create common behavior for common model:

  • before Validate trims all fields in model.
  • if it's array trim all values in array.

    1. I'm wondered why in Yii2 core doesn't exist such possibility. Or I'm wrong. Am I?

    2. What problems could I face if I trim all fields?

Cattery answered 20/4, 2016 at 13:42 Comment(2)
You could use the trim rule, yiiframework.com/doc-2.0/…Resolutive
yes but in this case I have to write this rule for each model and for all fields that I want to trim. I want to right it once for all modelsCattery
H
11

You can create a behavior and attach it at your models.

1) Create the behavior TrimBehavior in common/components.

<?php

namespace common\components;

use yii\db\ActiveRecord;
use yii\base\Behavior;

class TrimBehavior extends Behavior
{

    public function events()
    {
        return [
            ActiveRecord::EVENT_BEFORE_VALIDATE => 'beforeValidate',
        ];
    }

    public function beforeValidate($event)
    {
        $attributes = $this->owner->attributes;
        foreach($attributes as $key => $value) { //For all model attributes
            $this->owner->$key = trim($this->owner->$key);
        }
    }
}

2) In your models add the following:

//...
use common\components\TrimBehavior;
//...

/**
 * Returns a list of behaviors that this component should behave as.
 *
 * @return array
 */
public function behaviors()
{
    return [
        [
            'class' => TrimBehavior::className(),
        ],
    ];
}

Trimming attributes it depends on business logic. If you really need it then it's ok.

Hydrology answered 20/4, 2016 at 20:51 Comment(6)
Yes you are totally right, that was exactly what I was looking for. But what potential problem would I face? is it field will be array or related record, or anythings else.Cattery
You have to check using is_array() or something different according what you need each time.Hydrology
Yes, I absolutely agree.Cattery
The behavior should be in components folder, not common/components, and namespace should be app/components.Unicameral
@Unicameral common is used in yii2-app-advanced template. Many people use it. So common is common ;-)Ripley
This solution, but a little bit more flexible, can be also found as a composer package: laxity7/yii2-trim-behavior.Ripley
U
0

I tried suggested solution by Kostas Mitsarakis using behaviours and found that, while it works, will made some additional problems. I think one should do trim already on the $_POST data, so add this function to your Controller and all the posted data will be trimmed before getting into your model:

public function beforeAction($action)
{
    
    array_walk_recursive($_POST, function (&$val, $index)
    {
        $val = trim($val);
        // maybe also:
        // if(empty($val)) $val = null;
    });
    return parent::beforeAction($action);
}
Unicameral answered 2/9, 2022 at 13:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.