• Stars
    star
    872
  • Rank 52,322 (Top 2 %)
  • Language
    PHP
  • License
    MIT License
  • Created almost 10 years ago
  • Updated about 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Powerful implementation of the Specification pattern in PHP

RulerZ Build Status Scrutinizer Code Quality

⚠️ This project is no longer maintained, reach out to me if you are interested in becoming maintainer ⚠️

The central idea of Specification is to separate the statement of how to match a candidate, from the candidate object that it is matched against.

Specifications, explained by Eric Evans and Martin Fowler

RulerZ is a PHP implementation of the Specification pattern which puts the emphasis on three main aspects:

  • an easy and data-agnostic DSL to define business rules and specifications,
  • the ability to check if a candidate satisfies a specification,
  • the ability to filter or query any datasource to only retrieve candidates matching a specification.

Introduction

Business rules can be written as text using a dedicated language, very close to SQL, in which case we refer to them as rules or they can be encapsulated in single classes and referred to as specifications.

Once a rule (or a specification) is written, it can be used to check if a single candidate satisfies it or directly to query a datasource.

The following datasources are supported natively:

  • array of arrays,
  • array of objects.

And support for each one of these is provided by an additional library:

Killer feature: when working with Doctrine, Pomm, or Elasticsearch, RulerZ is able to convert rules directly in queries and does not need to fetch data beforehand.

That's cool, but why do I need that?

First of all, you get to express business rules in a dedicated, simple language. Then, these business rules can be encapsulated in specification classes, reused and composed to form more complex rules. Specifications are now reusable and testable. And last but not least, these rules can be used both to check if a candidate satisfies it and to filter any datasource.

If you still need to be conviced, you can read the whole reasoning in this article.

Quick usage

As a quick overview, we propose to see a little example that manipulates a simple rule and several datasources.

1. Write a rule

The rule hereafter describes a "high ranked female player" (basically, a female player having more than 9000 points).

$highRankFemalesRule = 'gender = "F" and points > 9000';

2. Define a datasource

We have the following datasources:

// a Doctrine QueryBuilder
$playersQb = $entityManager
    ->createQueryBuilder()
    ->select('p')
    ->from('Entity\Player', 'p');

// or an array of arrays
$playersArr = [
    ['pseudo' => 'Joe',   'gender' => 'M', 'points' => 2500],
    ['pseudo' => 'Moe',   'gender' => 'M', 'points' => 1230],
    ['pseudo' => 'Alice', 'gender' => 'F', 'points' => 9001],
];

// or an array of objects
$playersObj = [
    new Player('Joe',   'M', 40, 2500),
    new Player('Moe',   'M', 55, 1230),
    new Player('Alice', 'F', 27, 9001),
];

3. Use a rule to query a datasource

For any of our datasource, retrieving the results is as simple as calling the filter method:

// converts the rule in DQL and makes a single query to the DB
$highRankFemales = $rulerz->filter($playersQb, $highRankFemalesRule);
// filters the array of arrays
$highRankFemales = $rulerz->filter($playersArr, $highRankFemalesRule);
// filters the array of objects
$highRankFemales = $rulerz->filter($playersObj, $highRankFemalesRule);

3. (bis) Check if a candidate satisfies a rule

Given a candidate, checking if it satisfies a rule boils down to calling the satisfies method:

$isHighRankFemale = $rulerz->satisfies($playersObj[0], $highRankFemalesRule);

Going further

Check out the documentation to discover what RulerZ can do for you.

License

This library is under the MIT license.

More Repositories

1

grabana

User-friendly Go library for building Grafana dashboards
Go
686
star
2

dark

(grafana) Dashboards As Resources in Kubernetes
Go
428
star
3

semver-release-action

GitHub Action to automatically create SemVer compliant releases based on PR labels.
Go
85
star
4

backstage-plugin-confluence

Confluence plugins for backstage
TypeScript
58
star
5

backstage-plugin-grafana

Grafana plugin for Backstage
TypeScript
57
star
6

backstage-plugin-announcements

Announcements plugin for Backstage
TypeScript
52
star
7

