Breaking the Mold

I always write my talks in Markdown format, so for those people who couldn't make it to Laracon, here's my notes in their rough format. It should tide you over until the conference videos make an appearance.

Hi everyone, and thanks for having me back in the good U ESS OF A for another talk and a few days of fun. My name's Dayle Rees and I use red pandas to educate developers.

I'm Welsh, so I might sound a little funny, but I'm hoping you'll be able to understand me today. Are there any other welsh people in here? Cool, any Americans? Being Welsh is great, because we clearly have the best flag in the world. I mean look, a dragon? Sorry but stars and stripes isn't gonna cut it against a dragon.

Here, I've made a new flag for you.

http://i.imgur.com/xZ3PQ33.png

Some of you will have seen and maybe if you're brave, read one of these books. Or both, if you're hardcore like that. I wrote Code Bright a few years ago now, a book for Laravel three who's goal was to entice more users to the framework, and I like to think it succeeded. My latest book 'Code Bright' has over 3700 readers and over 400 pages (so far) of Laravel goodness. It's become almost a welcome package for new developers seeking to pick up Laravel. So thanks to everyone who has supported my writing.

I've also created 100+ colour schemes for 10+ editors that are used by hundreds of thousands of developers around the world. As you can see, my time and projects are devoted to trying to make the life of a developer more enjoyable. Our job is hard, so we should enjoy doing it.

Last year I came to Laracon and explained how Laravel had grown quickly from the days where there were 2 or three of us using it. Plenty more now of course. Also how becomming involved in the project and beginning to write had changed my life.

I mentioned how I'd just moved from a quiet little town and got a job at a Cardiff development agency called Box UK. So a year has passed and now I'm somewhere else. Haha, now I know that doesn't sound great, but I had a lot of fun at box meeting some great developers and learned a lot, but eventually I found myself seeking more challenge and to invest myself in my work. So just before Christmas I left the company to become head of development for a startup called ParkatmyHouse.com. When does a startup cease to be a startup? Well, I'm not sure since it's been around for 7 years or so.

Head of development is an interesting role, since at the moment I get to be both lead developer, project manager, cook and bottle-wash. Which suits me fine, I'm learning to multi-task, and to manage, and I love learning new things. I'm also really lucky because I was allowed to bring my entire team to Laracon.

< Embarrass James >

If you've not heard of the site before then let me explain. We allow property owners to rent their driveways and in some circumstances parking lots to other drivers to earn some extra pocket money. We're helping to solve the problem of parking in major cities. I find it's really rewarding to be working on something that's helping to solve real problems in the world, no matter how small they may appear to be. We're actually hiring all kinds of developers and designers in the UK at the moment, so it would be plain wrong of me to not use this event as a hiring opportunity, so send me an email if you're interested.

So when I joined the company I was gifted with something that all we developers crave and dream about. I'm not talking about an endless supply of code red and Cheetos. (neither of these exist in the UK by the way). Anyone have any guesses?

A blank slate.

We're looking to grow the company and reach more drivers and property owners. We're building a central API not only to power the typical site and mobile app lineup, but also a range of awesome in-car devices. They say go big or go home, well we don't want to go home.

The whole system is being re-built from the ground up. I was hired because there was an intention internally to stick to PHP and some curiosity towards Laravel, but other than that we were free to make our own decisions.

So where am I going with all this? I figured you might be asking that question by now so let sidetrack one last time.

Whenever you become associated with a community, a tool, or a framework, especially in the realm of education, you start to receive emails, tweets, messages w/e medium. Here's one that I receive on a regular basis, and I'm pretty sure that Taylor has seen this one once or twice.

"Where do I put x?"

This is a question I absolutely loathe to answer. Laravel provides a huge amount of flexibility for the developer. You can break it into pieces and do your own thing with it. For this reason there isn't always a default location for something. This means that any answer that I give you will be a matter of preference.

My fear when it comes to matters of preference is that they have a terrible habit of becoming pseudo standards. Someone somewhere blogs with their own opinion. The article receives some attention, gets spread around, people start chiming in and preaching, then BOOM if you're not doing it this way you're "wrong".

There's a lot of this preaching becoming standard in developer communities and as an educator I find it a little worrying. I try to keep away from it. We all learn at our own pace, and as a noobie developer how do you tune out all of the "you must do it this way". The trick to learning is to enjoy, and to enjoy you need to get started quickly, see results and be driven by curiosity. Preaching just creates a scary community for newcomers to grow within.

What I guess I'm saying, is that it's much better to teach with options rather than opinions. So where do these questions come from? Well let me show you a part of Laravel that I call the 'app package', I'm not sure why, maybe boilerplate or blueprint is a better word. Anyway, it's the contents of laravel/laravel the repository that you clone down when you first get started with Laravel.

