{"id":13669545,"url":"https://github.com/hoaproject/Ruler","last_synced_at":"2025-04-27T04:33:30.960Z","repository":{"id":9307128,"uuid":"11146594","full_name":"hoaproject/Ruler","owner":"hoaproject","description":"The Hoa\\Ruler library.","archived":true,"fork":false,"pushed_at":"2021-07-10T22:39:25.000Z","size":384,"stargazers_count":626,"open_issues_count":15,"forks_count":66,"subscribers_count":41,"default_branch":"master","last_synced_at":"2024-10-30T00:00:43.828Z","etag":null,"topics":["business-rules","hoa","library","php","rule-engine","ruler"],"latest_commit_sha":null,"homepage":"https://hoa-project.net","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"bchavez/BugTrap","license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hoaproject.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-07-03T09:21:14.000Z","updated_at":"2024-10-04T12:40:17.000Z","dependencies_parsed_at":"2022-09-02T23:40:51.466Z","dependency_job_id":null,"html_url":"https://github.com/hoaproject/Ruler","commit_stats":null,"previous_names":[],"tags_count":26,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoaproject%2FRuler","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoaproject%2FRuler/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoaproject%2FRuler/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoaproject%2FRuler/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hoaproject","download_url":"https://codeload.github.com/hoaproject/Ruler/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223939017,"owners_count":17228512,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["business-rules","hoa","library","php","rule-engine","ruler"],"created_at":"2024-08-02T08:01:16.873Z","updated_at":"2024-11-11T06:30:30.826Z","avatar_url":"https://github.com/hoaproject.png","language":"PHP","funding_links":[],"categories":["PHP","规则引擎( Rules Engine )"],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://static.hoa-project.net/Image/Hoa.svg\" alt=\"Hoa\" width=\"250px\" /\u003e\n\u003c/p\u003e\n\n---\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://travis-ci.org/hoaproject/Ruler\"\u003e\u003cimg src=\"https://img.shields.io/travis/hoaproject/Ruler/master.svg\" alt=\"Build status\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://coveralls.io/github/hoaproject/Ruler?branch=master\"\u003e\u003cimg src=\"https://img.shields.io/coveralls/hoaproject/Ruler/master.svg\" alt=\"Code coverage\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://packagist.org/packages/hoa/ruler\"\u003e\u003cimg src=\"https://img.shields.io/packagist/dt/hoa/ruler.svg\" alt=\"Packagist\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://hoa-project.net/LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/packagist/l/hoa/ruler.svg\" alt=\"License\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  Hoa is a \u003cstrong\u003emodular\u003c/strong\u003e, \u003cstrong\u003eextensible\u003c/strong\u003e and\n  \u003cstrong\u003estructured\u003c/strong\u003e set of PHP libraries.\u003cbr /\u003e\n  Moreover, Hoa aims at being a bridge between industrial and research worlds.\n\u003c/p\u003e\n\n# Hoa\\Ruler\n\n[![Help on IRC](https://img.shields.io/badge/help-%23hoaproject-ff0066.svg)](https://webchat.freenode.net/?channels=#hoaproject)\n[![Help on Gitter](https://img.shields.io/badge/help-gitter-ff0066.svg)](https://gitter.im/hoaproject/central)\n[![Documentation](https://img.shields.io/badge/documentation-hack_book-ff0066.svg)](https://central.hoa-project.net/Documentation/Library/Ruler)\n[![Board](https://img.shields.io/badge/organisation-board-ff0066.svg)](https://waffle.io/hoaproject/ruler)\n\nThis library allows to manipulate a rule engine. Rules can be written\nby using a dedicated language, very close to SQL. Therefore, they can\nbe written by a user and saved in a database.\n\nSuch rules are useful, for example, for commercial solutions that need\nto manipulate promotion or special offer rules written by a user. To\nquote [Wikipedia](https://en.wikipedia.org/wiki/Business_rules_engine):\n\n\u003e A business rules engine is a software system that executes one or more\n\u003e business rules in a runtime production environment. The rules might come from\n\u003e legal regulation (“An employee can be fired for any reason or no reason but\n\u003e not for an illegal reason”), company policy (“All customers that spend more\n\u003e than $100 at one time will receive a 10% discount”), or other sources. A\n\u003e business rule system enables these company policies and other operational\n\u003e decisions to be defined, tested, executed and maintained separately from\n\u003e application code.\n\n[Learn more](https://central.hoa-project.net/Documentation/Library/Ruler).\n\n## Installation\n\nWith [Composer](https://getcomposer.org/), to include this library into\nyour dependencies, you need to\nrequire [`hoa/ruler`](https://packagist.org/packages/hoa/ruler):\n\n```sh\n$ composer require hoa/ruler '~2.0'\n```\n\nFor more installation procedures, please read [the Source\npage](https://hoa-project.net/Source.html).\n\n## Testing\n\nBefore running the test suites, the development dependencies must be installed:\n\n```sh\n$ composer install\n```\n\nThen, to run all the test suites:\n\n```sh\n$ vendor/bin/hoa test:run\n```\n\nFor more information, please read the [contributor\nguide](https://hoa-project.net/Literature/Contributor/Guide.html).\n\n## Quick usage\n\nAs a quick overview, we propose to see a very simple example that manipulates a\nsimple rule with a simple context. After, we will add a new operator in the\nrule. And finally, we will see how to save a rule in a database.\n\n### Three steps\n\nSo first, we create a context with two variables: `group` and `points`, and we\nthen assert a rule. A context holds values to concretize a rule. A value can\nalso be the result of a callable. Thus:\n\n```php\n$ruler = new Hoa\\Ruler\\Ruler();\n\n// 1. Write a rule.\n$rule  = 'group in [\"customer\", \"guest\"] and points \u003e 30';\n\n// 2. Create a context.\n$context           = new Hoa\\Ruler\\Context();\n$context['group']  = 'customer';\n$context['points'] = function () {\n    return 42;\n};\n\n// 3. Assert!\nvar_dump(\n    $ruler-\u003eassert($rule, $context)\n);\n\n/**\n * Will output:\n *     bool(true)\n */\n```\n\nIn the next example, we have a `User` object and a context that is populated\ndynamically (when the `user` variable is concretized, two new variables, `group`\nand `points` are created). Moreover, we will create a new operator/function\ncalled `logged`. There is no difference between an operator and a function\nexcept that an operator has two operands (so arguments).\n\n### Adding operators and functions\n\nFor now, we have the following operators/functions by default: `and`, `or`,\n`xor`, `not`, `=` (`is` as an alias), `!=`, `\u003e`, `\u003e=`, `\u003c`, `\u003c=`, `in` and\n`sum`. We can add our own by different way. The simplest and volatile one is\ngiven in the following example. Thus:\n\n```php\n// The User object.\nclass User\n{\n    const DISCONNECTED = 0;\n    const CONNECTED    = 1;\n\n    public $group      = 'customer';\n    public $points     = 42;\n    protected $_status = 1;\n\n    public function getStatus()\n    {\n        return $this-\u003e_status;\n    }\n}\n\n$ruler = new Hoa\\Ruler\\Ruler();\n\n// New rule.\n$rule  = 'logged(user) and group in [\"customer\", \"guest\"] and points \u003e 30';\n\n// New context.\n$context         = new Hoa\\Ruler\\Context();\n$context['user'] = function () use ($context) {\n    $user              = new User();\n    $context['group']  = $user-\u003egroup;\n    $context['points'] = $user-\u003epoints;\n\n    return $user;\n};\n\n// We add the logged() operator.\n$ruler-\u003egetDefaultAsserter()-\u003esetOperator('logged', function (User $user) {\n    return $user::CONNECTED === $user-\u003egetStatus();\n});\n\n// Finally, we assert the rule.\nvar_dump(\n    $ruler-\u003eassert($rule, $context)\n);\n\n/**\n * Will output:\n *     bool(true)\n */\n```\n\nAlso, if a variable in the context is an array, we can access to its values from\na rule with the same syntax as PHP. For example, if the `a` variable is an\narray, we can write `a[0]` to access to the value associated to the `0` key. It\nworks as an hashmap (PHP array implementation), so we can have strings \u0026 co. as\nkeys. In the same way, if a variable is an object, we can call a method on it.\nFor example, if the `a` variable is an array where the value associated to the\nfirst key is an object with a `foo` method, we can write: `a[0].foo(b)` where\n`b` is another variable in the context. Also, we can access to the public\nattributes of an object. Obviously, we can mixe array and object accesses.\nPlease, take a look at the grammar (`hoa://Library/Ruler/Grammar.pp`) to see all\nthe possible constructions.\n\n### Saving a rule\n\nNow, we have two options to save the rule, for example, in a database. Either we\nsave the rule as a string directly, or we will save the serialization of the\nrule which will avoid further interpretations. In the next example, we see how\nto serialize and unserialize a rule by using the `Hoa\\Ruler\\Ruler::interpret`\nstatic method:\n\n```php\n$database-\u003esave(\n    serialize(\n        Hoa\\Ruler\\Ruler::interpret(\n            'logged(user) and group in [\"customer\", \"guest\"] and points \u003e 30'\n        )\n    )\n);\n```\n\nAnd for next executions:\n\n```php\n$rule = unserialize($database-\u003eread());\nvar_dump(\n    $ruler-\u003eassert($rule, $context)\n);\n```\n\nWhen a rule is interpreted, its object model is created. We serialize and\nunserialize this model. To see the PHP code needed to create such a model, we\ncan print the model itself (as an example). Thus:\n\n```php\necho Hoa\\Ruler\\Ruler::interpret(\n    'logged(user) and group in [\"customer\", \"guest\"] and points \u003e 30'\n);\n\n/**\n * Will output:\n *     $model = new \\Hoa\\Ruler\\Model();\n *     $model-\u003eexpression =\n *         $model-\u003eand(\n *             $model-\u003efunc(\n *                 'logged',\n *                 $model-\u003evariable('user')\n *             ),\n *             $model-\u003eand(\n *                 $model-\u003ein(\n *                     $model-\u003evariable('group'),\n *                     [\n *                         'customer',\n *                         'guest'\n *                     ]\n *                 ),\n *                 $model-\u003e{'\u003e'}(\n *                     $model-\u003evariable('points'),\n *                     30\n *                 )\n *             )\n *         );\n */\n```\n\nHave fun!\n\n## Documentation\n\nThe\n[hack book of `Hoa\\Ruler`](https://central.hoa-project.net/Documentation/Library/Ruler) contains\ndetailed information about how to use this library and how it works.\n\nTo generate the documentation locally, execute the following commands:\n\n```sh\n$ composer require --dev hoa/devtools\n$ vendor/bin/hoa devtools:documentation --open\n```\n\nMore documentation can be found on the project's website:\n[hoa-project.net](https://hoa-project.net/).\n\n## Getting help\n\nThere are mainly two ways to get help:\n\n  * On the [`#hoaproject`](https://webchat.freenode.net/?channels=#hoaproject)\n    IRC channel,\n  * On the forum at [users.hoa-project.net](https://users.hoa-project.net).\n\n## Contribution\n\nDo you want to contribute? Thanks! A detailed [contributor\nguide](https://hoa-project.net/Literature/Contributor/Guide.html) explains\neverything you need to know.\n\n## License\n\nHoa is under the New BSD License (BSD-3-Clause). Please, see\n[`LICENSE`](https://hoa-project.net/LICENSE) for details.\n\n## Related projects\n\nThe following projects are using this library:\n\n  * [RulerZ](https://github.com/K-Phoen/rulerz), Powerful implementation of the\n    Specification pattern in PHP,\n  * [ownCloud](https://owncloud.org/), A safe home for all your data,\n  * [PhpMetrics](http://www.phpmetrics.org/), Static analysis tool for PHP,\n  * [`hiqdev/php-billing`](https://github.com/hiqdev/php-billing), a billing library in PHP \n  * [`atoum/ruler-extension`](https://github.com/atoum/ruler-extension), This\n    extension allows to filter test results in [atoum](http://atoum.org/).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhoaproject%2FRuler","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhoaproject%2FRuler","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhoaproject%2FRuler/lists"}