Rusty

Documentation as tests "à la" Rust for PHP.
PHP
48
star
8

DoctrineStateMachineBundle

[DEPRECATED] Doctrine2 behavior adding a finite state machine in your entities
PHP
46
star
9

RulerZBundle

Symfony Bundle for RulerZ
PHP
38
star
10

backstage-plugin-opsgenie

OpsGenie plugin for Backstage
TypeScript
35
star
11

Vich-Uploader-Sandbox

VichUploaderBundle sandbox
PHP
26
star
12

Vex

[DEPRECATED] Extract videos from any URL
PHP
24
star
13

DoctrineStateMachineBehavior

[DEPRECATED] Doctrine2 behavior adding a finite state machine in your entities
PHP
14
star
14

KPhoenSmsSenderBundle

[DEPRECATED] Integration of the SmsSender library into Symfony2.
PHP
14
star
15

rulerz-spec-builder

Specification builder for RulerZ
PHP
11
star
16

regis

PHP
9
star
17

gaufrette-extras

[DEPRECATED] PHP library providing extra features to the awesome Gaufrette
PHP
8
star
18

KPhoenContactBundle

Yet another contact bundle
PHP
7
star
19

boucle

Boucle is a static travel map and albums generator.
PHP
6
star
20

php-sql-parser

SQL parser implemented in pure PHP
Pascal
6
star
21

NegotiationServiceProvider

[DEPRECATED] Negotiation Service Provider for Silex
PHP
5
star
22

runner

Set of tools to work with .FIT, .TCX and .GPX files.
Python
5
star
23

travelr

Travelr is another static gallery generator, made for travelers.
PHP
5
star
24

gaufrette-extras-bundle

[DEPRECATED] Symfony2 bundle integrating the Gaufrette Extras library
PHP
3
star
25

mon-appart

La recherche d'appart pour ceux qui n'ont pas envie de chercher.
PHP
3
star
26

Config

My configuration files
Ruby
3
star
27

docker-sabre-katana

Docker image for the sabre/katana server
Makefile
3
star
28

k-phoen.github.io

My blog – generated by https://github.com/K-Phoen/blog
HTML
2
star
29

sfTaskExtraPlugin

PHP
2
star
30

silex-rulerz-provider

Silex provider for RulerZ
PHP
2
star
31

Python-REPL

Online Python Read-Eval-Print Loop (REPL)
JavaScript
2
star
32

rulerz-bridge

Symfony Bridge for RulerZ
PHP
2
star
33

negotiation

[DEPRECATED] Content Negotiation tools for Go
Go
2
star
34

node-simple-xlsx

Simple XLSX writer for Node.js.
JavaScript
2
star
35

Random-Stuff-Generator

API providing randomly generated entities (users, locations, events, ...)
PHP
2
star
36

docker-symfony

A Symfony Docker container
PHP
1
star
37

gostore

Gostore is a distributed hash table implementation based on the SWIM protocol and rendezvous hashing.
Go
1
star
38

HoaRouterBundle

[EXPERIMENT] Integrates Hoa/Router in Symfony
PHP
1
star
39

gaas

Geocoder As A Service
PHP
1
star
40

vagrant-dev-box

Vagrant and Puppet powered development box (for PHP and nodejs projects)
Puppet
1
star
41

myVagrant

My vagrant configuration
Ruby
1
star
42

backstage-plugin-codemods

TypeScript
1
star
43

advent_of_code_2018

Go
1
star
44

docker-nginx-php

1
star
45

negotiate

[DEPRECATED] Martini handler providing content negotiation to requests
Go
1
star
46

blog

My blog.
HTML
1
star
47

Wlppr

A small Python script to use wlppr.com and wallbase.cc for your wallpapers
Python
1
star
48

docker-sickbeard

This is a Dockerfile to set up "Sickbeard" on a Raspberry Pi
Shell
1
star
49

Pong

Un semblant de jeu de Ping-Pong réalisé en tant que TP/mini-projet de réseaux.
Java
1
star
50

Form-Class

A form creation & validation class
PHP
1
star