Conditional application rules

I would need different application rules for different users. For example I would need to have a rule, what checks that the user can not save an article in the past. However I would let admins to do this.

I have like 6 different rules, and I do not want to copy-paste the same check to all of them.

Hello rrd,

I’m not a CakePHP guru but I think you can do that specifying which validator to use when you save your entity:

ArticlesTable.php

public function validationDefault(Validator $validator) {
    $validator
              ->add(...);
        return $validator;
    }

public function validationAdmin(Validator $validator) {
    $validator
              ->add(...);
        return $validator;
    }

ArticlesController.php

    public function add() {
         ....
        $this->Articles->save($article, [
            'validate' => $user->role == "admin" ? 'Admin' : 'Default';
        ]);
    }

Thanks. It is useful, but in my case I need application rules not validation.

Ho yes sorry, I didn’t read you post correctly.

Instead of Copy/Pasting you can make standalone Rules objects that decorate other rules apply their rules based on the state in the entities/relations that are being persisted.

class AdminAllowedRule
{
    public function __construct($callable)
    {
            $this->callable = $callable;
    }

    public function __invoke(EntityInterface $entity, $options)
    {
            if ($entity->user->is_admin) {
                    return true;
            }
            $cb = $this->callable;
            return $cb($entity, $options);
    }
}

This decorator approach would allow you do decorate your rules with the ‘admin allowed’ logic.

    $rules->add(new AdminAllowedRule(function ($entity, $options) {
            return $entity->created < time();
    });

This is pretty rough code, but with some polish it could work.

1 Like

Great!

This is exactly what I need. As I see this is similar how validation works, somehow I just did not realized this :slight_smile:

Anyway I polish it for myself. Let’s see…