popcorn4dinner/collections

A flexible, simple to use and non-opinionated collection library

1.0.1 2018-06-26 08:29 UTC

README

A flexible, simple to use and non-opinionated collection library.

Features

  • minimalistic and easily comprehendable
  • supports pagiantion
  • supports json serialization
  • a bunch of util functions to make your live easier
  • designed for extensibility

Creating a collection

Minimal Usage:

use Popcorn4dinner\Collection\AbstractCollection;

class MyCollection extends AbstractCollection
{ 
   
 protected function isCollectableInstance($item): bool
     {
        // This is the place where you can inforce typing,
        // but also any other convention that all items in your collection 
        // have to follow.
        
         return true;
     }
}
$item1 = new ExampleItem();
$item2 = new ExampleItem();

$collection = new MyCollection($item1, $item2); 

foreach($collection as $item){
   //  Your logic goes here...
}

Controlling storage mechanics

use Popcorn4dinner\Collection\AbstractCollection;

class MyCollection extends AbstractCollection
{

 // Now users are stored uniquly by their email address
 protected function store($user)
 {
     $this->items[$user->email] = $user;
 }     
  
 protected function isCollectableInstance($user): bool
 {
     return $user->email !== null;
 }
}

Pagination and REST API endpoints

Paginated Collections can be used so enable pagination for API Endpoints and Views.

use Popcorn4dinner\Collection\AbstractPaginatedCollection;
  
class ExampleCollection extends AbstractPaginatedCollection
{

    protected function isCollectableInstance($item): bool
    {
        return is_a($item, ExampleItem::class);
    }
    
}
$offset = 10;
$limit = 20;
$totalAmountOfItems = 25;
  
$collection = new ExampleCollection($items, $offset, $limit, $totalAmountOfItems);
  
$collection->getPageSize()
// 10
  
$collections->getAmountPages()
// 3
  
$collection->getCurrentPage()
// 2
  
$collection->hasPreviousPage()
// true
  
$collection->hasNextPage()
// true

Paginated REST endpoints

use Popcorn4dinner\Collection\AbstractJsonSerializableCollection;
  
class ExampleJsonSerializableCollection extends AbstractJsonSerializableCollection
{
    protected function isCollectableInstance($item): bool
    {
        return is_a($item, ExampleItem::class);
    }
  
    protected static function serializeItem($item): array
    {
        return [ 'name' => $item->name];
    }
      
}
$collection->jsonSerialize();

/*
 * [
 *   "items" => 
 *      [
 *        [ "name" => "Some name"],
 *        ...  
 *      ],
 *   "_total" => 25,
 *   "_offset" => 10,
 *   "_limit" => 20,
 *   "_page_size" => 10,
 *   "_current_page" => 2,
 *   "_amount_pages" => 3,
 *   "_has_next_page" => true,
 *   "_has_previous_page" => true
 * ]
 */

Create collections from a request body

$users = PaginatedUserCollection::fromRequestBody($requestBody, 
    function($userDataRow){
        return new User($userDataRow['name']);
    }
);

Utility functions

each

Applies the callback to all items within the collection.

$users->each(
    function($user) { return $user->lock(); }
);

map

Applies the callback to all items within the collection and returns a new collection.

$lockedUsers = $users->map(
    function($user) { return $user->lock(); }
);

first

Returns the first item in the collection

$bird = $birds->first();

last

Returns the last item in the collection

$bird = $birds->last();

get

Return and item by key

$bird = $birds->get(3);

$user = $user->get("someone@example.com");

filter

Returns a new collection based on the filter callback

$productsAddedToday = $products->filter(
    function($product) { return $product->createdAt() > new \DateTime('today'); }
);

reject

Reverse effect of filter(). Return a new collection based on the filter callback

$delayedTrains = $trains->reject(
    function($tain) { return $train->isOnTime(); }
);

sort

Sorts the collection based on a callback

$purchases->sort(
    function($a, $b){ return $a->createdAt > $b->createdAt; }
);

unique

Return a new Collection with unique items.

$uniqueVisits = $visits->unique();

split

Maybe my personal favorite: Returns an array of collections, split based on the given callback.

$purchasesByDay = $purchases->split(
    functions($purchase){ return $purchase->createdAt->format('Y-m-d'); }
);
  
// returns:
// [
//    '2017-08-01' => PurchaseCollection...

reduce

Returns an array of transformed items.

$userIds = $users->reduce(
    function($user){ $user->id }
);

toArray

Returns an Array with all items in the collection.

SomeArrayFunction( $collection->toArray() );

License

MIT