This is your space. It's where you work, where your stuff lives. If it was an empty directory then it wouldn't be very welcoming would it? Laravel is for people of all levels of experience. It's the framework that grows with you. For this reason the folders you find within the app directory are typical of MVC applications. They are named cleanly, and it's clear to a beginner that controllers go in the controllers directory, and models go in the models directory. We have a route file for our routes, a configuration folder for our configurations and every thing's where it should be.

Until you come to something like a view composer, or the registration of an observer. These aren't things that you are going to use unless you are working on a larger application, or something more complex. That's why there aren't any default folders or files there for these things.

Only the directories needed to get started quickly, create little applications and get started with the framework. So it's easy to see why that old dreaded question keeps showing up. Where do we put x?

Well I thought today I'd break my rules. I'm going to share some of the opinions and decisions that I've made when starting my most recent project. It's important to note that these ideas and customisations are my own choice, and may not make sense for every project. Also many of the techniques I've used to shape a project have been borrowed/stolen from others. Reading others' code is a great way of learning new tricks.

So let's start at that lovely blank slate. To begin with I either use Composer's create-project or simply clone the Laravel repository to my local machine. I'll normally let my Laravel project live in the 'project' directory rather than the root of my project repository, because this means that I can add other folders for various build / workflow tasks as I see fit.

The next phase of my project setup I like to call the hulk smash phase.

#!/bin/bash

alias hulksmash='rm -rf'

hulksmash app/controllers
hulksmash app/models
hulksmash app/commands
hulksmash app/tests
hulksmash app/filters.php

echo 'Puny god!'

Now I need to do some cleanup. We've destroyed some folders so we aren't gonna need some of the autoloading. We can clean this up by editing the composer.json:

"autoload": {
    "classmap": [
        "app/commands",
        "app/controllers",
        "app/models",
        "app/database/migrations",
        "app/database/seeds",
        "app/tests/TestCase.php"
    ]
},

Laravel has an additional autoloader to avoid all the composer dump-autoload repeating, so we need to update that too. You can find it in app/start/global.php.

/*
|--------------------------------------------------------------------------
| Register The Laravel Class Loader
|--------------------------------------------------------------------------
|
| In addition to using Composer, you may use the Laravel class loader to
| load your controllers and models. This is useful for keeping all of
| your classes in the "global" namespace without Composer updating.
|
*/

ClassLoader::addDirectories(array(

    app_path().'/commands',
    app_path().'/controllers',
    app_path().'/models',
    app_path().'/database/seeds',

));

We can rip that out completely. While we're there, we might as well get rid of the filters file.

/*
|--------------------------------------------------------------------------
| Require The Filters File
|--------------------------------------------------------------------------
|
| Next we will load the filters file for the application. This gives us
| a nice separate location to store our route and application filter
| definitions instead of putting them all in the main routes file.
|
*/

require app_path().'/filters.php';

There, now the app directory is purely for configuration and templates. So now we need to create a new home for our code. Now with Laravel there are commonly two accepted ways of providing callbacks to the routing engine, events, etc. You can use closures or you can use class and method pairs. Now closures are great if you're building a really small app, if you want to hack something together quickly, or even if you're still learning web development. However, if I'm building a sizeable app, or one that I intend to maintain, then 90% of the time I will use class/method pairs. It means my classes can share properties and dependencies, they can be grouped by purpose, and they can be instantiated and tested in isolation.

Now that we're done with deleting, it's time to get creating. We're going to namespace our code so that we don't get any conflicting class names with other packages, and so we can create an organized structure for our source.

I like to create a src directory parallel to the app directory that the framework has provided for us. It keeps my code away from what I consider to be configuration. This directory is purely for classes.

"autoload": {
    "classmap": [
        "app/database/migrations",
        "app/database/seeds",
    ],
    "psr-4": {
        "Rees\\Laracon\\": "src"
    }
},

The next thing that we need to do, is to add the PSR-4 autoloading mechanism. If you've encountered PSR-0 autoloading, you'll already know that it allows for matching nested class directories and class names to the namespace. Well PSR-4 also does this, but you don't need to create directories for the namespace prefix that we defined in composer.json Rees\Laracon. It may not be a huge change, but for me, it means that the sidebar on my editor is that little bit slimmer, and everything looks that a little neater.

Don't forget to add the trailing slashes to the namespace prefix, or Jordi will personally show up at your house with a baseball bat and a pair of pliers. Also don't forget to run composer update once you're done to update the namespace mapping, or I'll personally show up at your house with an army of cuddly pandas.

Well now we can start creating structure. I'll typically add in the directories that we know we're going to need. They mostly replicate that of what you see in most MVC frameworks.

src
- Commands
- Controllers
- Models

As you can see, we've already started to create groups for our class by function, but since we're using classes for all the things, let's go ahead and create more directories.

src
├── Commands
├── Controllers
├── Exceptions
├── Filters
├── Models
├── Observers
├── Providers
├── Repositories
├── Sanitizers
├── ServiceProviders
├── Services
├── Utility
└── Validators

Hopefully some of these directories might make sense, if they don't then don't worry about it. We'll get back to them later.

