2017 © Pedro PelĂĄez
 

library business-rule-engine

Reusable library

image

mpoiriert/business-rule-engine

Reusable library

  • Thursday, March 27, 2014
  • by mpoiriert
  • Repository
  • 1 Watchers
  • 5 Stars
  • 1,342 Installations
  • PHP
  • 1 Dependents
  • 0 Suggesters
  • 2 Forks
  • 0 Open issues
  • 1 Versions
  • 0 % Grown

The README.md

Business Rule Engine

Build Status, (*1)

Engine that implement the specification pattern, (*2)

To use the business engine you need to need to instantiate a IBusinessRuleEngine class and assign a IRuleProvider to it. The IRuleProvider is responsible to provide rule base on their name. A rule is simply a callable with a name attach to it., (*3)


$businessRuleEngine = new \Nucleus\BusinessRuleEngine\BusinessRuleEngine(); $ruleProvider = new \Nucleus\BusinessRuleEngine\InMemoryRuleProvider(); $businessRuleEngine->setRuleProvider($ruleProvider); $ruleProvider->setRule('ruleTrue',function(){ return true; }); $ruleProvider->setRule('ruleFalse',function(){ return false; });

*A easy way to make a rule implement in a class that have this as it's only concern is to use the __invoke magic method.*, (*4)

From there you can call the business rule engine methods with a rule specification, (*5)


$businessRuleEngine->check("ruleTrue");//true $businessRuleEngine->check("ruleFalse");//false $result = $businessRuleEngine->getFirstMatch( array( "check1" => "ruleFalse", "check2" => "ruleTrue", ) ); echo $result;//check2 $result = $businessRuleEngine->getFirstMatch( array( "check1" => "ruleFalse", "check2" => "ruleTrue", "check3" => "ruleTrue", ) ); var_export($result);// array('check2','check3')

Rule Specification

A rule specification is a string concatenation of the rule name and the default parameter in Yaml. If you want to call the rule toto with default parameter param1 = 1, param2 = array(1,2) it would look like this:, (*6)

"toto{param1:1,param2[1,2]}"

You can add a ! before the rule if you want to make it false so you don't have to pass a parameter to the rule to say not match:, (*7)

"!toto{param1:1,param2[1,2]}"

If you want to check that 2 or more rules must validate you can pass a array of rule:, (*8)

array("toto{param1:1,param2[1,2]}","!toto{param1:1,param2[1,2]}")

Obviously the previous example will not pass since we are using the same rule with a not (!) in the second test. This will result in (true && !true) or (false && !false) evaluation., (*9)

If you want to do a OR check you can put this in a second array:, (*10)

array(array("toto{param1:1,param2[1,2]}","!toto{param1:1,param2[1,2]}"))

In this case the ending result will always result in a true result since the evaluation will be ((true || !true) or ((false || !false)), (*11)

You can mix those:, (*12)

array(rule1{},array(rule2{},rule3{}))

This will result in ($rule1Result && ($rule2Result || $rule3Result)), (*13)

This system is inspire from Symfony 1 credentials checks http://symfony.com/legacy/doc/reference/1_4/en/08-Security and the specification pattern http://en.wikipedia.org/wiki/Specification_pattern, (*14)

Check the unit test for more example of how to use it., (*15)

'Real' life usage

Here is some example of usage that could occur in real live. The implementation of class a rule are not available within this library, this library is just the engine itself., (*16)

Security

Check some complex permission rule base on a object that can provide a permission list, (*17)


$businessRuleEngine->check(array("permission{name:user}","!permission{name:newUser}"),array($user));//user && !newUser $businessRuleEngine->check(array(array("permission{name:admin}","permission{name:moderator}")),array($user));// admin || moderator

Payment Method

Check witch payment method to offer base on some order attribute, (*18)


$paymentMethodName = $businessRuleEngine->getFirstMatch( array( "cheapCharge" => array("orderCountry{countries:[CA,US]}","maxOrderPrice{max:9.99}"), "digitalProduct" => array("!orderContainPhysical"), "fallback" => array() ), $order )

Poker Card Game

Base on a hand witch have the biggest value. This is not complete but show how it could be use, (*19)


$rules = array( array("cardsValues{values:[10,11,12,13,A]}","cardsSameColor"), array("cardsStraight","cardsSameColor"), array("cardsSameValue{amountOfCards:[4]}"), array("cardsSameValue{amountOfCards:[3,2]"), array("cardsSameColor"), array("cardsStraight"), array("cardsSameValue{amountOfCards:[3]"), array("cardsSameValue{amountOfCards:[2,2]"), array("cardsSameValue{amountOfCards:[2]"), array(), ); $positionHand1 = $businessRuleEngine->getFirstMatch($rules,$hand1); $positionHand2 = $businessRuleEngine->getFirstMatch($rules,$hand2); if($positionHand1 == $positionHand2) { if($businessRuleEngine->check('firstHandHighestCardValue',array('hand1'=>$hand1,'hand2'=>$hand2))) { $winner = 'hand1'; } else { $winner = 'hand2'; } } else { $winner = $positionHand1 < $positionHand2 ? 'hand1' : 'hand2'; }

Promotion Display

If you display a promotion base on a user. Completely invented rules..., (*20)


$businessRuleEngine->check( array('lastTransaction{delay: - 1 months}','lastVisit{delay: -5 days}',array('totalPurchaseLessThan{amount:20.95}','fromCountry{countries[CA,US]}')), $user );

This would mean that you display the promotion if, (*21)

the last transaction of the user have been done more than 1 months ago, (*22)

AND, (*23)

the last visit of the user have been done more thant 5 days ago, (*24)

AND, (*25)

(the user have purchase for less the 20.95 in total, (*26)

OR, (*27)

in coming from country in the list CA and US), (*28)

The Versions

27/03 2014

dev-master

9999999-dev

Reusable library

  Sources   Download

MIT

The Requires

 

The Development Requires

by Martin Poirier ThĂ©orĂȘt

library specification nucleus business-rule-engine