bobthecow / Ruler

A simple stateless production rules engine for modern PHP
MIT License
1.06k stars 140 forks source link

How to generate rulesets from Database? #28

Closed paulm17 closed 10 years ago

paulm17 commented 10 years ago

Hey,

First of all, love the ruleset engine. It saves me a ton of work that otherwise I would have had to do.

Now, it didn't take me long to get to grips with it. But I think I have it a wall with my own experience of php here.

What I am unable to do, is figure out how to generate rulesets dynamically.

Let me give a hardcoded example.

    $rb = new RuleBuilder;

    $context = new Context;
    $context['country'] = 'UK';
    $context['device'] = 'desktop';

    $rule = $rb->create(
        $rb->logicalAnd(
            $rb->logicalOr(
                $rb['country']->equalTo('Canada'),
                $rb['country']->equalTo('USA'),
                $rb['country']->equalTo('UK')
            ),
            $rb->logicalOr(
                $rb['device']->equalTo('mobile'),
                $rb['device']->equalTo('tablet'),
                $rb['device']->equalTo('desktop')
            )
        ), function() {
            $this->match = true;      
        }
    );

    $rule->execute($context);

    if ($this->match) {
        return 'Match';
    }
    else {
        return 'No Match';
    }

What I have incoming say from a $_GET variable is what's inserted into the context. The database contents will be Canada, USA, UK and then mobile, tablet, desktop respectively.

So my question is. How do I dynamically create multiple logicalOr rulesets that contain multiple equalTo variables?

In addition, I haven't seen an in_array operator as that would have been really nice to do $rb['country']->containsEither('Canada', 'UK', 'USA') and eliminate the need for multiple equalTo instances.

Edit: I am on 5.5.10 if that helps.

Thanks

paulm17 commented 10 years ago

Thought I would pay this forward. I got this done by a 3rd party.

So lets say I have 3 params to match against. Which could be a result from a database query.

    $rb = new RuleBuilder;

    $mdarray=array(
        "country"=>array('Canada','USA','UK'),
        "device"=>array('mobile','tablet','desktop'),
        "manfacturer"=>array('acer', 'vodaphone', 'nokia')
    );

    $topargs = array();

    foreach($mdarray as $key=>$arr){
        $args = array();
        foreach($arr as $val){
            array_push($args,$rb[$key]->equalTo($val));
        }
        array_push($topargs,call_user_func_array(array($rb, "logicalOr"), $args));
    }

    $context = new Context;
    $context['country'] = 'USA';
    $context['device'] = 'desktop';
    $context['manfacturer'] = 'nokia';

    $rule = $rb->create(
        call_user_func_array(array($rb, "logicalAnd"), $topargs)
        , function() {
            $this->match = true;      
        }
    );

    $rule->execute($context);

    if ($this->match) {
        return 'Match';
    }
    else {
        return 'No Match';
    }