Right, our routes file has gone missing, hasn't it? What about the procedural style files where we register filters and observers and all that magic? Well truthfully you could do that within a service provider, and that's perfectly fine, we'll take a closer look at service providers later. However, these registrations are really simple, let's just create procedural files for them.

src
├── Commands
├── Controllers
├── Exceptions
├── Filters
├── Models
├── Observers
├── Providers
├── Repositories
├── Sanitizers
├── ServiceProviders
├── Services
├── Utility
├── Validators
├── composers.php
├── filters.php
├── observers.php
├── routes.php
└── services.php

Here we have a number of files for registering our own classes with the framework components. They'll likely be one liners. You'll noticed that I've added separate files for things like observer registrations, and view composers. Once again I like to group these registration by component or purpose. The services file is something that I half-inched from Symfony for quick container bindings. Anything more complex and I'll use a ServiceProvider (later).

These files won't work on their own though. We need to make Laravel aware of them. Remember the filters call from the global/start.php file? Well we can modify that line to reflect that route. I normally just use __DIR__ as a starting point.

For the rest of the files, you can either add more lines to global/start.php, or just link them from the original routes file, like this :

<?php

// Services are located within our /src directory.
require_once base_path().'/src/services.php';

// Routes are located within our /src directory.
require_once base_path().'/src/routes.php';

// Observers are located within our /src directory.
require_once base_path().'/src/observers.php';

// Helpers are located within our /src directory.
require_once base_path().'/src/helpers.php';

Here we've used the base_path() helper instead of __DIR__.

Right now, with all the rage on testing you're probably thinking WTF DAYLE WTF WHERE U PUT TESTS WTF IS GOON ON WTF.

Well I deleted the original tests folder, and I don't really want my tests mixed in with all my other code, since they'll likely contain classes that aren't namespaced.

What I like to do, is instead create a directory called tests right there next to the src and app directories. A lot of people want to group their test suites by type, so acceptance and unit and blah blah blah. That's fine and if that makes sense to you then go ahead and do it.

It might be different for my project because I don't really have a client as such, but I like to do things a little differently. All I really want is confidence in my code, to know its working, and to ensure that there's enough coverage that I know when something goes wrong during a monster refactor session (happens on a daily basis). I see a lot of people fighting over which testing suite is the best. I never really got that. Why not all? They are -dev dependencies so there's hardly a class loading overhead right? This means that my test directory looks a little like this.

tests
├── behat
├── codeception
└── phpunit

These are the three that I like to use. Behat is fantastic for BDD. I love the syntax of the features and it works really well. I've only started using it in the past 6 months or so and I'm a total convert.

Codeception does all the things, so it's not a bad idea to have it along for the ride. It's a great little framework. It can also run PHPUnit test-cases, but I keep them separate. Build time isn't a massive concern right now, who knows, this might change later. Project structures evolve along with your code.

Of course I will bootstrap all of these frameworks for use with Laravel, and create a build script to execute them all. My build script will normally run checkstyle, and mess detection, and generate api docs and that kinda thing as well. Well, I'm a sysada at heart so I normally use ant for build tools. It's simple and clean and I know the syntax well. I'll create a bunch of targets for running each individual test app or checkstyle or generation process in isolation. Then I'll add another target called test that will run all of those other targets as one clean process. This means that I can tell my CI environment to use ant and just run ant test to run all the things. Fail on everything, that's right, even checkstyle. Who cares, we run our build locally too, right?

It's getting closer to that time that we actually write some code isn't it? You'd probably be itching at this point. Well let me share a few little tips and tricks.

Let's start with this one.

BASE CLASS ALL THE THINGS

In each of those directories I will have a base class. Every single one. Every one of my classes will extend this base class, or I guess, another class that extends that base class. So here's an example of a Observer base class.

<?php

namespace Rees\Laracon\Observers;

abstract class BaseObserver
{

}

There, that's it. Nothing more. All of my observers will extend this class. I'm sure that one or two of you are thinking that I'm some sort of lunatic right now, but I'm getting kinda used to that feeling, so let's move on for a sec. Let's take a look at the base model, because that's a little different.

<?php

namespace Rees\Laracon\Models;

use Illuminate\Database\Eloquent\Model;

abstract class BaseModel extends Model
{

}

So we need to inherit some of the framework's goodies with this one. For that reason we bring in the Eloquent model class, and extend that.

If you're sitting there thinking 'Isn't the Laravel model called Eloquent?' then you're half right. The Eloquent that you normally extend is an alias to the Illuminate\Database\Eloquent\Model class, to make it a little easier for simple non-namespaced apps to get going quickly.

Now I don't normally use the aliases, because I'm a little stupid. You could if you like though, I guess that way if you change the target of the alias, the rest of your code will update. The alias is in the root namespace though, so you'll still need to bring it in. It looks like this:

<?php

namespace Rees\Laracon\Models;

use Eloquent;

