Custom Collections
William Cahill-Manley
william@cahillmanley.com
San Diego Laravel User Group
11 / 18 / 2015
Creating Collections
<?php
$items = collect ( range( 1, 12 ) );
=> Illuminate\Support\Collection {
all: [
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
],
}
// Creating Directly:
$items = new Illuminate\Support\Collection( range( 1, 12 ) );
Working with Collections
>>> $items = collect ( range( 1, 12 ) );
>>> $items->first();
=> 1
>>> $items->last();
=> 12
>>> $items->random();
=> 2
>>> $items->random();
=> 5
>>> $items->reverse();
=> Illuminate\Support\Collection {#681
all: [
12,
11,
10,
9,
8,
7,
6,
5,
4,
3,
2,
1,
],
}
Manipulation
$items->map( function ( $item ) {
return pow( $item, 2 );
});
=> Illuminate\Support\Collection {
all: [
1,
4,
9,
16,
25,
36,
49,
64,
81,
100,
121,
144,
],
}
Filtering
$items->filter( function ( $item ) {
return $item % 2 == 0;
});
=> Illuminate\Support\Collection {
all: [
1 => 2,
3 => 4,
5 => 6,
7 => 8,
9 => 10,
11 => 12,
],
}
Chaining Operations
$items->map( function ( $item ) {
return pow( $item, 2 );
})->filter( function( $item ) {
return $item % 2 == 0;
});
=> Illuminate\Support\Collection {
all: [
1 => 4,
3 => 16,
5 => 36,
7 => 64,
9 => 100,
11 => 144,
],
}

