Yii 2.0: Before Query Example : Soft Delete

3 followers

This is how i do before query on Yii 2.0

(or you can use my extension here : yii2-before-query)

1. Base Trait Before Query

namespace common\traits\base;
trait BeforeQueryTrait{
 
    public static function find() {
        $obj = new static;
        $class = new \ReflectionClass($obj);
        $condition = [];
        foreach ($class->getProperties(\ReflectionProperty::IS_STATIC) as $property) {
            if(strpos($property->getName(),'BEFORE_QUERY') !== false && is_array($property->getValue($obj))){
                $condition = array_merge($condition, $property->getValue($obj));
            }
        }
        return parent::find()->andFilterWhere($condition);
    }
}

2. Add new property on model

Next, you can add new property on your model like this :

class MyClass extends \yii\db\ActiveRecord{
    use \common\traits\base\BeforeQueryTrait;
    public static $BEFORE_QUERY = ['myColumn' => 'myValue'];
}

3. You can create a new trait.

For example, i've created Soft Delete Boolean Trait :

trait SoftDeleteBoolTrait{
    public static $BEFORE_QUERY_SOFT_DELETE = ['isdeleted' => 0];
 
    public function deleteSoft() {
        $col = key(static::$BEFORE_QUERY_SOFT_DELETE);
        $this->{$col} = 1;
        return $this->save(false,[$col]);
    }
 
    public static function restore($id) {
        $col = key(static::$BEFORE_QUERY_SOFT_DELETE);
        $model = parent::findOne($id, 1);
        $model->{$col} = 0;
        $model->save(false,[$col]);
    }
}

Use it on model :

class MyClass extends \yii\db\ActiveRecord{
    use \common\traits\base\BeforeQueryTrait;
    use \common\traits\SoftDeleteBoolTrait;
}

Total 2 comments

#19267 report it
moo.tensai at 2015/05/04 06:17am
Re : Improvement @once
  1. I prefer not to break after needed property found. BeforeQueryTrait is a base class, and find() must cover any *BEFORE_QUERY* property. If other trait override find(), there will be collision.
  2. updated, thx for your improvement! I remove " && $property->isStatic()" on if section.
  3. updated, thx for your improvement!
  4. Sorry, I don't really get it.
#19266 report it
once at 2015/05/04 03:11am
improvement
  1. foreach cycle should breaks after needed property found
  2. $class->getProperties(ReflectionProperty::IS_STATIC) - get only static properties
  3. add brackets in if statement
  4. instead of static property you can you interface SoftDeletableInterface with protected static method, example signature public static function getSoftDeletableConditions(); and do not need to find static property, what if programmer forget add it, and in soft deletable interface you can add method restore

Leave a comment

Please to leave your comment.

Write new article