class BaseModel extends Eloquent
{

}

This will work just fine.

So why bother right? Well I have a couple of reasons for using them. The best one is for overrides and shared things. Let's say you have the BaseModel above. Boss Landsman comes into the office and is all like...

"Our users are precious, we can't afford to delete any of their data, archive everything."

and you're all like.

"OH SNAP BOSS LANDSMAN, IT'S 6PM ON A FRIDAY, HOW AM I GONNA DO THAT?"

Well I guess you could use a soft delete right? So we update a timestamp on delete instead of removing the data. Now you're gonna have to update your migrations if you don't have that column, sorry guys, can't help you with that.

We also need to add that softDeletes property to all our models.

/**
 * Enable soft delete.
 *
 * @var boolean
 */
protected $softDelete = true;

Well you go ahead and do that. You know what I'm gonna do? I'm gonna add it to my base class. Yep. Done. So I can use my BaseClass to provide defaults for my own code. I can still override them again in the classes that extend the base classes if I want to, but at least I can change things 'globally' with ease.

If we find ourselves doing things more than once, we normally create a new component, or sometimes just pull that logic into a separate method that we can call to multiple times. Well you'll often find that this kind of repetition continues across all of your classes in the component directory. It's time for your BaseClass to step up and take that method like a man. Add it to your base class and suddenly it's available to all the other classes. A really quick way to add common functionality.

Now that we've shifted the structure of our application a little. You might have noticed that the shape of the app, is much more similar to that of a packagist package, or some kind of standalone bundle of code. The typical src, tests and bootstrap files.

.
├── app
├── artisan
├── bootstrap
├── composer.json
├── phpunit.xml
├── public
├── server.php
├── src
└── tests

The framework now doesn't have impact on the shape our application. It's just a toolkit that sits away from our code, there for us when we need it. Hell, if we were feeling psychotic and wanted to swap to another framework, compatible with the classes that we've created, we could probably just rip out the app (now config) and public directories, and replace with the new one. Don't do that though, you love Laravel, and it loves you too.

I keep mentioning that the app directory is now purely for configuration and bootstrapping of the framework. So if you'd like to call it something else, then go ahead. Just checkout the bootstrap/paths.php file.

/*
|--------------------------------------------------------------------------
| Application Path
|--------------------------------------------------------------------------
|
| Here we just defined the path to the application directory. Most likely
| you will never need to change this value as the default setup should
| work perfectly fine for the vast majority of all our applications.
|
*/

'app' => __DIR__.'/../app',

/*
|--------------------------------------------------------------------------
| Storage Path
|--------------------------------------------------------------------------
|
| The storage path is used by Laravel to store cached Blade views, logs
| and other pieces of information. You may modify the path here when
| you want to change the location of this directory for your apps.
|
*/

'storage' => __DIR__.'/../app/storage',

So these are the lines that you want to change to reflect the renaming of your app directory. Hell, if you wanna add your own path helper to access your src directory, well Laravel ain't gonna stop ya.

/*
|--------------------------------------------------------------------------
| Source Path
|--------------------------------------------------------------------------
|
| This is the path to the PAMH source folder. Sorry, but I couldn't bring
| myself to make this comment perfectly span three lines like Taylor
| does, so this will have to do. Oh wait, look! I managed it.
|
*/

'src' => __DIR__.'/../src',

The next section of my talk is dedicated to building your own toolset. As developers we created tools that people can use to make their lives easier. We should also be making tools to make our own lives easier, otherwise we are wasting time for our companies and clients.

Laravel provides a comprehensive tool-set to cater for many of a developers day to day needs. Extra third party packages will add in a lot more, and often you'll find a problem is already solved. However, when a tool is created, it has been constructed in its most basic form to be as useful to as many developers as can be. It's not taYlored for your application.

When the framework gives us lemons, we should make lemonade. Let's take the Validator for example. Most of you are familiar with using the validator from the controller or model in the following format.

// Get ALL the arrays.
$data       = Input::get();
$rules      = [ ... ];
$messages   = [ ... ];

// Create a validator.
$validator = Validator::make($rules, $data, $messages);

// Run semi-positive validation.
if (!$validator->passes()) {

    // Bail out.
    dd($validator->messages());
}

// OH SAY CAN YOU SEE..
$this->launchMissiles();

// Mwahahahaha.
$this->evilLaugh();

It's a great way to learn how the component works, and that's why teach it, but as a developer you should be able to wrap this component in a way that will avoid all the repetition.

For example, we're working an an API. With an API you often have create (POST) and update (PUT) actions. These sometimes require different validation sets, especially if you allow partial (PATCH) updates.

Here's what our validator looks like. So we have a class to represent the type of data we're validating. Normally something like PandaValidator. The class contains a protected multi dimensional array keyed by validation rule-set, with validation rules contained internally.

You can also provide a multi-dimensional messages array for extra/different validation messages. You can even provide an array of sanitizers, but we'll get to that later.

