2017 © Pedro Peláez
 

library collection-pipeline

PHP (partial) implementation of a pipeline collection. Work with a collection of objects without making a bunch of callables, loops, & ifs.

image

arete/collection-pipeline

PHP (partial) implementation of a pipeline collection. Work with a collection of objects without making a bunch of callables, loops, & ifs.

  • Tuesday, October 27, 2015
  • by aretecode
  • Repository
  • 1 Watchers
  • 6 Stars
  • 25 Installations
  • PHP
  • 1 Dependents
  • 0 Suggesters
  • 1 Forks
  • 0 Open issues
  • 1 Versions
  • 0 % Grown

The README.md

Arete\CollectionPipeline

Build Status HHVM Status Author Latest Unstable Version License Codacy Badge, (*1)

Work with a collection of objects without making a bunch of callables, loops, & ifs., (*2)

After reading Martin Fowler on the Collection Pipeline I wanted to use something similar in PHP, thus, this was born. League\Pipeline was used as was Illuminate\Support\Collection (all functions from this Collection are available in the chain.), (*3)

Example

This is our example group we will use

use Arete\CollectionPipeline\CollectionPipeline as CP;

class MockEntity {
    public $id;
    public $name;
    public function __construct($id, $name) {
        $this->id = $id;
        $this->name = $name;
    }
    public function getId() {
        return $this->id;
    }
    public function getName() {
        return $this->name;
    }
}

// ids are just random for testing
$array = array(
    new MockEntity(null, "eric"), #0
    new MockEntity(10, "tim"),    #1
    new MockEntity(111, "beau"),  #2
    new MockEntity(11, "ross"),   #3
    new MockEntity(12, "sarah"),  #4
    new MockEntity(13, "taylor"), #5
    new MockEntity(-42, "lea"),   #6
    new MockEntity("eh", "phil"), #7
    new MockEntity(6, "larry"),   #8
    new MockEntity(10, "frank"),  #9
    new MockEntity(["eh"], "joe"),#10

    new MockEntity(99, "kayla"),  #12
    new MockEntity(0, "martin"),  #11
    new MockEntity(1, "brad"),    #13
    new MockEntity(2, "luke"),    #14
    new MockEntity(3, "paul"),    #15
    new MockEntity(4, "ash"),     #16
    new MockEntity(5, "davey"),   #17
    new MockEntity(18,"anthony"), #18
    new MockEntity(19,"tim"),     #19
);

String functions

$result = CP::from($array)->wheres('getId', 'is_string')->all();

# gives: [7 => $array[7]]

! String functions

$result = CP::from($array)->wheres('getId', '!is_string')->all();

# gives: everything in $array except #7

Each

Use ::wheresEach to compare the whole value without using any accessors., (*4)

instanceof

$result = CP::from($array)->wheres('instanceof', MockEntity::CLASS)->all();

# gives: everything in $array

! instanceof

$result = CP::from($array)->wheres('!instanceof', MockEntity::CLASS)->all();

# gives: empty array, they all are instances of MockEntity

comparison operators

comparison operator tests, (*5)

$result = CP::from($array)->wheres('getId', '>', 110)->all();

# gives: [9 => $array[9]]

chaining

$result = CP::from($array)->wheres('getId', '!is_string')->wheres('getId', '>', 10)->wheres('getName', '===', 'tim')->all();

# gives: [19 => $array[19]]

argument order:

The accessor return value (X) as the first argument, and the value you are using in the comparison (Y)., (*6)

// one does contain joe, but none contain derek
$stringItWouldBeIn = 'joe,derek';
$x = 'getName';
$y = $stringItWouldBeIn;

// containsSubString is from arete\support
$result = CP::from($array)->wheresYX($x, 'containsSubString', $y)->all();

# gives: [10 => $array[10]]

Laravel Illuminate:

Since it extends Illuminate\Support\Collection, you can use their functions, such as:, (*7)

$result = CP::from($array)->wheres('id', 'is_string', null, 'property')->keys();

# gives: [7]

Types:

// will only check for the method `getId`
$result = CP::from($array)->wheres('getId', '>', 110, 'method')->all();

# gives: [9 => $array[9]]

Reverse order

// compares 110 < $payload->getId()
$result = CP::from($array)->wheres('getId', '<', 110, 'method', 'yx')->all();

# gives: [9 => $array[9]]

callables

$stringItWouldBeIn = 'joe,jonathon';
$result = CP::from($array)->wheresYX('getName', 'containsSubString', $stringItWouldBeIn, 'callable')->all();
$result = CP::from($array)->wheres('getId', function($value) {
    if ($value == 'tim')
        return true
    return false;
})->all();

# gives: [10 => $array[10]]

Value:

Value is an optional parameter, so if you want to check say, a property only, but have no value to compare it to:, (*8)

// will only check for the property `id`,
// it could be ['property', 'method'] if you wanted to use a method if the property was not there
// or it could be ['property', 'method', 'callable'] (which is default)
$result = CP::from($array)->wheres('id', 'is_string', null, 'property')->all();

# gives: [9 => $array[9]]

Specification

arete/specification, (*9)


use Arete\Specification\Specification; use Arete\Specification\SpecificationTrait; class NameEquals implements Specification { use ParameterizedSpecification; use SpecificationTrait; public function isSatisfiedBy($entity) { if ($entity->getName() == $this->value) return true; return false; } } $result = CP::from($array)->satisfying(new NameEquals('tim')); # gives: [10 => $array[10]]

Installation

It can be installed from Packagist using Composer., (*10)

In your project root just run:, (*11)

$ composer require arete/collection-pipeline, (*12)

Make sure that you’ve set up your project to autoload Composer-installed packages., (*13)

Running tests

Run via the command line by going to arete/collection-pipeline directory and running phpunit, (*14)

@TODO:

  • [ ] add ability to get an array with objects method values. Meaning, if I want to just get $objects->getName(); as an array of $objectNames and also maybe set what the key is?
  • [x] option to pass in an array with the '!' if you want it to be not?
  • [x] move ExpressionBuilder to Constructor()
  • [ ] optimize the filters so they can be combined and done in one loop when requested as array / all()?
  • [ ] pass in multiple string functions & comparison operators, such as 'is_string | is_int & >' be able to do ('methodName', 'strlen >', 5) (could use some Symfony\ExpressionLanguage optionally if alias are required) when this is done, it will really use the pipeline how it ought to
  • [ ] similar to the last todo, but with chaining method calls
  • [ ] move examples out of readme (except for 1), and into [examples/]
  • [x] add in spaceship comparison operator depending on version (thanks @seldaek)
  • [ ] ands using last method?
  • [x] refactor ExendedPipeline so it is less of a God object.
  • [ ] array key in Specification
  • [x] array key for matching along with the method, property, and callable
  • [x] abstract argsOrderYX & XY
  • [x] remove null check from ::wheresComparison
  • [x] add ability to reverse arguments in expressions
  • [ ] add casting of accessor
  • [ ] add ::reduce() similar implementation as ::map()

The Versions

27/10 2015

dev-master

9999999-dev

PHP (partial) implementation of a pipeline collection. Work with a collection of objects without making a bunch of callables, loops, & ifs.

  Sources   Download

MIT

The Requires

 

The Development Requires

by Avatar aretecode

collection pipeline arete