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 ..."
... );

Thank You

Questions?

Made with Slides.com