Here's how it looks to validate using our validators.

// Normally this would be injected.
$validator = new PandaValidator;

// Validate against the create ruleset.
if (!$validator->validate($data, 'create')) {

    // Bail out.
    dd("You can't fool me with your red painted cat!");
}

// ----------------------------------------------------

// We handle API errors with pretty messages using exceptions.
throw new ValidationFailedException($validator);

This is all accomplished using a clever BaseValidator here's the primary bit of magic.

public function validate($data, $ruleset = 'create')
{
    // We allow collections, so transform to array.
    if ($data instanceof Collection) {
        $data = $data->toArray();
    }

    // Execute sanitizers over the data before validation.
    $this->runSanitizers($data);

    // Load the correct ruleset.
    $rules = $this->rules[$ruleset];

    // Load the correct messageset.
    $messages = $this->messages[$ruleset];

    // Create the validator instance and validate.
    $validator = Validator::make($data, $rules, $messages);
    if (!$result = $validator->passes()) {
        $this->errors = $validator->messages();
    }

    // Return the validation result.
    return $result;
}

Don't worry about the sanitizers, but the rest should be pretty clear.

Finally, here's what our actual validator looks like. It's a fairly empty class, with some arrays specific to the validation of the current object type.

<?php

namespace Rees\Laracon\Validators;

use Rees\Laracon\Validators\BaseValidator;

class PandaValidator extends BaseValidator
{
    /**
     * Validation rules for this Validator.
     *
     * @var array
     */
    protected $rules = [

        'create' => [
            'first_field'   => ['required', 'min:3'],
            'second_field'  => ['required', 'min:3'],
            'third_field'   => ['required', 'min:3']
        ],

        'update' => [
            'first_field'   => ['min:3'],
            'second_field'  => ['min:3'],
            'third_field'   => ['min:3']
        ],

    ];
}

If we want to, we can provide an array of custom error messages, or even an array of sanitizers (soon) to run before validation. It means that we now have validation rule-sets specific to each type that we want to validate. Our validator classes are slim, and easy to create.

Okay then, let's take a look at sanitizers. When you take data from the user, and validate this data before storing it, it would be a shame to fail the validation because of a simple formatting error. For example, an API user has entered a credit card but provided dashes between the sets of digits. It's an easy error to make, and one that shouldn't require them to re-enter their payment details. For this reason we have included another custom component that we like to call a Sanitizer.

Sanitizers are classes which contain methods for transforming and filtering specific fields into a common format before validation occurs. In the example of the credit card field, we would strip spaces and non digit characters.

Here's our BaseSanitizer class.

<?php

namespace Rees\Laracon\Sanitizers;

abstract class BaseSanitizer
{
    /**
     * An array of sanitizer methods to be
     * executed.
     *
     * @var array
     */
    protected $sanitizers = [];

    /**
     * Trigger the sanitization process by
     * iterating the sanitizers array and
     * mutating our data array.
     *
     * @param  array $data
     * @return array
     */
    public function sanitize($data)
    {
        // Iterate all of the sanitizer methods.
        foreach ($this->sanitizers as $sanitizer) {
            $method = 'sanitize'.$sanitizer;
            // If the sanitization method exists, call it
            // to mutate our data set.
            if (method_exists($this, $method)) {
                $data = call_user_func([$this, $method], $data);
            }
        }
        return $data;
    }
}

We have an empty protected collection of sanitizer keys, and a sanitize method that will iterate these keys and attempt to execute the associated method on our validation data array.

Let's take a look at a class that implements this.

<?php

namespace Rees\Laracon\Sanitizers;

class UsersSanitizer extends BaseSanitizer
{
    /**
     * An array of sanitizer methods to be
     * executed.
     *
     * @var array
     */
    protected $sanitizers = ['Email'];

    /**
     * Sanitize an email address.
     *
     * @param  array $data
     * @return Rees\Laracon\Sanitizers\UserSanitizer
     */
    public function sanitizeEmail($data)
    {
        if (isset($data['email'])) {
            $data['email'] = strtolower($data['email']);
        }
        return $this;
    }
}

So here we have a Sanitizer class for a user data array. It contains a single method that is used to convert the users email address to a lowercase value. Here we aren't using the sanitizer to protect the data against validation failure, but instead to standardize the presentation of this field within our database.

This is a great time to mention how custom tool-sets, much like your application code itself will evolve over time. The sanitizer class that you see above was the original version of the sanitizer that was used on our project. Over time, it became apparent that we would like a much finer level of control to our sanitization system.

I chose to emulate some of the frameworks own functionality to bring consistency to the project. For example, here you would bind a sanitization key to a class and method pair, much like you would defining a custom filter in Laravel or binding a route in the routing system to a controller and action. Here's what it looks like.

Sanitizer::register('strtolower', 'Rees\\Laracon\\Sanitizers\\GenericSanitizer@lower');