Extending
<?php
use Illuminate\Support\Collection;
class MathCollection extends Collection
{
public function pow( $power )
{
return $this->map( function( $item ) use ( $power ) {
return pow( $item, $power );
});
}
...
}
$items = new MathCollection( range( 1, 12 ) );
$items->pow( 2 );
Chained Extension
class MathCollection extends Collection
{
public function pow( $power )
{
return $this->map( function( $item ) use ( $power ) {
return pow( $item, $power );
});
}
public function even()
{
return $this->filter( function( $item ) {
return $item % 2 == 0;
});
}
public function odd()
{
return $this->filter( function( $item ) {
return $item % 2 != 0;
});
}
}
$items = new MathCollection( range( 1, 12 ) );
$items->pow( 2 )->even();
Converting
>>> $items = collect( range( 1, 12 ) );
...
>>> $items->toArray();
=> [
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
]
>>> $items->toJson();
=> "[1,2,3,4,5,6,7,8,9,10,11,12]"
Converting
>>> $items = collect( range( 1, 12 ) );
...
>>> with( new MathCollection( $items ) )->pow( 3 );
=> MathCollection {
all: [
1,
8,
27,
64,
125,
216,
343,
512,
729,
1000,
1331,
1728,
],
}
Hashes
>>> $schedule = collect( [
[
"name" => "William Cahill-Manley",
"title" => "Custom Collections"
],
[
"name" => "John Congdon",
"title" => "Wrapping Laravel around a legacy codebase"
]
] );
=> Illuminate\Support\Collection {
all: [
[
"name" => "William Cahill-Manley",
"title" => "Custom Collections",
],
[
"name" => "John Congdon",
"title" => "Wrapping Laravel around a legacy codebase",
],
],
}
Hashes
>>> $schedule = collect( [
[
"name" => "William Cahill-Manley",
"title" => "Custom Collections"
],
[
"name" => "John Congdon",
"title" => "Wrapping Laravel around a legacy codebase"
]
] );
>>> $schedule->lists( 'name' );
=> Illuminate\Support\Collection {
all: [
"William Cahill-Manley",
"John Congdon",
],
}
Hashes
>>> $schedule = collect( [
[
"name" => "William Cahill-Manley",
"title" => "Custom Collections"
],
[
"name" => "John Congdon",
"title" => "Wrapping Laravel around a legacy codebase"
]
] );
>>> $schedule->lists( 'title' );
=> Illuminate\Support\Collection {
all: [
"Custom Collections",
"Wrapping Laravel around a legacy codebase",
],
}
Hashes
>>> $schedule = collect( [
[
"name" => "William Cahill-Manley",
"title" => "Custom Collections"
],
[
"name" => "John Congdon",
"title" => "Wrapping Laravel around a legacy codebase"
]
] );
>>> $schedule->lists( 'title', 'name' );
=> Illuminate\Support\Collection {
all: [
"William Cahill-Manley" => "Custom Collections",
"John Congdon" => "Wrapping Laravel around a legacy codebase",
],
}
Eloquent Collections
>>> User::all();
=> Illuminate\Database\Eloquent\Collection {#693
all: [
App\User {#694
id: "1",
name: "William Cahill-Manley",
email: "william@cahillmanley.com",
created_at: "2015-11-16 23:31:31",
updated_at: "2015-11-16 23:31:31",
},
App\User {#695
id: "2",
name: "William Cahill-Manley",
email: "william@kindari.net",
created_at: "2015-11-16 23:31:40",
updated_at: "2015-11-16 23:31:40",
},
App\User {#696
id: "3",
name: "William Cahill-Manley",
email: "wmanley@cari.net",
created_at: "2015-11-16 23:31:51",
updated_at: "2015-11-16 23:31:51",
},
],
}
Getting Eloquent Collections
User::all();
User::get();
User::where('name', 'like', '%william%')->get();
>>> $users = User::where('name', 'no match')->get();
=> Illuminate\Database\Eloquent\Collection {
all: [],
}
>>> if ( $users ) { echo "Yup"; }
Yup
=> null
>>> $users->isEmpty();
=> true
->find()
>>> $users = User::all();
...
>>> $users->find(1);
=> App\User {
id: "1",
name: "William Cahill-Manley",
email: "william@cahillmanley.com",
created_at: "2015-11-16 23:31:31",
updated_at: "2015-11-16 23:31:31",
}
>>> $users->find(5);
=> null
Eager Loading
>>> $users = User::with('orders')->get();
...
>>> $users = User::get();
...
>>> $users->load('orders');
=> Illuminate\Database\Eloquent\Collection {#696
all: [
App\User {#697
id: "1",
name: "William Cahill-Manley",
email: "william@cahillmanley.com",
created_at: "2015-11-16 23:31:31",
updated_at: "2015-11-16 23:31:31",
orders: Illuminate\Database\Eloquent\Collection {#705
all: [
App\PurchaseOrder {#708
id: "1",
user_id: "1",
cost: "10",
description: "Cloud Server",
created_at: "2015-11-18 08:30:37",
updated_at: "2015-11-18 08:30:37",
},
],
},
},
App\User {#698
id: "2",
name: "William Cahill-Manley",
email: "william@kindari.net",
created_at: "2015-11-16 23:31:40",
updated_at: "2015-11-16 23:31:40",
orders: Illuminate\Database\Eloquent\Collection {#703
all: [],
},
},
App\User {#699
id: "3",
name: "William Cahill-Manley",
email: "wmanley@cari.net",
created_at: "2015-11-16 23:31:51",
updated_at: "2015-11-16 23:31:51",
orders: Illuminate\Database\Eloquent\Collection {#704
all: [],
},
},
],
}
Dictionary
>>> $users = User::all();
...
>>> $users->getDictionary();
=> [
1 => App\User {
id: "1",
name: "William Cahill-Manley",
email: "william@cahillmanley.com",
created_at: "2015-11-16 23:31:31",
updated_at: "2015-11-16 23:31:31",
},
2 => App\User {
id: "2",
name: "William Cahill-Manley",
email: "william@kindari.net",
created_at: "2015-11-16 23:31:40",
updated_at: "2015-11-16 23:31:40",
},
3 => App\User {
id: "3",
name: "William Cahill-Manley",
email: "wmanley@cari.net",
created_at: "2015-11-16 23:31:51",
updated_at: "2015-11-16 23:31:51",
},
]
Relationships
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function orders()
{
return $this->hasMany('App\PurchaseOrder');
}
}
>>> User::find(1)->orders;
=> Illuminate\Database\Eloquent\Collection {
all: [
App\PurchaseOrder {
id: "1",
user_id: "1",
cost: "10",
description: "Cloud Server",
created_at: "2015-11-18 08:30:37",
updated_at: "2015-11-18 08:30:37",
},
],
}
Relations that return Collections
- hasMany()
- belongsToMany()
- hasManyThrough()
- morphMany()
- morphToMany()
Custom Eloquent Collections
<?php namespace Illuminate\Database\Eloquent;
...
abstract class Model implements ArrayAccess, Arrayable, Jsonable, JsonSerializable
{
...
/**
* Create a new Eloquent Collection instance.
*
* @param array $models
* @return \Illuminate\Database\Eloquent\Collection
*/
public function newCollection(array $models = [])
{
return new Collection($models);
}
...
}
User Collection
<?php
class UserCollection extends Illuminate\Database\Eloquent\Collection
{
}
class User extends Illuminate\Database\Eloquent\Model
{
public function newCollection(array $models = [])
{
return new UserCollection($models);
}
}
User Collection
>>> User::get();
=> UserCollection {
all: [
App\User {
id: "1",
name: "William Cahill-Manley",
email: "william@cahillmanley.com",
created_at: "2015-11-16 23:31:31",
updated_at: "2015-11-16 23:31:31",
},
App\User {
id: "2",
name: "William Cahill-Manley",
email: "william@kindari.net",
created_at: "2015-11-16 23:31:40",
updated_at: "2015-11-16 23:31:40",
},
App\User {
id: "3",
name: "William Cahill-Manley",
email: "wmanley@cari.net",
created_at: "2015-11-16 23:31:51",
updated_at: "2015-11-16 23:31:51",
},
],
}
- Repository Pattern
- Provider Seperation
- Quality Code
... Not tonight, folks!
class UserCollection extends Illuminate\Database\Eloquent\Collection
{
public $emailVariables = [
'email',
'name',
'id'
];
public function getSubstitutions($keys)
{
$output = array();
foreach($keys as $key)
{
$output[ "%{$key}%" ] = $this->lists( $key );
}
return collect($output);
}
...
}
class UserCollection extends Illuminate\Database\Eloquent\Collection
{
...
public function email($subject, $text, $html)
{
$sendgrid = app('sendgrid');
$mail = app('sendgrid.email');
$mail->setSubject( $subject );
$mail->setText( $text );
$mail->setHtml( $html );
$this->chunk( 100 )->each( function( $users ) use( $sendgrid, $mail ) {
$mail->setSmtpapiTos( $users->lists( 'email' )->toArray() );
$mail->setSubstitutions( $users->getSubstitutions( $users->emailVariables )->toArray() );
$sendgrid->send( $mail );
});
}
}
>>> $users = User::all();
...
>>> $users->email(
... 'Product Announcement',
... "Hello %name%,\n\nOn Friday we will be launching a new product ...",
... "<p>Hello %name%,</p><p>On <b>Friday</b> we will be launching a new product ..."
... );