Of course, I add a new file called sanitizers.php to the root of my source directory to allow for the registration of additional sanitizers.

Now my validation class can contain an array of fields to sanitizer(s). Here's a quick example.

protected $sanitizers = [
    'email'             => ['strtolower', 'trim'],
    'username'          => ['strtolower', 'trim']
];

We could later expand our sanitizer component to automatically call global functions by name, and other neat tricks to fulfil the requirements of our project.

Here's one of my favourite components that we've added to the project. The seeder. Yes, yes. I know that Laravel comes with its own seeding engine. It's for that reason that I built my solution with the extra requirements for my project on top of the original seeding engine. Use what's already there as a foundation for building your own tool-kit.

First let's consider the requirements. We're building an API, and we'd like to perform acceptance tests to emulate the way that our clients would interact with the API end points. Now, we could have shaped our system using repositories and mock them within tests with using internal redirection to see what result we get back, but that seems like a lot of hassle. We'd like our testing to be clean and consistent. We want it to be convenient so that we can easily add more tests.

It's for this reason that we've gone with a seeded test database. We don't need to use internal redirection, because we can use a Behat context file to hit the API directly on port 80 (or 8080 as I have it with vagrant) to act in an identical manner to our clients.

I'm using a Behat context that makes use of Guzzle to correct directly to the API? Why am I saying this? Because I wanted to mention that I'm using a context that was originally created by Phil Sturgeon, and then modified to suit the needs of our project. It re-iterates the idea of building upon the framework components, but this time borrowing a piece of open source magic from another developer, and extending it to allow for the requirements of our project.

Let's take a look at a seeder now.

<?php

namespace Rees\Laracon\Seeders;

use Hash;

class UsersSeeder extends BaseSeeder
{
    /**
     * The name of the table to seed.
     *
     * @var string
     */
    protected $table = 'users';

    /**
     * A multi-dimensional array of seeds.
     *
     * @var array
     */
    protected $seeds = [
        [
            'first_name'    => 'Dayle',
            'last_name'     => 'Rees',
        ],
        [
            'first_name'    => 'James',
            'last_name'     => 'Johns',
        ],
    ];

    /**
     * Add fake data to a seed.
     *
     * @param  Faker\Generator  $faker
     * @return mixed
     */
    protected function fake($faker)
    {
        $date = $faker->dateTimeThisYear()->format('Y-m-d H:i:s');
        return [
            'first_name'                => $faker->firstName,
            'last_name'                 => $faker->lastName,
            'email'                     => $faker->email,
            'password'                  => implode('-', $faker->words(3)),
            'reset_token'               => md5($faker->randomNumber),

            'created_at' => $date,
            'updated_at' => $date,
        ];
    }

    /**
     * Override to modify data before saving.
     *
     * @param  array $seed
     * @return array
     */
    protected function modify($seed)
    {
        // For the users seeder only, hash the password.
        $seed['password'] = Hash::make($seed['password']);
        return $seed;
    }
}

First let's look at the fake() method. What this method does is construct an entirely fake record using the wonderful 'Faker' library. It will result in an array representing an object with dummy data, but somewhat believable.

You'll also so the modify() method below. This isn't required, and is a little bit of a special case for the UserSeeder but it will simply hash all provided passwords before inserting into the database.

When the seeder is executed, it will generate 25 fake records, and chunk insert them into the table defined within the $table property.

Don't want 25? Not a problem, we can simply override the protected $amount integer with a new value.

Here's the clever part. Random data is great, it will fill up our database nicely. It's not great to test against though. Luckily our instance of faker has been bootstrapped with a seed number, so that it will always generate randomly in the same way... so I guess, not randomly at all then. Oh well.

The issue is, sometimes we want to hard code data within our seeded database, or fix relationships to certain keys. It's for this reason that the protected $seeds array exists. Take another look.

$seeds is a multi dimensional array containing sets of FIXED seeds. With data that is more real to us and less random. These seeds will be inserted first, and the remainder of the records will be faked up to the '$amount' parameter. In a way, you could say the real and fake seed sets are merged up to the maximum amount.

Not only that, but any fields that aren't defined in the fixed seeds, will be replaced by randomly generated content using the blueprint in the fake method. This means that the fixed seed is merged with our fake seed, and has a higher priority.

Now I have to be truthfully honest. The whole reason that I created the fixed mechanism is because I didn't originally spot the random seed functionality of faker. Someone told me on twitter and I had a head-desk moment.

Fortunately, it turns out that because even the expected random figures are generated in order, if you were to add an extra field into the blueprint, then the order would shift and the data would be completely different.

This would ruin our test suite, so luckily we only test against records that have been seeded fixed. The last feature that I've added to our custom seed component, is one or two helpers for seeding relationships. The class has access to two additional methods:

$this->uniqueKey('table_name');
$this->randomKey('table_name');

The uniqueKey method will return a unique primary key value from the table specified. This is useful for ensuring that a table record is not related twice. By passing an array of field names as a second parameter, it will also check the fixed seed array with those fields to ensure that no conflicts occur.

The second method will simply return an entirely random key from the provided table. These ID's may repeat.

Internally, these methods use the faker randomElement() method to pick from the available keys. This means that unless we change the order of seed generation. It will always seed the same way.

As a final tool, I'd like to present the Provider. This isn't related to the ServiceProvider but it seemed like the most suitable name for its purpose.

Sometimes in your applications, you end up using large key value arrays of useful data, but it might not be dynamic. For this reason, storing it in the database seems a little redundant. It's only likely to change along with a code push. For these times we invented the Provider.

It's a class that contains a key value array. I know, I know, that doesn't sound very exciting. Go ahead, take a look.

<?php

namespace Rees\Laracon\Providers;

class CurrencySymbolsProvider extends BaseProvider
{
    /**
     * Default currency.
     *
     * @var string
     */
    protected static $defaultValue = 'GBP';

    /**
     * Map of currency symbols.
     *
     * @var array
     */
    protected static $data = [
        'USD' => '$',
        'GBP' => '£',
        'CAD' => 'CA $',
        'NZD' => 'NZ $',
        'AUD' => 'AU $',
        'EUR' => '€',
        'TRY' => 'TRY',
        'NOK' => 'kr',
        'SEK' => 'kr',
        'DKK' => 'kr',
        'ILS' => '₪',
    ];
}

So in our class we have two static properties. As you can see, the second $data property is the one that contains our internal key value array.

So why the provider? Well we like Laravel or rather, Illuminate collections. They are fantastic, lots of little helper methods. Using our base class we can call..

CurrencySymbolsProvider::make();

.. to retrieve the array wrapped in a collection. Now we have access to all those wonderful methods that you're used to with your Eloquent result collections for example.

We also have access to quick methods such as get() to pluck out a single value using dot.notation for when the array is nested.

You may have noticed the $default property. This is because we realised that these kinds of classes are great for the data that might be used to seed a dropdown. For this reason we have the default() method which will use the property to pull a default value from the array.

Well, we've taken a look at a few components now. Let's take at another look at an element of project structure. The event.

There are times in our application that we like to log things. I know, I know there's a log method for that. I'm actually talking about logging for statistical purpose. Or even to queue a notification email for sending.

I feel like this kind of thing greatly interrupts the flow of the application. In terms of statistical logging, you may not want to worry about pushing stats out to an external service while you're writing the code for creating a new user.

For this reason I love to use events.

I normally place an event where something constructive, or a noticeable change has happened in the code that I'm writing. Here's an example.

// Get the payment method.
$method = PaymentMethod::find($methodId);

// Fetch the stripe service.
$stripe = App::make('stripe');

// Charge the payment method 30 whatevers.
$payment = $stripe->charge(30.00, $method);

// Notify listeners of payment.
Event::fire('payments.method_charged', [$method, $payment]);

Here, once the users card has been charged, we fire an event called payments.method_charged. We also provide any useful objects or values, in this case the payment method, and the object representing the result of a payment.

Even if I don't have any plans to act upon this action. I'll still add the event. It's one of those circumstances where I easily prefer flexibility over the minimal performance gain.

So why is it flexible?

Well the big boss man has suddenly decided that when we charge a user we should send them an invoice. I know right, the cheek. It wasn't in the original spec, talk about scope creep.

After billing the boss man for 5k you start to implement this new feature. Without the event that we'd placed earlier. You'd have to go back into the payment model, and litter your model code with notification code to queue and later send an email. It can quickly create mess, and in honesty, I like to keep both logging and notification away from my core logic.

With the event in place we just create a new observer class.

<?php

namespace Rees\Laracon\Observers;

class PaymentsInvoiceObserver extends BaseObserver
{
    public function reportPayment()
    {
        // Report payment to fancy financial
        // analytical sass thing they are paying
        // a lot of money for.
    }

    public function sendInvoice()
    {
        // Create invoice and queue an email
        // to send it to the customer.
    }
}

// --------- observers.php --------------

Event::listen('payments.method_charge', 'Rees\\Laracon\\Observers\\PaymentsInvoiceObserver@reportPayment');
Event::listen('payments.method_charge', 'Rees\\Laracon\\Observers\\PaymentsInvoiceObserver@sendInvoice');

To me this is a much cleaner way of handling notification and logging logic.

The last piece to the puzzle when breaking the mould, is the ServiceProvider.

If you've come across the ServiceProvider before, then it was likely during the process of integrating a third party component or tool.

The instructions would tell you to add the package to composer.json. Run a composer update, and then add the the component's service provider to the array in your app/config/app.php configuration file.

So what does that class do? Why is it so important that we add it? Well you see, the ServiceProvider is your code, or package's entry point into the framework.

It allows your to jump in during the frameworks bootstrapping process and do your own thing. It gives you full access to the heart of Laravel which is the $app object. Essentially, a special instance of the illuminate container that's used to hold the whole framework together.

Let's take a look at an empty service provider.

<?php

namespace Rees\Laracon\ServiceProviders;

use Illuminate\Support\ServiceProvider;

class EmptyServiceProvider extends ServiceProvider
{
    public function register()
    {

    }
}

Now I know that I normally have my own base class, but this time I left the Illuminate service provider class in for clarity.

We can use the register() method, which is called late into the framework bootstrapping, to do anything we want. In this occurrence, let's create an imaginary stripe service.

Try to pretend that there aren't 234234234 stripe packages for Laravel, and that we want to integrate their PHP SDK instead. The PHP SDK isn't tied to any particular framework, so it doesn't have a service provider.

We could instantiate our stripe connection instance in the logic portion of the app, pulling back the stripe credentials from a configuration file.

Sure, we could do this, but if we had to use stripe in multiple 'locations' within our system, it would become quite tiring. It would be much better to create that connection only once, the first time that it's needed.

Let's first write the connection code.

<?php

namespace Rees\Laracon\ServiceProviders;

use Config;
use Stripe\Client;
use Illuminate\Support\ServiceProvider;

class EmptyServiceProvider extends ServiceProvider
{
    public function register()
    {
        // Get the API token from config.
        $token = Config::get('stripe.token');

        // Create the stripe client.
        $client = Client($token);
    }
}

Okay, so we've created a client. Where should we put it? Well we're told it's good to keep things in the container right? It's the best place to hold things, we can do all kinds of things like swap items held in the container later for testing or extension of components.

The abstract service provider has the main application provider set to $this->app at construction, so it's easy to access from our service providers which extend it.

Let's use that container instance to place the client in the container.

<?php

namespace Rees\Laracon\ServiceProviders;

use Config;
use Stripe\Client;
use Illuminate\Support\ServiceProvider;

class StripeServiceProvider extends ServiceProvider
{
    public function register()
    {
        // Get the API token from config.
        $token = Config::get('stripe.token');

        // Create the stripe client.
        $client = new Client($token);

        // Bind the client into the container.
        $this->app['stripe'] = $client;
    }
}

Great! Well not quite great. You see the issue here is that register method is called every time for every request, and every time the framework is bootstrapped.

This means that pulling the configuration, creating the client (which may indeed check the connection status) is going to happen at startup, halting all other code.

We don't want that really. I mean, the framework might be routing to some logic that doesn't even need stripe. Maybe the client has requested POST /login. We don't need stripe there, but it's still going to be constructed, and it might take that time to ensure the client has a connection.

This is bad practice. We only really want the stripe service when we intend to use it. So how can we solve this problem? Let's take a look.

<?php

namespace Rees\Laracon\ServiceProviders;

use Config;
use Stripe\Client;
use Illuminate\Support\ServiceProvider;

class StripeServiceProvider extends ServiceProvider
{
    public function register()
    {
        // Bind the client into the container.
        $this->app['stripe'] = $this->app->share(function () {

            // Get the API token from config.
            $token = Config::get('stripe.token');

            // Create the stripe client.
            return new Client($token);
        });
    }
}

That's much better. Let's work through this. Right in the middle you'll see that we're creating the client within a Closure, which returns the client instance.

This closure is handed to the share() method on our application instance, which is then bound within the application container.

Share is a clever method, it will execute the closure only once. Caching the result for the next time it is requested. The closure will only be executed the first time that you attempt to resolve stripe from the container. Something like this:

$stripe = App::make('stripe');

Now stripe is only being created when it's needed, and the same client will be resolved every time it is requested.

There's one final tweak that we could make to this provider, but it's only really needed if you are writing a provider for a re-distributable package. You see that use of the Config class? Well because we have use Config; at the top of the class it means that we are using the Config facade alias which is located in the root namespace.

If someone pulls our redist package into their project, and they have removed the alias, or pointed it to something else, then we'd be stuffed. We can get around this by using the $this->app instance again. Most of the Laravel components are placed in the container, even the configuration component. We just need to be able to access it by key.

Finding the key is fairly simple, if we take a look at the framework codebase, you can find a components key either in its service provider, or the Facade, as identified by the this line:

protected static function getFacadeAccessor() { return 'config'; }

Now that we know the key is config all we need to do is access it directly from within the application instance, like this.

<?php

namespace Rees\Laracon\ServiceProviders;

use Stripe\Client;
use Illuminate\Support\ServiceProvider;

class StripeServiceProvider extends ServiceProvider
{
    public function register()
    {
        $app = $this->app;

        // Bind the client into the container.
        $this->app['stripe'] = $this->app->share(function () use ($app) {

            // Get the API token from config.
            $token = $app['config']->get('stripe.token');

            // Create the stripe client.
            return new Client($token);
        });
    }
}

Now we have no dependencies on the Config facade.

Well I guess I didn't add my closing statement to the talk? Well I guess next time you're gonna have to come and see me in person!

Thanks for listening guys!