Newer posts are loading.
You are at the newest post.
Click here to check if anything new just came in.

January 28 2014

14:00

Setting Up a Local Mirror for Composer Packages With Satis

Installing all your PHP libraries with Composer is a great way to save time. But larger projects automatically tested and run at each commit to your software version control (SVC) system will take a long time to install all the required packages from the Internet. You want to run your tests as soon as possible through your continuous integration (CI) system so that you have fast feedback and quick reactions on failure. In this tutorial we will set up a local mirror to proxy all your packages required in your project’s composer.json file. This will make our CI work much faster, install the packages over the local network or even hosted on the same machine, and make sure we have the specific versions of the packages always available.


What Is Satis?

Satis is the name of the application we will use to mirror the various repositories for our project. It sits as a proxy between the Internet and your composer. Our solution will create a local mirror of a few packages and instruct our composer to use it instead of the sources found on the Internet.

Here is an image that says more than a thousand words.

Architecture

Our project will use composer as usual. It will be configured to use the local Satis server as the primary source. If a package is found there, it will be installed from there. If not, we will let composer use the default packagist.org to retrieve the package.


Getting Satis

Satis is available through composer, so installing it is very simple. In the attached source code archive, you will find Satis installed in the Sources/Satis folder. First we will install composer itself.

$ curl -sS https://getcomposer.org/installer | php
#!/usr/bin/env php All settings correct for using Composer Downloading...
 Composer successfully installed to: /home/csaba/Personal/Programming/NetTuts/Setting up a local mirror for Composer packages with Satis/Sources/Satis/composer.phar Use it: php composer.phar

Then we will install Satis.

$ php composer.phar create-project composer/satis --stability=dev --keep-vcs Installing composer/satis (dev-master eddb78d52e8f7ea772436f2320d6625e18d5daf5)
  - Installing composer/satis (dev-master master)
    Cloning master
 Created project in /home/csaba/Personal/Programming/NetTuts/Setting up a local mirror for Composer packages with Satis/Sources/Satis/satis Loading composer repositories with package information Installing dependencies (including require-dev) from lock file
  - Installing symfony/process (dev-master 27b0fc6)
    Cloning 27b0fc645a557b2fc7bc7735cfb05505de9351be

  - Installing symfony/finder (v2.4.0-BETA1)
    Downloading: 100%

  - Installing symfony/console (dev-master f44cc6f)
    Cloning f44cc6fabdaa853335d7f54f1b86c99622db518a

  - Installing seld/jsonlint (1.1.1)
    Downloading: 100%

  - Installing justinrainbow/json-schema (1.1.0)
    Downloading: 100%

  - Installing composer/composer (dev-master f8be812)
    Cloning f8be812a496886c84918d6dd1b50db5c16da3cc3

  - Installing twig/twig (v1.14.1)
    Downloading: 100%
 symfony/console suggests installing symfony/event-dispatcher () Generating autoload files

Configuring Satis

Satis is configured by a JSON file very similar to composer. You can use whatever name you want for your file and specify it for usage later. We will use “mirrored-packages.conf“.

{
    "name": "NetTuts Composer Mirror",
    "homepage": "http://localhost:4680",

    "repositories": [
        { "type": "vcs", "url": "https://github.com/SynetoNet/monolog" },
        { "type": "composer", "url": "https://packagist.org" }
    ],

    "require": {
        "monolog/monolog": "syneto-dev",
        "mockery/mockery": "*",
        "phpunit/phpunit": "*"
    },
    "require-dependencies": true
}

Let’s analyze this configuration file.

  • name – represents a string that will be shown on the web interface of our mirror.
  • homepage – is the web address where our packages will be kept. This does not tell our web server to use that address and port, it is rather just information of a working configuration. We will set up the access to it on that addres and port later.
  • repositories – a list of repositories ordered by preference. In our example, the first repository is a Github fork of the monolog logging libraries. It has some modifications and we want to use that specific fork when installing monolog. The type of this repository is “vcs“. The second repository is of type “composer“. Its URL is the default packagist.org site.
  • require – lists the packages we want to mirror. It can represent a specific package with a specific version or branch, or any version for that matter. It uses the same syntax as your “require” or “require-dev” in your composer.json.
  • require-dependencies – is the final option in our example. It will tell Satis to mirror not only the packages we specified in the “require” section but also all their dependencies.

To quickly try out our settings we first need to tell Satis to create the mirrors. Run this command in the folder where you installed Satis.

$ php ./satis/bin/satis build ./mirrored-packages.conf ./packages-mirror Scanning packages Writing packages.json Writing web view

While the process is taking place, you will see how Satis mirrors each found version of the required packages. Be patient it may take a while to build all those packages.

Satis requires that date.timezone to be specified in the php.ini file, so make sure it is and set to your local timezone. Otherwise an error will appear.

[Twig_Error_Runtime]
  An exception has been thrown during the rendering of a template
("date_default_timezone_get(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set) function. 

Then we can run a PHP server instance in our console pointing to the recently created repository. PHP 5.4 or newer is required.

$ php -S localhost:4680 -t ./packages-mirror/ PHP 5.4.22-pl0-gentoo Development Server started at Sun Dec  8 14:47:48 2013 Listening on http://localhost:4680 Document root is /home/csaba/Personal/Programming/NetTuts/Setting up a local mirror for Composer packages with Satis/Sources/Satis/packages-mirror Press Ctrl-C to quit.
[Sun Dec  8 14:48:09 2013] 127.0.0.1:56999 [200]: /
[Sun Dec  8 14:48:09 2013] 127.0.0.1:57000 [404]: /favicon.ico - No such file or directory

And we can now browse our mirrored packages and even search for specific ones by pointing our web browser to http://localhost:4680:

MirrorWebpage

Let’s Host It on Apache

If you have a running Apache at hand, creating a virtual host for Satis will be quite simple.

Listen 4680

<Directory "/path/to/your/packages-mirror"> Options -Indexes FollowSymLinks AllowOverride all Order allow,deny Allow from all
</Directory>

<VirtualHost *:4680> DocumentRoot "/path/to/your/packages-mirror" ServerName 127.0.0.1:4680 ServerAdmin admin@example.com
 ErrorLog syslog:user

</VirtualHost>

We just use a .conf file like this, put in Apache’s conf.d folder, usually /etc/apache2/conf.d. It creates a virtual host on the 4680 port and points it to our folder. Of course you can use whatever port you want.


Updating Our Mirrors

Satis can not automatically update the mirrors unless we tell it. So the easiest way, on any UNIX like system, is to just add a cron job to your system. That would be very easy, and just a simple script to execute our update command.

#!/bin/bash php /full/path/to/satis/bin/satis build \
/full/path/to/mirrored-packages.conf \
/full/path/to/packages-mirror

The drawback of this solution is that it is static. We have to manually update the mirrored-packages.conf every time we add another package to our project’s composer.json. If you are part of a team in a company with a big project and a continuous integration server, you can’t rely on people remembering to add the packages on the server. They may not even have permissions to access the CI infrastructure.


Dynamically Updating Satis Configuration

It’s time for a PHP TDD exercise. If you just want your code ready and running, check out the source code attached to this tutorial.

require_once __DIR__ . '/../../../../vendor/autoload.php';
 class SatisUpdaterTest extends PHPUnit_Framework_TestCase {
    function testBehavior() {
        $this->assertTrue(true);
    }
}

As usual we start with a degenerative test, just enough to make sure we have a working testing framework. You may notice that I have quite a strange looking require_once line, this is because I want to avoid having to reinstall PHPUnit and Mockery for each small project. So I have them in a vendor folder in my NetTuts‘ root. You should just install them with composer and drop the require_once line altogether.

class SatisUpdaterTest extends PHPUnit_Framework_TestCase {
	function testDefaultConfigFile() {
		$expected = '{
    "name": "NetTuts Composer Mirror",
    "homepage": "http://localhost:4680",

    "repositories": [
        { "type": "vcs", "url": "https://github.com/SynetoNet/monolog" },
        { "type": "composer", "url": "https://packagist.org" }
    ],

    "require": {
    },
    "require-dependencies": true
}';
		$actual = $this->parseComposerConf('');
		$this->assertEquals($expected, $actual);
	}
}

That looks about right. All the fields except “require” are static. We need to generate only the packages. The repositories are pointing to our private git clones and to packagist as needed. Managing those is more of a sysadmin job than a software developer’s.

Of course this fails with:

PHP Fatal error:  Call to undefined method SatisUpdaterTest::parseComposerConf()

Fixing that is easy.

private function parseComposerConf($string) {
}

I just added an empty method with the required name, as private, to our test class. Cool, but now we have another error.

PHPUnit_Framework_ExpectationFailedException : Failed asserting that null matches expected '{ ... }'

So, null does not match our string containing all that default configuration.

private function parseComposerConf($string) {
    return '{
"name": "NetTuts Composer Mirror",
"homepage": "http://localhost:4680",

"repositories": [
    { "type": "vcs", "url": "https://github.com/SynetoNet/monolog" },
    { "type": "composer", "url": "https://packagist.org" }
],

"require": {
},
"require-dependencies": true
}';
}

OK, that works. All tests are passing.

PHPUnit 3.7.28 by Sebastian Bergmann. Time: 15 ms, Memory: 2.50Mb OK (1 test, 1 assertion)

But we introduced a horrible duplication. All that static text in two places, written character by character in two different places. Let’s fix it:

class SatisUpdaterTest extends PHPUnit_Framework_TestCase {
	static $DEFAULT_CONFIG = '{
    "name": "NetTuts Composer Mirror",
    "homepage": "http://localhost:4680",

    "repositories": [
        { "type": "vcs", "url": "https://github.com/SynetoNet/monolog" },
        { "type": "composer", "url": "https://packagist.org" }
    ],

    "require": {
    },
    "require-dependencies": true
}';

	function testDefaultConfigFile() {
		$expected =  self::$DEFAULT_CONFIG;

		$actual = $this->parseComposerConf('');
		$this->assertEquals($expected, $actual);
	}

	private function parseComposerConf($string) {
		return self::$DEFAULT_CONFIG;
	}
}

Ahhh! That’s better.

	function testEmptyRequiredPackagesInComposerJsonWillProduceDefaultConfiguration() {
    $expected = self::$DEFAULT_CONFIG;

    $actual = $this->parseComposerConf('{"require": {}}');
    $this->assertEquals($expected, $actual);
}

Well. That also passes. But it also highlights some duplication and useless assignment.

	function testDefaultConfigFile() {
    $actual = $this->parseComposerConf('');
    $this->assertEquals(self::$DEFAULT_CONFIG, $actual);
}
 function testEmptyRequiredPackagesInComposerJsonWillProduceDefaultConfiguration() {
    $actual = $this->parseComposerConf('{"require": {}}');
    $this->assertEquals(self::$DEFAULT_CONFIG, $actual);
}

We inlined the $expected variable. $actual could also be inlined, but I like it better this way. It keeps the focus on what is tested.

Now we have another problem. The next test I want to write would look like this:

function testARequiredPackageInComposerWillBeInSatisAlso() {
    $actual = $this->parseComposerConf(
    '{"require": {
        "Mockery/Mockery": ">=0.7.2"
    }}');
    $this->assertContains('"Mockery/Mockery": ">=0.7.2"', $actual);
}

But after writing the simple implementation, we will notice it requires json_decode() and json_encode(). And of course these functions reformat our string and matching strings will be difficult at best. We have to take a step back.

function testDefaultConfigFile() {
    $actual = $this->parseComposerConf('');
    $this->assertJsonStringEqualsJsonString($this->jsonRecode(self::$DEFAULT_CONFIG), $actual);
}
 function testEmptyRequiredPackagesInComposerJsonWillProduceDefaultConfiguration() {
    $actual = $this->parseComposerConf('{"require": {}}');
    $this->assertJsonStringEqualsJsonString($this->jsonRecode(self::$DEFAULT_CONFIG), $actual);
}
 private function parseComposerConf($jsonConfig) {
    return $this->jsonRecode(self::$DEFAULT_CONFIG);
}
 private function jsonRecode($json) {
    return json_encode(json_decode($json, true));
}

We changed our assertion method to compare JSON strings and we also recoded our $actual variable. ParseComposerConf() was also modified to use this method. You will see in a moment how it helps us. Our next test becomes more JSON specific.

function testARequiredPackageInComposerWillBeInSatisAlso() {
    $actual = $this->parseComposerConf(
        '{"require": {
            "Mockery/Mockery": ">=0.7.2"
        }}');
    $this->assertEquals('>=0.7.2', json_decode($actual, true)['require']['Mockery/Mockery']);
}

And making this test pass, along with the rest of the tests, is quite easy, again.

private function parseComposerConf($jsonConfig) {
    $addedConfig = json_decode($jsonConfig, true);
    $config = json_decode(self::$DEFAULT_CONFIG, true);
    if (isset($addedConfig['require'])) {
        $config['require'] = $addedConfig['require'];
    }
    return json_encode($config);
}

We take the input JSON string, decode it, and if it contains a “require” field we use that in our Satis configuration file instead. But we may want to mirror all versions of a package, not just the last one. So maybe we want to modify our test to check that the version is “*” in Satis, regardless of what exact version is in composer.json.

function testARequiredPackageInComposerWillBeInSatisAlso() {
    $actual = $this->parseComposerConf(
        '{"require": {
            "Mockery/Mockery": ">=0.7.2"
        }}');
    $this->assertEquals('*', json_decode($actual, true)['require']['Mockery/Mockery']);
}

That obviously fails with a cool message:

PHPUnit_Framework_ExpectationFailedException : Failed asserting that two strings are equal. Expected :* Actual   :>=0.7.2

Now, we need to actually edit our JSON before re-encoding it.

private function parseComposerConf($jsonConfig) {
    $addedConfig = json_decode($jsonConfig, true);
    $config = json_decode(self::$DEFAULT_CONFIG, true);
    $config = $this->addNewRequires($addedConfig, $config);
    return json_encode($config);
}
 private function toAllVersions($config) {
    foreach ($config['require'] as $package => $version) {
        $config['require'][$package] = '*';
    }
    return $config;
}
 private function addNewRequires($addedConfig, $config) {
    if (isset($addedConfig['require'])) {
        $config['require'] = $addedConfig['require'];
        $config = $this->toAllVersions($config);
    }
    return $config;
}

To make the test pass we have to iterate over each element of the required packages array and set their version to ‘*’. See method toAllVersion() for more details. And to speed up this tutorial a little bit, we also extracted some private methods in the same step. This way, parseComoserConf() becomes very descriptive and easy to understand. We could also inline $config into the arguments of addNewRequires(), but for aesthetic reasons I left it on two lines.

But what about “require-dev” in composer.json?

function testARquiredDevPackageInComposerWillBeInSatisAlso() {
    $actual = $this->parseComposerConf(
        '{"require-dev": {
            "Mockery/Mockery": ">=0.7.2",
            "phpunit/phpunit": "3.7.28"
        }}');
    $this->assertEquals('*', json_decode($actual, true)['require']['Mockery/Mockery']);
    $this->assertEquals('*', json_decode($actual, true)['require']['phpunit/phpunit']);
}

That obviously fails. We can make it pass with just copy/pasting our if condition in addNewRequires():

private function addNewRequires($addedConfig, $config) {
    if (isset($addedConfig['require'])) {
        $config['require'] = $addedConfig['require'];
        $config = $this->toAllVersions($config);
    }
    if (isset($addedConfig['require-dev'])) {
        $config['require'] = $addedConfig['require-dev'];
        $config = $this->toAllVersions($config);
    }
    return $config;
}

Yep, that makes it pass, but those duplicated if statements are nasty looking. Let’s deal with them.

private function addNewRequires($addedConfig, $config) {
    $config = $this->addRequire($addedConfig, 'require', $config);
    $config = $this->addRequire($addedConfig, 'require-dev', $config);
    return $config;
}
 private function addRequire($addedConfig, $string, $config) {
    if (isset($addedConfig[$string])) {
        $config['require'] = $addedConfig[$string];
        $config = $this->toAllVersions($config);
    }
    return $config;
}

We can be happy again, tests are green and we refactored our code. I think only one test is left to be written. What if we have both “require” and “require-dev” sections in composer.json?

function testItCanParseComposerJsonWithBothSections() {
    $actual = $this->parseComposerConf(
        '{"require": {
            "Mockery/Mockery": ">=0.7.2"
            },
        "require-dev": {
            "phpunit/phpunit": "3.7.28"
        }}');
    $this->assertEquals('*', json_decode($actual, true)['require']['Mockery/Mockery']);
    $this->assertEquals('*', json_decode($actual, true)['require']['phpunit/phpunit']);
}

That fails because the packages set by “require-dev” will overwrite those of “require” and we will have an error:

Undefined index: Mockery/Mockery

Just add a plus sign to merge the arrays, and we are done.

private function addRequire($addedConfig, $string, $config) {
    if (isset($addedConfig[$string])) {
        $config['require'] += $addedConfig[$string];
        $config = $this->toAllVersions($config);
    }
    return $config;
}

Tests are passing. Our logic is finished. All we left to do is to extract the methods into their own file and class. The final version of the tests and the SatisUpdater class can be found in the attached source code.

We can now modify our cron script to load our parser and run it on our composer.json. This will be specific to your projects’ particular folders. Here is an example you can adapt to your system.

#!/usr/local/bin/php

<?php require_once __DIR__ . '/Configuration.php';

$outputDir = '/path/to/your/packages-mirror';
$composerJsonFile = '/path/to/your/projects/composer.json';
$satisConf = '/path/to/your/mirrored-packages.conf';

$satisUpdater = new SatisUpdater();
$conf = $satisUpdater->parseComposerConf(file_get_contents($composerJsonFile)); file_put_contents($satisConf, $conf);
 system(sprintf('/path/to/satis/bin/satis build %s %s', $satisConf, $outputDir), $retval); exit($retval);

Making Your Project Use the Mirror

We talked about a lot of things in this article, but we did not mention how we will instruct our project to use the mirror instead of the Internet. You know, the default is packagist.org? Unless we do something like this:

   "repositories": [
        {
            "type": "composer",
            "url": "http://your-mirror-server:4680"
        }
    ],

That will make your mirror the first choise for composer. But adding just that into the composer.json of your project will not disable access to packagist.org. If a package can not be found on the local mirror, it will be downloaded from the Internet. If you wish to block this feature, you may also want to add the following line to the repositories section above:

"packagist": false

Final Thoughts

That’s it. Local mirror, with automatic adapting and updating packages. Your colleagues will never have to wait a long time while they or the CI server installs all the requirements of your projects. Have fun.

January 24 2014

19:37

SOLID: Part 3 – Liskov Substitution & Interface Segregation Principles

The Single Responsibility (SRP), Open/Closed (OCP), Liskov Substitution, Interface Segregation, and Dependency Inversion. Five agile principles that should guide you every time you write code.

Because both the Liskov Substitution Principle (LSP) and the Interface Segregation Principle (ISP) are quite easy to define and exemplify, in this lesson we will talk about both of them.


Liskov Substitution Principle (LSP)

Child classes should never break the parent class’ type definitions.

The concept of this principle was introduced by Barbara Liskov in a 1987 conference keynote and later published in a paper together with Jannette Wing in 1994. Their original definition is as follows:

Let q(x) be a property provable about objects x of type T. Then q(y) should be provable for objects y of type S where S is a subtype of T.

Later on, with the publication of the SOLID principles by Robert C. Martin in his book Agile Software Development, Principles, Patterns, and Practices and then republished in the C# version of the book Agile Principles, Patterns, and Practices in C#, the definition became known as the Liskov Substitution Principle.

This leads us to the definition given by Robert C. Martin:

Subtypes must be substitutable for their base types.

As simple as that, a subclass should override the parent class’ methods in a way that does not break functionality from a client’s point of view. Here is a simple example to demonstrate the concept.

class Vehicle {

	function startEngine() {
		// Default engine start functionality
	}

	function accelerate() {
		// Default acceleration functionality
	}
}

Given a class Vehicle – it may be abstract – and two implementations:

class Car extends Vehicle {

	function startEngine() {
		$this->engageIgnition();
		parent::startEngine();
	}

	private function engageIgnition() {
		// Ignition procedure
	}

}

class ElectricBus extends Vehicle {

	function accelerate() {
		$this->increaseVoltage();
		$this->connectIndividualEngines();
	}

	private function increaseVoltage() {
		// Electric logic
	}

	private function connectIndividualEngines() {
		// Connection logic
	}

} 

A client class should be able to use either of them, if it can use Vehicle.

class Driver {
	function go(Vehicle $v) {
		$v->startEngine();
		$v->accelerate();
	}
} 

Which leads us to a simple implementation of the Template Method Design Pattern as we used it in the OCP tutorial.

template_method

Based on our previous experience with the Open/Closed Principle, we can conclude that Liskov’s Substitution Principle is in strong relation with OCP. In fact, “a violation of LSP is a latent violation of OCP” (Robert C. Martin), and the Template Method Design Pattern is a classic example of respecting and implementing LSP, which in turn is one of the solutions to respect OCP also.


The Classic Example of LSP Violation

To illustrate this completely, we will go with a classic example because it is highly significant and easily understandable.

class Rectangle {

	private $topLeft;
	private $width;
	private $height;

	public function setHeight($height) {
		$this->height = $height;
	}

	public function getHeight() {
		return $this->height;
	}

	public function setWidth($width) {
		$this->width = $width;
	}

	public function getWidth() {
		return $this->width;
	}

}

We start with a basic geometrical shape, a Rectangle. It is just a simple data object with setters and getters for width and height. Imagine that our application is working and it is already deployed to several clients. Now they need a new feature. They need to be able to manipulate squares.

In real life, in geometry, a square is a particular form of rectangle. So we could try to implement a Square class that extends a Rectangle class. It is frequently said that a child class is a parent class, and this expression also conforms to LSP, at least at first sight.

SquareRect

But is a Square really a Rectangle in programming?

class Square extends Rectangle {

	public function setHeight($value) {
		$this->width = $value;
		$this->height = $value;
	}

	public function setWidth($value) {
		$this->width = $value;
		$this->height = $value;
	}
} 

A square is a rectangle with equal width and height, and we could do a strange implementation like in the above example. We could overwrite both setters to set the height as well as the width. But how would that affect client code?

class Client {

	function areaVerifier(Rectangle $r) {
		$r->setWidth(5);
		$r->setHeight(4);

		if($r->area() != 20) {
			throw new Exception('Bad area!');
		}

		return true;
	}

} 

It is conceivable to have a client class that verifies the rectangle’s area and throws an exception if it is wrong.

function area() {
	return $this->width * $this->height;
}

Of course we added the above method to our Rectangle class to provide the area.

class LspTest extends PHPUnit_Framework_TestCase {

	function testRectangleArea() {
		$r = new Rectangle();
		$c = new Client();
		$this->assertTrue($c->areaVerifier($r));
	}

}

And we created a simple test by sending an empty rectangle object to area verifier and the test passes. If our Square class is correctly defined, sending it to the Client’s areaVerifier() should not break its functionality. After all, a Square is a Rectangle in all mathematical sense. But is our class?

function testSquareArea() {
	$r = new Square();
	$c = new Client();
	$this->assertTrue($c->areaVerifier($r));
}

Testing it is very easy and it breaks big time. An exception is thrown to us when we run the test above.

PHPUnit 3.7.28 by Sebastian Bergmann.

Exception : Bad area!
#0 /paht/: /.../.../LspTest.php(18): Client->areaVerifier(Object(Square))
#1 [internal function]: LspTest->testSquareArea()

So, our Square class is not a Rectangle after all. It breaks the laws of geometry. It fails and it violates the Liskov Substitution Principle.

I especially love this example because it not only violates LSP, it also demonstrates that object oriented programming is not about mapping real life to objects. Each object in our program must be an abstraction over a concept. If we try to map one-to-one real objects to programmed objects, we will almost always fail.


The Interface Segregation Principle

The Single Responsibility Principle is about actors and high level architecture. The Open/Closed Principle is about class design and feature extensions. The Liskov Substitution Principle is about subtyping and inheritance. The Interface Segregation Principle (ISP) is about business logic to clients communication.

In all modular applications there must be some kind of interface that the client can rely on. These may be actual Interface typed entities or other classic objects implementing design patterns like Facades. It doesn’t matter which solution is used. It always has the same scope: to communicate to the client code on how to use the module. These interfaces can reside between different modules in the same application or project, or between one project as a third party library serving another project. Again, it doesn’t matter. Communication is communication and clients are clients, regardless of the actual individuals writing the code.

So, how should we define these interfaces? We could think about our module and expose all the functionalities we want it to offer.

hugeInterface

This looks like a good start, a great way to define what we want to implement in our module. Or is it? A start like this will lead to one of two possible implementations:

  • A huge Car or Bus class implementing all the methods on the Vehicle interface. Only the sheer dimensions of such classes should tell us to avoid them at all costs.
  • Or, many small classes like LightsControl, SpeedControl, or RadioCD which are all implementing the whole interface but actually providing something useful only for the parts they implement.

It is obvious that neither solution is acceptable to implement our business logic.

specializedImplementationInterface

We could take another approach. Break the interface into pieces, specialized to each implementation. This would help to use small classes that care about their own interface. The objects implementing the interfaces will be used by the different type of vehicles, like car in the image above. The car will use the implementations but will depend on the interfaces. So a schema like the one below may be even more expressive.

carUsingInterface

But this fundamentally changes our perception of the architecture. The Car becomes the client instead of the implementation. We still want to provide to our clients ways to use our whole module, that being a type of vehicle.

oneInterfaceManyClients

Assume we solved the implementation problem and we have a stable business logic. The easiest thing to do is to provide a single interface with all the implementations and let the clients, in our case BusStation, HighWay, Driver and so on, to use whatever thew want from the interface’s implementation. Basically, this shifts the behavior selection responsibility to the clients. You can find this kind of solution in many older applications.

The interface-segregation principle (ISP) states that no client should be forced to depend on methods it does not use.

However, this solution has its problems. Now all the clients depend on all the methods. Why should a BusStation depend on the state of lights of the bus, or on the radio channels selected by the driver? It should not. But what if it does? Does it matter? Well, if we think about the Single Responsibility Principle, it is a sister concept to this one. If BusStation depends on many individual implementations, not even used by it, it may require changes if any of the individual small implementations change. This is especially true for compiled languages, but we can still see the effect of the LightControl change impacting BusStation. These things should never happen.

Interfaces belong to their clients and not to the implementations. Thus, we should always design them in a way to best suite our clients. Some times we can, some times we can not exactly know our clients. But when we can, we should break our interfaces in many smaller ones, so they better satisfy the exact needs of our clients.

segregatedInterfaces

Of course, this will lead to some degree of duplication. But remember! Interfaces are just plain function name definitions. There is no implementation of any kind of logic in them. So the duplications is small and manageable.

Then, we have the great advantage of clients depending only and only on what they actually need and use. In some cases, clients may use and need several interfaces, that is OK, as long as they use all the methods from all the interfaces they depend on.

Another nice trick is that in our business logic, a single class can implement several interfaces if needed. So we can provide a single implementation for all the common methods between the interfaces. The segregated interfaces will also force us to think of our code more from the client’s point of view, which will in turn lead to loose coupling and easy testing. So, not only have we made our code better to our clients, we also made it easier for ourselves to understand, test and implement.


Final Thoughts

LSP taught us why reality can not be represented as a one-to-one relation with programmed objects and how subtypes should respect their parents. We also put it in light of the other principles that we already knew.

ISP teaches us to respect our clients more than we thought necessary. Respecting their needs will make our code better and our lives as programmers easier.

Thank you for your time.

January 23 2014

19:41

Validation and Exception Handling: From the UI to the Backend

Sooner or later in your programming career you will be faced with the dilemma of validation and exception handling. This was the case with me and my team also. A couple or so years ago we reached a point when we had to take architectural actions to accommodate all the exceptional cases our quite large software project needed to handle. Below is a list of practices we came to value and apply when it comes to validation and exception handling.


Validation vs. Exception Handling

When we started discussing our problem, one thing surfaced very quickly. What is validation and what is exception handling? For example in a user registration form, we have some rules for the password (it must contain both numbers and letters). If the user enters only letters, is that a validation issue or an exception. Should the UI validate that, or just pass it to the backend and catch any exceptions that my be thrown?

We reached a common conclusion that validation refers to rules defined by the system and verified against user provided data. A validation should not care about how the business logic works, or how the system for that matter works. For example, our operating system may expect, without any protests, a password composed of plain letters. However we want to enforce a combination of letters and numbers. This is a case for validation, a rule we want to impose.

On the other hand, exceptions are cases when our system may function in an unpredicted way, wrongly, or not at all if some specific data is provided in a wrong format. For example, in the above example, if the username already exists on the system, it is a case of an exception. Our business logic should be able to throw the appropriate exception and the UI catch and handle it so that the user will see a nice message.


Validating in the User Interface

Now that we made clear what our goals are, let’s see some examples based on the same user registration form idea.

Validating in JavaScript

To most of today’s browsers, JavaScript is second nature. There is almost no webpage without some degree of JavaScript in it. One good practice is to validate some basic things in JavaScript.

Let’s say we have a simple user registration form in index.php, as described below.

<!DOCTYPE html>
<html>
	<head>
		<title>User Registration</title>
		<meta charset="UTF-8">
	</head>
	<body>
		<h3>Register new account</h3>
		<form>
			Username:
			<br/>
			<input type="text" />
			<br/>
			Password:
			<br/>
			<input type="password" />
			<br/>
			Confirm:
			<br/>
			<input type="password" />
			<br/>
			<input type="submit" name="register" value="Register">
		</form>
	</body>
</html>

This will output something similar to the image below:

RegistrationForm

Every such form should validate that the text entered in the two password fields are equal. Obviously this is to ensure the user does not make a mistake when typing in his or her password. With JavaScript, doing the validation is quite simple.

First we need to update a little bit of our HTML code.

<form onsubmit="return validatePasswords(this);">
	Username:
	<br/>
	<input type="text" />
	<br/>
	Password:
	<br/>
	<input type="password" name="password"/>
	<br/>
	Confirm:
	<br/>
	<input type="password" name="confirm"/>
	<br/>
	<input type="submit" name="register" value="Register">
</form>

We added names to the password input fields so we can identify them. Then we specified that on submit the form should return the result of a function called validatePasswords(). This function is the JavaScript we’ll write. Simple scripts like this can be kept in the HTML file, other, more sophisticated ones should go in their own JavaScript files.

<script>
	function validatePasswords(form) {
		if (form.password.value !== form.confirm.value) {
			alert("Passwords do not match");
			return false;
		}
		return true;
	}

</script>

The only thing we do here is to compare the values of the two input fields named “password” and “confirm“. We can reference the form by the parameter we send in when calling the function. We used “this” in the form’s onsubmit attribute, so the form itself is sent to the function.

When the values are the same, true will be returned and the form will be submitted, otherwise an alert message will be shown telling the user the passwords do not match.

PasswordDoNotMatchAlert

HTML5 Validations

While we can use JavaScript to validate most of our inputs, there are cases when we want to go on an easier path. Some degree of input validation is available in HTML5, and most browsers are happy to apply them. Using HTML5 validation is simpler in some cases, though it offers less flexibility.

<head>
	<title>User Registration</title>
	<meta charset="UTF-8">
	<style>
		input {
			width: 200px;
		}
		input:required:valid {
			border-color: mediumspringgreen;
		}
		input:required:invalid {
			border-color: lightcoral;
		}
	</style>
</head>
<body>
	<h3>Register new account</h3>
	<form onsubmit="return validatePasswords(this);">
		Username:
		<br/>
		<input type="text" name="userName" required/>
		<br/>
		Password:
		<br/>
		<input type="password" name="password"/>
		<br/>
		Confirm:
		<br/>
		<input type="password" name="confirm"/>
		<br/>
		Email Address:
		<br/>
		<input type="email" name="email" required placeholder="A Valid Email Address"/>
		<br/>
		Website:
		<br/>
		<input type="url" name="website" required pattern="https?://.+"/>
		<br/>
		<input type="submit" name="register" value="Register">
	</form>
</body>

To demonstrate several validation cases, we extended our form a little bit. We added an email address and a website also. HTML validations were set on three fields.

  • The text input username is just simply required. It will validate with any string longer than zero characters.
  • The email address field is of type “email” and when we specify the “required” attribute, browsers will apply a validation to the field.
  • Finally, the website field is of type “url“. We also specified a “pattern” attribute where you can write your regular expressions that validate the required fields.

To make the user aware of the state of the fields, we also used a little bit of CSS to color the borders of the inputs in red or green, depending on the state of the required validation.

HTMLValidations

The problem with HTML validations is that different browsers behave differently when you try to submit the form. Some browsers will just apply the CSS to inform the users, others will prevent the submission of the form altogether. I recommend you to test your HTML validations thoroughly in different browsers and if needed also provide a JavaScript fallback for those browsers that are not smart enough.


Validating in Models

By now many people know about Robert C. Martin’s clean architecture proposal, in which the MVC framework is only for presentation and not for business logic.

HighLevelDesign

Essentially, your business logic should reside in a separate, well isolated place, organized to reflect the architecture of your application, while the framework’s views and controllers should control the delivery of the content to the user and models could be dropped altogether or, if needed, used only to perform delivery related operations. One such operation is validation. Most frameworks have great validation features. It would be a shame to not put your models at work and do a little validation there.

We will not install several MVC web frameworks to demonstrate how to validate our previous forms, but here are two approximate solutions in Laravel and CakePHP.

Validation in a Laravel Model

Laravel is designed so that you have more access to validation in the Controller where you also have direct access to the input from the user. The built-in validator kind of prefers to be used there. However there are suggestions on the Internet that validating in models is still a good thing to do in Laravel. A complete example and solution by Jeffrey Way can be found on his Github repository.

If you prefer to write your own solution, you could do something similar to the model below.

class UserACL extends Eloquent {
    private $rules = array(
        'userName' => 'required|alpha|min:5',
        'password'  => 'required|min:6',
		'confirm' => 'required|min:6',
		'email' => 'required|email',
		'website' => 'url'
    );

    private $errors;

    public function validate($data) {
        $validator = Validator::make($data, $this->rules);

        if ($validator->fails()) {
            $this->errors = $validator->errors;
            return false;
        }
        return true;
    }

    public function errors() {
        return $this->errors;
    }
}

You can use this from your controller by simply creating the UserACL object and call validate on it. You will probably have the “register” method also on this model, and the register will just delegate the already validated data to your business logic.

Validation in a CakePHP Model

CakePHP promotes validation in models as well. It has extensive validation functionality at model level. Here is about how a validation for our form would look like in CakePHP.

class UserACL extends AppModel {

    public $validate = [
		'userName' => [
			'rule' => ['minLength', 5],
			'required' => true,
			'allowEmpty' => false,
			'on' => 'create',
			'message' => 'User name must be at least 5 characters long.'
		],
        'password' => [
            'rule'    => ['equalsTo', 'confirm'],
            'message' => 'The two passwords do not match. Please re-enter them.'
        ]
    ];

    public function equalsTo($checkedField, $otherField = null) {
		$value = $this->getFieldValue($checkedField);
        return $value === $this->data[$this->name][$otherField];
    }

	private function getFieldValue($fieldName) {
	    return array_values($otherField)[0];
	}
}

We only exemplified the rules partially. It is enough to highlight the power of validation in the model. CakePHP is particularly good at this. It has a great number of built-in validation functions like “minLength” in the example and various ways to provide feedback to the user. Even more, concepts like “required” or “allowEmpty” are not actually validation rules. Cake will look at these when generating your view and put HTML validations also on fields marked with these parameters. However rules are great and can easily be extended by just simply creating methods on the model class as we did to compare the two password fields. Finally, you can always specify the message you want to send to the views in case of validation failure. More on CakePHP validation in the cookbook.

Validation in general at the model level has its advantages. Each framework provides easy access to the input fields and creates the mechanism to notify the user in case of validation failure. No need for try-catch statements or any other sophisticated steps. Validation on the server side also assures that the data gets validated, no matter what. The user can not trick our software any more as with HTML or JavaScript. Of course, each server side validation comes with the cost of a network round-trip and computing power on the provider’s side instead of the client’s side.


Throwing Exceptions from the Business Logic

The final step in checking data before committing it to the system is at the level of our business logic. Information that reaches this part of the system should be sanitized enough to be usable. The business logic should only check for cases that are critical for it. For example, adding a user that already exists is a case when we throw an exception. Checking the length of the user to be at least five characters should not happen at this level. We can safely assume that such limitations were enforced at higher levels.

On the other hand, comparing the two passwords is a matter for discussion. For example, if we just encrypt and save the password near the user in a database, we could drop the check and assume previous layers made sure the passwords are equal. However, if we create a real user on the operating system using an API or a CLI tool that actually requires a username, password, and password confirmation, we may want to take the second entry also and send it to a CLI tool. Let it re-validate if the passwords match and be ready to throw an exception if they do not. This way we modeled our business logic to match how the real operating system behaves.

Throwing Exceptions from PHP

Throwing exceptions from PHP is very easy. Let’s create our user access control class, and demonstrate how to implement a user addition functionality.

class UserControlTest extends PHPUnit_Framework_TestCase {
	function testBehavior() {
		$this->assertTrue(true);
	}
}

I always like to start with something simple that gets me going. Creating a stupid test is a great way to do so. It also forces me to think about what I want to implement. A test named UserControlTest means I thought I will need a UserControl class to implement my method.

require_once __DIR__ . '/../UserControl.php';
class UserControlTest extends PHPUnit_Framework_TestCase {

	/**
	 * @expectedException Exception
	 * @expectedExceptionMessage User can not be empty
	 */
	function testEmptyUsernameWillThrowException() {
		$userControl = new UserControl();
		$userControl->add('');
	}

}

The next test to write is a degenerative case. We will not test for a specific user length, but we want to make sure we do not want to add an empty user. It is sometimes easy to lose the content of a variable from view to business, over all those layers of our application. This code will obviously fail, because we do not have a class yet.

PHP Warning:  require_once([long-path-here]/Test/../UserControl.php):
failed to open stream: No such file or directory in
[long-path-here]/Test/UserControlTest.php on line 2

Let’s create the class and run our tests. Now we have another problem.

PHP Fatal error:  Call to undefined method UserControl::add()

But we can fix that, too, in just a couple of seconds.

class UserControl {

	public function add($username) {

	}

}

Now we can have a nice test failure telling us the whole story of our code.

1) UserControlTest::testEmptyUsernameWillThrowException
Failed asserting that exception of type "Exception" is thrown.

Finally we can do some actual coding.

public function add($username) {
	if(!$username) {
		throw new Exception();
	}
}

That makes the expectation for the exception pass, but without specifying a message the test will still fail.

1) UserControlTest::testEmptyUsernameWillThrowException
Failed asserting that exception message '' contains 'User can not be empty'.

Time to write the Exception’s message

public function add($username) {
	if(!$username) {
		throw new Exception('User can not be empty!');
	}
}

Now, that makes our test pass. As you can observe, PHPUnit verifies that the expected exception message is contained in the actually thrown exception. This is useful because it allows us to dynamically construct messages and only check for the stable part. A common example is when you throw an error with a base text and at the end you specify the reason for that exception. Reasons are usually provided by third party libraries or application.

/**
 * @expectedException Exception
 * @expectedExceptionMessage Cannot add user George
 */
function testWillNotAddAnAlreadyExistingUser() {
	$command = \Mockery::mock('SystemCommand');
	$command->shouldReceive('execute')->once()->with('adduser George')->andReturn(false);
	$command->shouldReceive('getFailureMessage')->once()->andReturn('User already exists on the system.');
	$userControl = new UserControl($command);
	$userControl->add('George');
}

Throwing errors on duplicate users will allow us to explore this message construction a step further. The test above creates a mock which will simulate a system command, it will fail and on request, it will return a nice failure message. We will inject this command to the UserControl class for internal use.

class UserControl {

	private $systemCommand;

	public function __construct(SystemCommand $systemCommand = null) {
		$this->systemCommand = $systemCommand ? : new SystemCommand();
	}

	public function add($username) {
		if (!$username) {
			throw new Exception('User can not be empty!');
		}
	}

}

class SystemCommand {

}

Injecting the a SystemCommand instance was quite easy. We also created a SystemCommand class inside our test just to avoid syntax problems. We won’t implement it. Its scope exceeds this tutorial’s topic. However, we have another test failure message.

1) UserControlTest::testWillNotAddAnAlreadyExistingUser
Failed asserting that exception of type "Exception" is thrown.

Yep. We are not throwing any exceptions. The logic to call the system command and try to add the user is missing.

public function add($username) {
	if (!$username) {
		throw new Exception('User can not be empty!');
	}

	if(!$this->systemCommand->execute(sprintf('adduser %s', $username))) {
		throw new Exception(
				sprintf('Cannot add user %s. Reason: %s',
						$username,
						$this->systemCommand->getFailureMessage()
				)
			);
	}
}

Now, those modifications to the add() method can do the trick. We try to execute our command on the system, no matter what, and if the system says it can not add the user for whatever reason we throw an exception. This exception’s message will be part hard-coded, with the user’s name attached and then the reason from the system command concatenated at the end. As you can see, this code makes our test pass.

Custom Exceptions

Throwing exceptions with different messages is enough in most cases. However, when you have a more complex system you also need to catch these exceptions and take different actions based on them. Analyzing an exception’s message and taking action solely on that can lead to some annoying problems. First, strings are part of the UI, presentation, and they have a volatile nature. Basing logic on ever changing strings will lead to dependency management nightmare. Second, calling a getMessage() method on the caught exception each time is also a strange way to decide what to do next.

With all these in mind, creating our own exceptions is the next logical step to take.

/**
 * @expectedException ExceptionCannotAddUser
 * @expectedExceptionMessage Cannot add user George
 */
function testWillNotAddAnAlreadyExistingUser() {
	$command = \Mockery::mock('SystemCommand');
	$command->shouldReceive('execute')->once()->with('adduser George')->andReturn(false);
	$command->shouldReceive('getFailureMessage')->once()->andReturn('User already exists on the system.');
	$userControl = new UserControl($command);
	$userControl->add('George');
}

We modified our test to expect our own custom exception, ExceptionCannotAddUser. The rest of the test is unchanged.

class ExceptionCannotAddUser extends Exception {

	public function __construct($userName, $reason) {
		$message = sprintf(
			'Cannot add user %s. Reason: %s',
			$userName, $reason
		);
		parent::__construct($message, 13, null);
	}
}

The class that implements our custom exception is like any other class, but it has to extend Exception. Using custom exceptions also provides us a great place to do all the presentation related string manipulation. Moving the concatenation here, we also eliminated presentation from the business logic and respected the single responsibility principle.

public function add($username) {
	if (!$username) {
		throw new Exception('User can not be empty!');
	}

	if(!$this->systemCommand->execute(sprintf('adduser %s', $username))) {
		throw new ExceptionCannotAddUser($username, $this->systemCommand->getFailureMessage());
	}
}

Throwing our own exception is just a matter of changing the old “throw” command to the new one and sending in two parameters instead of composing the message here. Of course all tests are passing.

PHPUnit 3.7.28 by Sebastian Bergmann.

..

Time: 18 ms, Memory: 3.00Mb

OK (2 tests, 4 assertions)

Done.

Catching Exceptions in Your MVC

Exceptions must be caught at some point, unless you want your user to see them as they are. If you are using an MVC framework you will probably want to catch exceptions in the controller or model. After the exception is caught, it is transformed in a message to the user and rendered inside your view. A common way to achieve this is to create a “tryAction($action)” method in your application’s base controller or model and always call it with the current action. In that method you can do the catching logic and nice message generation to suit your framework.

If you do not use a web framework, or a web interface for that matter, your presentation layer should take care of catching and transforming these exceptions.

If you develop a library, catching your exceptions will be the responsibility of your clients.


Final Thoughts

That’s it. We traversed all the layers of our application. We validated in JavaScript, HTML and in our models. We’ve thrown and caught exceptions from our business logic and even created our own custom exceptions. This approach to validation and exception handling can be applied from small to big projects without any severe problems. However if your validation logic is getting very complex, and different parts of your project uses overlapping parts of logic, you may consider extracting all validations that can be done at a specific level to a validation service or validation provider. These levels may include, but not need to be limited to JavaScript validator, backend PHP validator, third party communication validator and so on.

Thank you for reading. Have a nice day.

January 20 2014

20:09

SOLID: Part 2 – The Open/Closed Principle

Single Responsibility (SRP), Open/Closed (OCP), Liskov’s Substitution, Interface Segregation, and Dependency Inversion. Five agile principles that should guide you every time you need to write code.


Definition

Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.

The Open/Closed Principle, OCP in short, is credited to Bertrand Mayer, a French programmer, who first published it in his book n Object-Oriented Software Construction in 1988.

The principle rose in popularity in the early 2000s when it became one of the SOLID principles defined by Robert C. Martin in his book Agile Software Development, Principles, Patterns, and Practices and later republished in the C# version of the book Agile Principles, Patterns, and Practices in C#.

What we are basically talking about here is to design our modules, classes and functions in a way that when a new functionality is needed, we should not modify our existing code but rather write new code that will be used by existing code. This sounds a little bit strange, especially if we are working in languages like Java, C, C++ or C# where it applies not only to the source code itself but to the binary also. We want to create new features in ways that will not require us to redeploy existing binaries, executables or DLLs.


OCP in the SOLID Context

As we progress with these tutorials, we can put each new principle in the context of the already discussed ones. We already discussed the Single Responsibility (SRP) that stated that a module should have only one reason to change. If we think about OCP and SRP, we can observe that they are complementary. Code specifically designed with SRP in mind will be close to OCP principles or easy to make it respect those principles. When we have code that has a single reason to change, introducing a new feature will create a secondary reason for that change. So both SRP and OCP would be violated. In the same way, if we have code that should only change when its main function changes and should remain unchanged when a new feature is added to it, thus respecting OCP, will mostly respect SRP also.

This does not mean that SRP always leads to OCP or vice versa, but in most cases if one of them is respected, achieving the second one is quite simple.


The Obvious Example of OCP Violation

From a purely technical point of view, the Open/Closed Principle is very simple. A simple relationship between two classes, like the one below violates the OCP.

violate1

The User class uses the Logic class directly. If we need to implement a second Logic class in a way that will allow us to use both the current one and the new one, the existing Logic class will need to be changed. User is directly tied to the implementation of Logic, there is no way for us to provide a new Logic without affecting the current one. And when we are talking about statically typed languages, it is very possible that the User class will also require changes. If we are talking about compiled languages, most certainly both the User executable and the Logic executable or dynamic library will require recompilation and redeployment to our clients, a process we want to avoid whenever possible.


Show Me the Code

Based only on the schema above, one can deduce that any class directly using another class would actually violate the Open/Closed Principle. And that is right, strictly speaking. I found it quite interesting to find the limits, the moment when you draw the line and decide that it is more difficult to respect OCP than modify existing code, or the architectural cost does not justify the cost of changing existing code.

Let’s say we want to write a class that can provide progress as a percent for a file that is downloaded through our application. We will have two main classes, a Progress and a File, and I imagine we will want to use them like in the test below.

function testItCanGetTheProgressOfAFileAsAPercent() {
	$file = new File();
	$file->length = 200;
	$file->sent = 100;

	$progress = new Progress($file);

	$this->assertEquals(50, $progress->getAsPercent());
}

In this test we are a user of Progress. We want to obtain a value as a percent, regardless of the actual file size. We use File as the source of information for our Progress. A file has a length in bytes and a field called sent representing the amount of data sent to the one doing the download. We do not care about how these values are updated in the application. We can assume there is some magical logic doing it for us, so in a test we can set them explicitly.

class File {
	public $length;
	public $sent;
}

The File class is just a simple data object containing the two fields. Of course in real life, it would probably contain other information and behavior also, like file name, path, relative path, current directory, type, permissions and so on.

class Progress {

	private $file;

	function __construct(File $file) {
		$this->file = $file;
	}

	function getAsPercent() {
		return $this->file->sent * 100 / $this->file->length;
	}

}

Progress is simply a class taking a File in its constructor. For clarity, we specified the type of the variable in the constructor’s parameters. There is a single useful method on Progress, getAsPercent(), which will take the values sent and length from File and transform them into a percent. Simple, and it works.

Testing started at 5:39 PM ...
PHPUnit 3.7.28 by Sebastian Bergmann.
.
Time: 15 ms, Memory: 2.50Mb
OK (1 test, 1 assertion)

This code seems to be right, however it violates the Open/Closed Principle. But why? And How?


Changing Requirements

Every application that is expected to evolve in time will need new features. One new feature for our application could be to allow streaming of music, instead of just downloading files. File‘s length is represented in bytes, the music’s duration in seconds. We want to offer a nice progress bar to our listeners, but can we reuse the one we already have?

No, we can not. Our progress is bound to File. It understands only files, even though it could be applied to music content also. But in order to do that we have to modify it, we have to make Progress know about Music and File. If our design would respect OCP, we would not need to touch File or Progress. We could just simply reuse the existing Progress and apply it to Music.


Solution 1: Take Advantage of the Dynamic Nature of PHP

Dynamically typed languages have the advantages of guessing the types of objects at runtime. This allows us to remove the typehint from Progress‘ constructor and the code will still work.

class Progress {

	private $file;

	function __construct($file) {
		$this->file = $file;
	}

	function getAsPercent() {
		return $this->file->sent * 100 / $this->file->length;
	}

} 

Now we can throw anything at Progress. And by anything, I mean literally anything:

class Music {

	public $length;
	public $sent;

	public $artist;
	public $album;
	public $releaseDate;

	function getAlbumCoverFile() {
		return 'Images/Covers/' . $this->artist . '/' . $this->album . '.png';
	}
} 

And a Music class like the one above will work just fine. We can test it easily with a very similar test to File.

function testItCanGetTheProgressOfAMusicStreamAsAPercent() {
	$music = new Music();
	$music->length = 200;
	$music->sent = 100;

	$progress = new Progress($music);

	$this->assertEquals(50, $progress->getAsPercent());
}

So basically, any measurable content can be used with the Progress class. Maybe we should express this in code by changing the variable’s name also:

class Progress {

	private $measurableContent;

	function __construct($measurableContent) {
		$this->measurableContent = $measurableContent;
	}

	function getAsPercent() {
		return $this->measurableContent->sent * 100 / $this->measurableContent->length;
	}

} 

Good, but we have a huge problem with this approach. When we had File specified as a typehint, we were positive about what our class can handle. It was explicit and if something else came in, a nice error told us so.

Argument 1 passed to Progress::__construct()
must be an instance of File,
instance of Music given.1

<p>But without the typehint, we must rely on the fact that whatever comes in will have two public variables of some exact names like "<code>length</code>" and "<code>sent</code>". Otherwise we will have a refused bequest.</p>

<blockquote>Refused bequest: a class that overrides a method of a base class in such a way that the contract of the base class is not honored by the derived class. ~Source Wikipedia.</blockquote>

<p>This is one of the <em>code smells</em> presented in much more detail in the <a href="https://tutsplus.com/course/detecting-code-smells/">Detecting Code Smells</a> premium course. In short, we do not want to end up trying to call methods or access fields on objects that do not conform to our contract. When we had a typehint, the contract was specified by it. The fields and methods of the <code>File</code> class. Now that we have nothing, we can send in anything, even a string and it would result in an ugly error.</p>

1

<p>A test like this, where we send in a simple string, will produce a refused bequest:</p>

1Trying to get property of non-object.

While the end result is the same in both cases, meaning the code breaks, the first one produced a nice message. This one, however, is very obscure. There is no way of knowing what the variable is – a string in our case – and what properties were looked for and not found. It is difficult to debug and to solve the problem. A programmer needs to open the Progress class and read it and understand it. The contract, in this case, when we do not explicitly specify the typehint, is defined by the behavior of Progress. It is an implicit contract, known only to Progress. In our example, it is defined by the access to the two fields, sent and length, in the getAsPercent() method. In real life the implicit contract can be very complex and hard to discover by just looking for a few seconds at the class.

This solution is recommended only if none of the other suggestions below can easily be implemented or if they would inflict serious architectural changes that do not justify the effort.


Solution 2: Use the Strategy Design Pattern

This is the most common and probably the most appropriate solution to respect OCP. It is simple and effective.

strategy

The Strategy Pattern simply introduces the use of an interface. An interface is a special type of entity in Object Oriented Programming (OOP) which defines a contract between a client and a server class. Both classes will adhere to the contract to ensure the expected behavior. There may be several, unrelated, server classes that respect the same contract thus being capable of serving the same client class.

interface Measurable {
	function getLength();
	function getSent();
}

In an interface we can define only behavior. That is why instead of directly using public variables we will have to think about using getters and setters. Adapting the other classes will not be difficult at this point. Our IDE can do most of the job.

function testItCanGetTheProgressOfAFileAsAPercent() {
	$file = new File();
	$file->setLength(200);
	$file->setSent(100);

	$progress = new Progress($file);

	$this->assertEquals(50, $progress->getAsPercent());
}

As usual, we start with our tests. We will need to use setters to set the values. If considered mandatory, these setters may also be defined in the Measurable interface. However, be careful what you put there. The interface is to define the contract between the client class Progress and the different server classes like File and Music. Does Progress need to set the values? Probably not. So the setters are highly unlikely to be needed to be defined in the interface. Also, if you would define the setters there, you would force all of the server classes to implement setters. For some of them, it may be logical to have setters, but others may behave totally differently. What if we want to use our Progress class to show the temperature of our oven? The OvenTemperature class may be initialized with the values in the constructor, or obtain the information from a third class. Who knows? To have setters on that class would be odd.

class File implements Measurable {

	private $length;
	private $sent;

	public $filename;
	public $owner;

	function setLength($length) {
		$this->length = $length;
	}

	function getLength() {
		return $this->length;
	}

	function setSent($sent) {
		$this->sent = $sent;
	}

	function getSent() {
		return $this->sent;
	}

	function getRelativePath() {
		return dirname($this->filename);
	}

	function getFullPath() {
		return realpath($this->getRelativePath());
	}

}

The File class is modified slightly to accommodate the requirements above. It now implements the Measurable interface and has setters and getters for the fields we are interested in. Music is very similar, you can check its content in the attached source code. We are almost done.

class Progress {

	private $measurableContent;

	function __construct(Measurable $measurableContent) {
		$this->measurableContent = $measurableContent;
	}

	function getAsPercent() {
		return $this->measurableContent->getSent() * 100 / $this->measurableContent->getLength();
	}

} 

Progress also needed a small update. We can now specify a type, using typehinting, in the constructor. The expected type is Measurable. Now we have an explicit contract. Progress can be sure the accessed methods will be always present because they are defined in the Measurable interface. File and Music can also be sure they can provide all that is needed for Progress by simply implementing all the methods on the interface, a requirement when a class implements an interface.

This design pattern is explained in greater detail in the Agile Design Patterns course.

A Note on Interface Naming

People tend to name interfaces with a capital I in front of them, or with the word “Interface” attached at the end, like IFile or FileInterface. This is an old-style notation imposed by some outdated standards. We are so much past the Hungarian notations or the need to specify the type of a variable or object in its name in order to easier identify it. IDEs identify anything in a split second for us. This allows us to concentrate on what we actually want to abstract.

Interfaces belong to their clients. Yes. When you want to name an interface you must think of the client and forget about the implementation. When we named our interface Measurable we did so thinking about Progress. If I would be a progress, what would I need to be able to provide the percent? The answer is simple, something we can measure. Thus the name Measurable.

Another reason is that the implementation can be from various domains. In our case, there are files and music. But we may very well reuse our Progress in a racing simulator. In that case, the measured classes would be Speed, Fuel, etc. Nice, isn’t it?


Solution 3: Use the Template Method Design Pattern

The Template Method design pattern is very similar to the strategy, but instead of an interface it uses an abstract class. It is recommended to use a Template Method pattern when we have a client very specific to our application, with reduced reusability and when the server classes have common behavior.

template_method

This design pattern is explained in greater detail in the Agile Design Patterns course.


A Higher Level View

So, how is all of this affecting our high level architecture?

HighLevelDesign

If the image above represents the current architecture of our application, adding a new module with five new classes (the blue ones) should affect our design in a moderate way (red class).

HighLevelDesignWithNewClasses

In most systems you can’t expect absolutely no effect on the existing code when new classes are introduced. However, respecting the Open/Closed Principle will considerably reduce the classes and modules that require constant change.

As with any other principle, try not to think about everything from before. If you do so, you will end up with an interface for each of your classes. Such a design will be hard to maintain and understand. Usually the safest way to go is to think about the possibilities and if you can determine whether there will be other types of server classes. Many times you can easily imagine a new feature or you can find one on the project’s backlog that will produce another server class. In those cases, add the interface from the beginning. If you can not determine, or if you are unsure – most of the time – simply omit it. Let the next programmer, or maybe even yourself, to add the interface when you need a second implementation.


Final Thoughts

If you follow your discipline and add interfaces as soon as a second server is needed, modifications will be few and easy. Remember, if code required changes once, there is a high possibility it will require change again. When that possibility turns into reality, OCP will save you a lot of time and effort.

Thank you for reading.

January 15 2014

11:00

HTML 5 and SVG: Providing a PNG Fallback with PHP and ImageMagick


  

Using SVG in web design has many advantages. Being a vector format is the biggest and has it standing out from the crowd of other image formats. You could have guessed, though, that while modern browsers do already support SVG, the good ole Internet Exploder doesn’t, at least not below version 9. As older versions of Internet Explorer are still out there in the wild, you should always consider implementing a fallback solution. Using PHP and ImageMagick makes it a snap to provide a fallback to PNG..

January 10 2014

21:22

Building a Customer Management App Using AngularJS and Laravel

When creating a single-page app we should use some kind of framework to do some of the job for us, so we can focus on the actual functionality. AngularJS fits here perfectly, because features like dynamic dependency injection and bi-directional data binding are just great. Sometimes we also require some kind of server. If you’ve chosen PHP then Laravel may be your best option, as it’s easy to work with and pretty powerful.


Introduction

In this tutorial you will create a simple customer/transaction management system with the ability to add and remove both transactions and customers. This is probably not the kind of thing you make very often, but it shows how to use features of both frameworks.

Before we start you should setup a MySQL database which we will use (Laravel supports many more of them, but this is still the most popular one). You don’t need any web server since we will be using PHP’s built-in one (but please keep in mind, that this solution is only for the development and should never be used in production – it lacks many features that are required for your app to work properly in public). For that, we will need at least PHP version 5.4.0.


Preparation

The first thing we have to do is to install Laravel. The full process is described on Laravel’s website. After that, you should have your project directory created with all of Laravel’s files in there. Navigate to that directory in your command line and run this command there:

php artisan serve

If all goes OK, you should see that the local development server was started on locahost:8000. Open your browser and navigate there, you should see Laravel’s welcome page:

first_run

Now we can proceed to the actual application.


Migrations and Models

Models in Laravel are just like in any other MVC framework. It’s using the Eloquent ORM to ease the work for you – you will probably never need to write an SQL query again (unless you’ll want something that Eloquent does not support). Using migrations you can modify the database structure with the ability to rollback changes if something goes wrong. You can read more about migrations in the documentation.

In our app we will use two models:

  • Customer – will hold the customer data
  • Transaction – will hold the information about a transaction

Let’s start by creating migrations for them. If you have not done so already, shut down the server we started earlier (Ctrl + C).

Customers

First, invoke this command:

php artisan migrate:make create_customers_table

This will create a migration file with a basic structure for you. Now navigate to app/database/migrations. There should be a file with its name starting with a timestamp and ending with “create_customers_table“. Laravel automatically created this basic structure for you. The up() method is called when the migration is applied, and down() when it’s rolled back.

First call the Schema::create() method. It takes two arguments – the schema’s name and a callback function:

Schema::create('customers', function ($table) {

The callback is executed when the table is created. The table object is passed as the $table variable and we manipulate the table’s structure using it. Let’s add an auto-incrementing id field:

	$table->increments('id');

Next there will be three string fields for the customer’s first name, surname and email:

	$table->string('first_name');
	$table->string('last_name');
	$table->string('email')->unique();

We make the email field unique by calling the unique() method on it.

The last method is for the timestamps:

	$table->timestamps();
});

This will create two date fields in the schema: created_at and updated_at. These will be used by Eloquent to store the time when the item was created and updated.

Finally, the code should look like this:

public function up() {
	Schema::create('customers', function ($table) {
		$table->increments('id');
		$table->string('first_name');
		$table->string('last_name');
		$table->string('email')->unique();
		$table->timestamps();
	});
}

The down() method is much simpler – it just deletes the schema:

public function down() {
	Schema::drop('customers');
}

Transactions

The code here will be similar to the customers’ one. First invoke this command:

php artisan migrate:make create_transactions_table

Now locate the appropriate file in the app/database/migrations and open it. Like earlier, start by creating the schema:

Schema::create('transactions', function ($table) {

Now add the fields for the id, transaction’s name, its cost and the id of the customer that it belongs to:

	$table->increments('id');
	$table->string('name');
	$table->float('amount');
	$table->integer('customer_id');

And of course the timestamps:

	$table->timestamps();
});

The final code should look like this:

public function up() {
	Schema::create('transactions', function ($table) {
		$table->increments('id');
		$table->string('name');
		$table->float('amount');
		$table->integer('customer_id');
		$table->timestamps();
	});
}

And now the down() method:

public function down() {
	Schema::drop('transactions');
}

Database Configuration

Now before you apply the migrations you’ll have to configure the connection to your database. Open the app/config/database.php file and go to line 55. Here is the configuration data for MySQL (there are few others in there, for example you could use SQLite or Postgres):

'mysql' => array(
	'driver'    => 'mysql',                 // database driver, don't touch
	'host'      => 'localhost',             // host of the database, usually localhost unless you have your db on some server
	'database'  => 'database',              // name of the database you will be using, it must be created earlier
	'username'  => 'root',                  // username that the script will use to connect, I strongly advice against using root user for this
	'password'  => '',                      // password for the user above, it's better not to use a blank one
	'charset'   => 'utf8',                  // encoding of the db
	'collation' => 'utf8_unicode_ci',       // db's collation setting
	'prefix'    => '',                      // prefix of the database tables, useful if you have multiple scripts using the same database
),

After you have filled that in, you are good to go. Make sure you saved the file and invoke this command from your app’s main directory (the one with the artisan file in it):

php artisan migrate

And thats it. If there were no errors, that means that the tables were created successfully. You can connect to your db using, for example, phpMyAdmin to check manually if you want.

Models

In Laravel, creating a model after you’ve configured your database using migrations is really quick. Navigate to app/models and delete the example User.php file that is there. Now create two files named Customer.php and Transaction.php.

Let’s start with Customer.php. Every model in Laravel has to extend the Eloquent class:

class Customer extends Eloquent {

Now we will define a relationship between the customer and their transactions. This is done by defining a public method in the model with the name of the property we would like to have in it (in this case transactions):

	public function transactions() {

Now in the body of the function there will be only one line:

		return $this->hasMany('Transaction');
	}
}

This tells Eloquent that it should provide all transactions with customer_id of the customer under a property named transactions.

Now we will do pretty much the same for the transactions, but we will reverse the relationship to make the transaction’s owner accessible via the customer property:

class Transaction extends Eloquent {
	public function customer() {
		return $this->belongsTo('Customer');
	}
}

This is done using the $this->belongsTo() method of the model.


Controllers

Now to actually use the models we have to create controllers for them. Head to the app/controllers directory, delete the HomeController.php only – BaseController.php is important as our controllers will extend it. Now create two files: CustomerController.php and TransactionController.php.

CustomerController

This controller will handle everything related to the customers – adding, removing and showing a list of them. Start by defining the class:

class CustomerController extends BaseController {

We will be using Laravel’s feature named RESTful controllers. It makes creating routes easier because we only have to define the base URI and Laravel will handle everything for us. This requires you to start your function names with the appropriate HTTP verb and then continue with the subroute name (using camelCase). So for example, if we would have a method named getNames and the base URI would be /customers, then the method will be accessible at /customers/names.

The getIndex(), postIndex(), deleteIndex() etc. methods will be mapped to the default route (in this case /customers).

Now let’s define our first route – getting the customer by their id:

	public function getIndex() {

Let’s get the id from the query parameters (Laravel provides a nice Input class to deal with that, so you don’t have to use $_GET, $_POST and $_FILES):

		$id = Input::get('id');

And search for the user in the database using that id:

		return Customer::find($id);
	}

Every method of the controller has to return a value that is a string or has a __toString() method. In this case the Customer model that is returned will be converted to JSON before sending.

Now lets return a list of all users (this will be accessible under /customers/all):

	public function getAll() {
		return Customer::all();
	}

As you can see, we can get all customers using the model’s all() method.

Now the longest part, adding a new customer:

	public function postIndex() {

First let’s check if all information needed was provided. We can do this using the Input::has() method:

		if (Input::has('first_name', 'last_name', 'email')) {

Let’s put all of the input fields in the $input variable to avoid calling Input::get() over and over. This can be done using Input::all():

			$input = Input::all();

Next we will check if any of the inputs are empty. If so, we will return a HTTP 400 Bad Request error with a more verbose message:

			if ($input['first_name'] == '' || $input['last_name'] == '' || $input['email'] == '') {
				return Response::make('You need to fill all of the input fields', 400);
			}

Since we wanted to return a status code other than 200 instead of just returning the message as a string, we used Response::make(), which takes the data to send as the first parameter and the status code as the second. Take a look at the docs if you want to know more about responses.

Now we finally create a new Customer model and feed it with the data provided:

			$customer = new Customer;
			$customer->first_name = $input['first_name'];
			$customer->last_name = $input['last_name'];
			$customer->email = $input['email'];

After that we can save the newly created model and respond to the request with it:

			$customer->save();
			
			return $customer;

Here we handle the case if not all of the inputs were provided:

		} else {
			return Response::make('You need to fill all of the input fields', 400);
		}
	}

Finally, we also need the ability to remove the customers. This one is really short:

	public function deleteIndex() {

We start by getting the id of the customer to delete:

		$id = Input::get('id');

Next, we search for and delete the customer:

		$customer = Customer::find($id);
		$customer->delete();

After that, we respond to the request with the id provided:

		
		return $id;
	}
}

Now before the routes can be accessed, we have to hook them. Open the app/routes.php file, delete everything but the comment and add this line at the end of the file:

Route::controller('/customers', 'CustomerController');

This will tell Laravel to route all requests at /customers to our CustomerController. Now you can use CURL to play with it. First start the server with php artisan serve and then you can, for example, create a customer:

curl -X POST -d "first_name=Jane&last_name=Doe&email=jdoe@gmail.com" http://localhost:8000/customers

Then you can get the list of all customers:

curl http://localhost:8000/customers/all

TransactionController

This, like the model is very similar to the CustomerController. First create the class:

class TransactionController extends BaseController {

Then let’s define the method to get all transactions for a user:

	public function getIndex() {
		$id = Input::get('id');
		return User::find($id)->transactions;
	}

As you can see we are using the relationship defined earlier to get the transactions (now recall the query you had to write to achieve the same thing using plain PHP and SQL).

The next thing will be the creation of transactions:

	public function postIndex() {

Like earlier, we are checking if all of the required information is provided:

		if (Input::has('name', 'amount')) {

If so, assign it to an $input variable:

			$input = Input::all();

Check if any of the values provided are empty and if so return an error:

			if ($input['name'] == '' || $input['amount'] == '') {
				return Response::make('You need to fill all of the input fields', 400);
			}

Now create the transaction and supply it with all of the info provided:

			$transaction = new Transaction;
			$transaction->name = $input['name'];
			$transaction->amount = $input['amount'];

Now we need to add it to the appropriate customer. Let’s find them by the id provided and add the $transaction to their transactions list:

			$id = $input['customer_id'];
			User::find($id)->transactions->save($transaction);

This is done using the transactions->save() method provided by Laravel. Now we can respond with the transaction created:

			return $transaction;

And handle the case where none or not all of the data was provided:

		} else {
			return Response::make('You need to fill all of the input fields', 400);
		}
	}

After that there is also a method to delete the transaction in the same way that we deleted the customer:

	public function deleteIndex() {
		$id = Input::get('id');
		$transaction = Transaction::find($id);
		$transaction->delete();
		
		return $id;
	}
}

Now just add the route and you can test the controller using CURL:

Route::controller('/transactions', 'TransactionController');

Conclusion

Alright, this is the end of the first part – in the second part of this tutorial, we will create the front-end using AngularJS. Feel free to add more features to your app (like editing customers or sorting), in case you did not find the information you were looking for, take a look at Laravel’s documentation.

January 09 2014

18:40

Creating a Photo Tag Wall With Twilio Picture Messaging & PHP

Twilio’s recently announced Picture Messaging has vastly opened up what we can do with text messaging, now we can attach photos to our text messages and have them get used in different ways.

In our case, we are going to build a Photo Tag Wall, which will contain photos linked to tags that will be displayed on a website.

This can be handy for events, or parties, or just about anything where you want to associate photos and tags.

To process our photos, we’ll be doing a few different things; We’re going to resize them, we’ll also use pusher to add a little real-time updating to the wall, with the idea of having it displayed on a monitor somewhere and letting it update as needed for everyone to see what is displayed.

We’re going to use the Jolt Microframework for PHP, and Idiorm and Paris for our MySql handling.


Getting Started

Ok, first let’s set up our database:


CREATE TABLE `tag`(

`id` bigint(20) NOT NULL AUTO_INCREMENT,

`name` varchar(255) NOT NULL DEFAULT '',

`slug` varchar(255) NOT NULL DEFAULT '',

PRIMARY KEY (`id`),

KEY `name` (`name`),

KEY `slug` (`slug`)

) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;

CREATE TABLE `photo`(

`id` bigint(20) NOT NULL AUTO_INCREMENT,

`tag_id` bigint(20) NOT  NULL DEFAULT '0',

`file` varchar(255) NOT NULL DEFAULT '',

`from` varchar(255) NOT NULL DEFAULT '',

`country` varchar(255) NOT NULL DEFAULT '',

`datetime` timestamp DEFAULT CURRENT_TIMESTAMP,

PRIMARY KEY (`id`),

KEY `tag_id` (`tag_id`),

KEY `file` (`file`)

) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;

We’re setting up two tables, one to store the tag, and one for the photos and the id to the tag they are associated with.

This table will store the tag, the image, and some meta data about the phone number that sent the photo.

We’re also going to need to download the Jolt framework, the Twilio PHP Library, and Idiorm and Paris.

The first thing you’ll want to do is grab these packages from their respective websites:

Now that you have all the packages downloaded to your computer, it’s time to setup your directory structure. We’ll be putting the files into our site’s root folder.

We’re putting the web services related files inside the Services folder, since it helps us watch where things are.

Ok, let’s set up our config.ini file, open up config.ini in your editor and modify the following settings:


;site settings

site.name = my site

site.url = http://mysiteurl.com

; rendering vars

views.root = views

views.layout = layout

; session vars

cookies.secret = IeNj0yt0sQu33zeflUFfym0nk1e

cookies.flash = _F

; db stuff

db.enabled = true

db.host = MY DATABASE HOST

db.name = MY DATABASE NAME

db.user = MY DATABASE USER

db.pass = MY DATABASE PASSWORD

; twilio stuff

twilio.accountsid = MY TWILIO ACCOUNT SID

twilio.authtoken = MY TWILIO AUTH TOKEN

twilio.from = MY TWILIO FROM NUMBER

You can see what you’ll have to fill in here, your site name, and URL, your database info and your Twilio info.


Now for the Coding!

To get started, let’s set up our models. We’ll create a file inside the system folder called models.php:


<?php

class Tag extends Model{

	public function photos(){

		return $this->has_many('Photo');

	}

}

class Photo extends Model {

	public function tag(){

		return $this->belongs_to('Tag');

	}

}

?>

This is a pretty basic model layout, but one nice thing about it, is that we’re using Paris to establish a relationship with the tag table. In fact, because we’ve previously built our database to have a tag_id field in the photo table, this model knows to associate all photos with the tag_id, where tag_id is the table name and the primary key field in the tag table.

The same is true for the Photo class, where we’ve set it to belong to a tag as specified in the tag() function.

This is handy for building a quick model system without a lot of overhead.

We also want to create our functions.php file, which we will also keep inside the system folder:


<?php

function slugify( $string ){

	$string = strtolower( trim($string) );

	$slug=preg_replace('/[^A-Za-z0-9-]+/', '-', $string);

	return $slug;

}

function cropResize($img,$out='',$dSize=170){

	$x = @getimagesize($img);

	$sw = $x[0];

	$sh = $x[1];

	$yOff = 0;

	$xOff = 0;

	if($sw < $sh) {

		$scale = $dSize / $sw;

		$yOff = $sh/2 - $dSize/$scale/2;

	} else {

		$scale = $dSize / $sh;

		$xOff = $sw/2 - $dSize/$scale/2;

}

$im = @ImageCreateFromJPEG ($img) or // Read JPEG Image

$im = @ImageCreateFromPNG ($img) or // or PNG Image

$im = @ImageCreateFromGIF ($img) or // or GIF Image

$im = false; // If image is not JPEG, PNG, or GIF

if (!$im) {

	readfile ($img);

} else {

	$thumb = @ImageCreateTrueColor ($dSize,$dSize);

	imagecopyresampled($thumb, $im,

	0, 0,

	$xOff,$yOff,

	$dSize, $dSize,

	$dSize / $scale ,$dSize / $scale);

}

if( $out == '' ){

	header('content-type:image/jpeg');

	imagejpeg($thumb);

}else{

	imagejpeg($thumb, $out);

}

}

functions.php will contain two core functions, one function, slugify(), will convert tag names into slugs, and the cropResize() function will take the image we pass to it, and save it within new dimensions.

We’ll be using these functions quite a lot coming up.

Most of our code will be stored inside index.php, so let’s set up the bare bones for it:


<?php

include("system/jolt.php");

require 'system/idiorm.php';

require 'system/paris.php';

require 'system/models.php';

require 'Services/Twilio.php';

require 'system/functions.php';

Ok, we’ve included our files, and nothing happened. Now, let’s get Jolt up and running:


$app = new Jolt();

$app->option('source', 'config.ini');

The above code just sets up Jolt and tells it to read the config.ini file and set our configuration settings, now let’s connect to our database:


if( $app->option('db.enabled') != false ){

	ORM::configure('mysql:host='.$app->option('db.host').';dbname='.$app->option('db.name'));

	ORM::configure('username', $app->option('db.user') );

	ORM::configure('password', $app->option('db.pass') );

}

Our final piece of bootstrapping, we want to set up our Twilio client:


$client = new Services_Twilio($app->option('twilio.accountsid'), $app->option('twilio.authtoken') );

$fromNumber = $app->option('twilio.from');

$app->store('client',$client);

This is our bootstrap section, so far all we’ve done is included our files, set up our Jolt app, connected to our database and initialized our Twilio client.

Right now, if you run your app, you’ll get a few errors. This is fine, we’ll be taking care of those errors next.


Routing

Now we have to set up our routes and tell our app what to do based on certain rules. These rules will be either get or post.

Our initial rules will be the home page, the tag page, and the listener:


$app->get('/',function(){

$app = Jolt::getInstance();

});

$app->get('/tag/:tag',function($tag){

$app = Jolt::getInstance();

});

$app->post('/listener',function($tag){

$app = Jolt::getInstance();

});

$app->listen();

We’ve just set up the initial bare bones actions for our homepage, which is represented by the '/', our tag page, and our listener.

You’ll notice the listener is a post rather than a get, that is because this is the handler from Twilio when new messages are received.

Lastly, you’ll see the $app->listen(); method call. This is the most important method call we have, as it tells the app to start running.


There’s No Place Like Home

Let’s set up the home page, and build the view that we’ll be displaying for everybody.

Replace the original homepage route with this one:


$app->get('/', function(){

$app = Jolt::getInstance();

$tags = Model::factory('Tag')->count();

if( isset($tags) ){

	$images = Model::factory('Photo')->count();

	$tagList = Model::factory('Tag')->find_many();

}else{

	$tags = 0;

	$images = 0;

	$tagList = array();

}

$app->render( 'home',array(

	'tags'=>$tags,

	'tagList' => $tagList,

	'fromNumber' => $app->option('twilio.from'),

	'images'=>$images

	));

});

You’ll also notice that we tell it to render something called ‘home‘, in the views folder, there is a home.php file, open it up and edit it as follows:


<p >Text <span><?php echo $fromNumber ?></span> a picture with the name of a tag.  Your image will be displayed on that tag.</p>

<div>

	<div>

		<p>Number of Tags: <?php echo $tags; ?></p>

		<p>Number of Images: <?php echo $images; ?></p>

	</div>

</div>

<hr />

<h3>Tags</h3>

<ul>

<?php   foreach($tagList as $tag){  ?>

	<li>

	<a href="<?php echo $uri?>/tag/<?php echo $tag->slug?>"><?php echo $tag->name?></a>

	</li>

<?php   }   ?>

</ul>

This file will take the variables we pass from the $app->render() function and make use of them here.

We’re going to display a count of total tags, along with total images, and a list of tags that a visitor can click on.

The actual page layout is controlled by a file called layout.php. Let’s go ahead and update that file now:


<html>

	<head>

		<title><?=$pageTitle?></title>

		<meta name="viewport" content="width=device-width, initial-scale=1.0">

		<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet">

		<link href="<?=$uri?>/style.css" rel="stylesheet">

		<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>

		<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>

	</head>

	<body>

		<div>

			<div>

				<ul>

					<li><a href="<?=$uri?>">Home</a></li>

				</ul>

				<h3>Photo Wall</h3>

			</div>

		<hr />

		<section>

			<?=$pageContent?>

		</section>

		</div>

	</body>

</html>

This is pretty bare bones HTML, but it covers what we’re needing. All output gets sent to the $pageContent variable in layout.php.


Picture Messaging!

Ok, now let’s handle the actual uploading of pictures from Twilio.

Log into your Twilio account and point a phone number to http://MYSITEURL/listener for SMS messages, where MYSITEURL is the address where you’ve uploaded your app.

We’re going to replace our listener route with this one:


$app->post('/listener', function(){

$app = Jolt::getInstance();

if ( isset($_POST['NumMedia']) && $_POST['NumMedia'] > 0 ){

	//  let's find out what tag this is for.. or create a new one..

	$thetag = slugify( $_POST['Body'] );

	$tag  = Model::factory('Tag')->where_equal( 'slug', $thetag )->find_one();

	if( isset($tag->id) && !empty($tag->id) ){

		$tag_id = $tag->id;

	}else{

		//  no tag already exists...

		$tag                    = Model::factory('Tag')->create();

		$tag->name              = $_POST['Body'];

		$tag->slug              = slugify( $_POST['Body'] );

		$tag->save();

		$tag_id = $tag->id();

	}

	for ($i = 0; $i < $_POST['NumMedia']; $i++){

	if (strripos($_POST['MediaContentType'.$i], 'image') === False){

		continue;

	}

	$file = sha1($_POST['MediaUrl'.$i]).'.jpg';

	file_put_contents('images/original/'.$file, file_get_contents($_POST['MediaUrl'.$i]));

	chmod ('images/original/'.$file, 01777);
	// Edit image

	$in = 'images/original/'.$file;

	$out = 'images/processed/'.$file;

	cropResize($in,$out,250);

	chmod ('images/processed/'.$file, 01777);
	// Remove Original Image

	unlink('images/original/'.$file);

	$photo              =   Model::factory('Photo')->create();

	$photo->tag_id      =   $tag_id;

	$photo->file        =   $file;

	$photo->from        =   $_POST['From'];

	$photo->country     =   $_POST['FromCountry'];

	$photo->save();

	}

	$message = $app->store('client')->account->messages->sendMessage(

	$app->option('twilio.from'), // From a valid Twilio number

	$_POST['From'], // Text this number

	"Image(s) Added to <".strtolower(trim($_POST['Body']))."> Photo Wall Link: ".$app->option('site.url')."/tag/".strtolower(trim($_POST['Body']))

	);

	return true;

}else{

	if ( isset($_POST['From']) ){

	$message = $app->store('client')->account->messages->sendMessage(

	$app->option('twilio.from'), // From a valid Twilio number

	$_POST['From'], // Text this number

	"MMS error. Please try sending your image again."

	);

}

header('HTTP/1.1 400 Bad Request', true, 400);

return false;

}

});

There is no view associated with this action. Now, let’s go over what it does.

This is only called during a post, hence the $app->post() statement.

When it is activated by someone sending in a message, we check to see if there are any images attached, and if there are, then we cycle through them and save them in the database.

First, we check to see if there are any tags already stored in our database that match the tag we attached to our image, and if there is, then we grab the id from the database, otherwise, we save a new record containing that tag’s information.

Next, we cycle through the uploaded files and make sure they are images. Each image is downloaded locally and stored inside the images/original folder. We then resize and crop the images to be a more manageable size, and store the new files inside the images/processed folder.

Finally, we store the images inside the database, along with some meta data on the call itself, and send a text message back to the sender to tell him or her to check out the tag page.

If no images were attached, then we send them a message that there was an error.


The Photo Wall

Now, we’ve set up the home page, and we’ve set up the listener. What’s left, is to set up the photo wall itself.

This will go inside the $app->get(‘/tag/:tag') call.

Replace the original placeholder with the following code:


// preload photos whenever a matching route has :tag in it

$app->filter('tag_slug', function ($tag_slug){

$app = Jolt::getInstance();

$tag = Model::factory('Tag')->where_equal('slug',$tag_slug)->find_one();

$photos = $tag->photos()->find_many();

$app->store('tag', $tag);

$app->store('photos', $photos);

});

$app->get('/tag/:tag_slug', function($tag_slug){

$app = Jolt::getInstance();

$tag = $app->store('tag');

$photos = $app->store('photos');

$app->render( 'gallery', array(

"pageTitle"=>"viewing Photos for {$tag->name}",

"tag"=>$tag,

"photos"=>$photos

));

});

Notice the $app->filter(), This is a handy method we can set up that will grab the tag and its photos each time the $tag_slug variable is passed, this lets us save on extra queries.

Now, we need to set up a gallery.php page inside views:


<div>

	<h1>#<?php echo $tag->name; ?></h1>

</div>

<hr />

<div>

	<div>

		<div id="container">

			<?php   foreach($photos as $photo){ ?>

			<?php if (file_exists('images/processed/'.$photo->file)){ ?>

		<div>

	<div>

	<a href="<?php echo $uri?>/images/processed/<?php echo $photo->file ?>" title="<?php echo $photo->datetime ?>" >
	<img src="<?php echo $uri?>/images/processed/<?php echo $photo->file ?>" /></a>

	<p><?php echo $photo->datetime?></p>

</div>

</div>

<?php } ?>

<?php } ?>

</div>

</div>

</div>

<script src="//cdnjs.cloudflare.com/ajax/libs/masonry/3.1.1/masonry.pkgd.min.js"></script>

<script type="text/javascript">

var container = document.querySelector('#container');

var msnry = new Masonry( container, {

itemSelector: '.image'

});

</script>

This will display the gallery, and use jQuery masonry to float all the images nicely.


In Conclusion

So that completes our app. You’ve now built a handy little photo wall that can be used to show photos from events. Be sure to checkout the links provided above to learn more about the libraries and frameworks used throughout this article. Thanks for reading.

January 02 2014

22:38

Acceptance Testing With Codeception

Typically new features for web applications are tested by visiting the appropriate page in a browser, maybe filling out some form data, submitting the form, and then developers or testers hope to see their desired result. This is the natural way most web developers test their apps. We can continue with this natural testing process and improve upon it to ensure our apps are as stable as possible by using Codeception.


What Is Codeception?

Codeception is a multi-featured testing framework for PHP. It can handle unit, functional, and acceptance testing of web applications and it’s powered by the already very popular PHPUnit testing framework.

Codeception allows us to test different kinds of user perspectives and site scenarios while they are visiting our app to ensure a pleasant user experience. By testing multiple scenarios, we can simulate a user’s natural flow throughout our application to make sure the app is working as expecting.


Installation & Configuration

Let’s start by creating a folder in our Sites‘s directory (or wherever you prefer to store your web applications) to hold our sample application that we’ll test with Codeception:

cd Sites
mkdir codeception

Now I’ve already created a small sample HTML and PHP file that we can use to test with. You can just copy and paste it from below. We’ll start with the toupper.html file:

# codeception/toupper.html

<!DOCTYPE html>
<html>
<head>
	<title>Convert Me!</title>
</head>
<body>

	<h1>Convert Me!</h1>

	<form action="toupper.php" method="post">

		<label for="string">Convert to Uppercase:</label>
		<input type="text" name="string" id="string">

		<input type="submit" value="Convert">

	</form>

</body>
</html>

This page simply displays a form allowing a user to enter in a string of text and we’ll convert it to uppercase using PHP. Next will be our PHP file which will process the form submission:

# codeception/toupper.php
<?php
$message = "No string entered";

if (!empty($_POST['string'])) {
	$message = "String converted: " . strtoupper($_POST['string']);
}

?>
<!DOCTYPE html>
<html>
<head>
	<title>To Upper!</title>
</head>
<body>

	<h1>To Upper!</h1>

	<p><?php echo $message; ?></p>

	<p><a href="toupper.html">Back to form</a>.</p>

</body>
</html>

This page creates a $message variable to hold a default message. We then check to see if the form was submitted. If so, we replace the default message with the uppercase converted string, then we echo out the message and at the bottom of the page we have a link, linking back to the form.

A super simple PHP application, but it does allow us to try out Codeception’s acceptance testing features.

Now let’s download and install Codeception. Luckily it is very easy to install and configure. There are a couple of ways to install it using either Composer, Git, and installing the Phar. I prefer to use Composer, so let’s create a composer.json file in the root of our codeception sample web app:

cd codeception
touch composer.json

Next, open up composer.json into your favorite text editor and add the following lines to download Codeception:

{
    "require": {
        "codeception/codeception": "*"
    }
}

Then run composer in your terminal:

composer update

To actually install it, run the following command:

./vendor/bin/codecept bootstrap

You’ll notice after running the previous commands, we now have tests and vendor folders in our sample web app.

Next we just need to add our local application’s URL into our tests/acceptance.suite.yml file:

class_name: WebGuy
modules:
    enabled:
        - PhpBrowser
        - WebHelper
    config:
        PhpBrowser:
            url: 'http://localhost/codeception/'

Ok, our sample application and Codeception should now be installed and ready to go.


Acceptance Testing

Acceptance testing allows us to test our applications using the normal website viewing process of visit a webpage, fill in a form, and submit the form to see the desired result. The difference is with Codeception, we don’t have to waste time going to the browser each time we want to test a new feature out, instead we can just run our acceptance tests to see if they pass or not.

Generating an Acceptance Test

Now we need a file that we can write our tests in. Codeception makes it super simple to create different types of tests by using the codecept generator scripts. Let’s generate a Toupper acceptance test:

./vendor/bin/codecept generate:cept acceptance Toupper

Here we run the codecept command again and tell it to generate an acceptance test with the name of Toupper (after file generation, the file will actually be named ToupperCept.php).

Writing an Acceptance Test

When using Codeception you will likely come across the various different “Guys” that run the various different tasks for the framework. There’s a CodeGuy, a TestGuy, and a WebGuy.

For acceptance testing, we’ll be using the WebGuy. Let’s open up our ToupperCept.php file in our favorite text editor and begin by creating a new WebGuy that we can use to run our tests:

$I = new WebGuy($scenario);

Here we create a new WebGuy object, storing it in an $I variable. We can now use this object to test out different parts of our page to ensure everything is correct.

Let’s make sure that our Toupper web page is loading up properly first, then we’ll test out the form submission:

$I = new WebGuy($scenario);
$I->wantTo('ensure Toupper form works');
$I->amOnPage('toupper.html');
$I->see('Convert Me!');

In the above code we use our $I object and call several of its methods to test out our page. We start by stating what we’re wanting to do. In this case, we’re just wanting to make sure our Toupper form works using the wantTo method. Then we use the amOnPage method to ensure we’re on the correct page of toupper.html. Finally we call the see method to ensure we see the text: Convert Me! on the webpage.

Executing Our Test

Now that we have a basic test to see if we’re on the right page and that we’re seeing the correct content, let’s run the test using the following command:

./vendor/bin/codecept run

This will run all test suites. You should see the following output in your console, showing a successful test:

successful-test-1

If you’d like to run only your acceptance tests, you can use the following command:

./vendor/bin/codecept run acceptance

Additionally, you can see the full list of actions performed by using the --steps flag:

./vendor/bin/codecept run acceptance --steps

Here’s what your console would look like:

successful-test-steps

Testing Forms

Next, let’s see how we can use Codeception to test out the functionality of our form. Let’s add the following into our ToupperCept.php file:

$I = new WebGuy($scenario);
$I->wantTo('ensure Toupper form works');
$I->amOnPage('toupper.html');
$I->see('Convert Me!');
$I->fillField('string', "Convert me to upper");
$I->click('Convert');
$I->amOnPage('toupper.php');
$I->see('To Upper!');

Here we just continue where we left off. After ensuring we’re on the right page, we then fill in the form using the fillField method passing it the field name and the value we’d like to use and then we click the Convert button. Afterwards, we verify we are now on the toupper.php page and that we’re seeing our heading of To Upper!.

Let’s run our tests again:

./vendor/bin/codecept run

Your console should have something similar to below, confirming the tests have passed:

successful-form-test

Testing Links

Now lastly, let’s test out the link that’s on our toupper.php page to ensure it takes us back home:

$I = new WebGuy($scenario);
$I->wantTo('ensure Toupper form works');
$I->amOnPage('toupper.html');
$I->see('Convert Me!');
$I->fillField('string', "Convert me to upper");
$I->click('Convert');
$I->amOnPage('toupper.php');
$I->see('To Upper!');
$I->click('Back to form');
$I->see('Convert Me!');

Again, we call the click method to click on our link and to make sure we’re back on the right page, we verify that we see the text Convert Me!.

successful-link-test

In Conclusion

Now that you know the basics of working with Codeception you should give it a try on your own. Go ahead and attempt to add a few more tests to ensure that the form displays the: No string entered error message if you submit the form empty.

Here’s my final code after doing the above and the resulting passed tests:

$I = new WebGuy($scenario);
$I->wantTo('ensure Toupper form works');
$I->amOnPage('toupper.html');
$I->see('Convert Me!');
$I->fillField('string', "Convert me to upper");
$I->click('Convert');
$I->amOnPage('toupper.php');
$I->see('To Upper!');
$I->click('Back to form');
$I->see('Convert Me!');
$I->fillField('string', '');
$I->click('Convert');
$I->amOnPage('toupper.php');
$I->see('No string entered');
successful-final-test

So to wrap up, Codeception is an awesome testing framework that allows you to write very readable tests, easily. Be sure to checkout the full documentation for more detailed examples and for information regarding the other testing paradigms.

December 23 2013

16:24

BDD With Behat

The BDD PHP framework Behat, allows you to test your PHP applications using human-readable sentences to write features and scenarios about how your applications should behave in order to test out its functionality. We can then run these tests to see if our application is behaving as expected. Let’s spend about 15 minutes quickly going over Behat’s installation process and learn how we can test our PHP applications behavior using the basics.


Installation

To begin testing with Behat, we just need to install it on our local development machine. I’ll be using Composer, but you can take a look at a the documentation for additional installation methods.

Within your PHP application (I have a blank PHP app named phpbehat created in advance) create a composer.json file with the following code to load in Behat:

{
	"require": {
		"behat/behat": "2.4.*@stable"
	},
	"minimum-stability": "dev",
	"config": {
		"bin-dir": "bin/"
	}
}

In your terminal we can install it using the following command:

composer update

We should now be able to run the bin/behat command to work with Behat.


Creating Features

We always begin by creating a new feature. A feature is something that we can use to describe a feature of our application and then implement it to get the test to pass.

A feature, at its simplest, consists of:

  • Human-readable, plain text.
  • Uses a .feature extension.
  • Contains the feature’s benefit, role, and the feature itself.
  • May hold a list of scenarios.

Now I can’t show you how to test all possible features for an application, as that would take far too long. But what I can do is show you how to go about writing a basic feature and you can adapt this code to make it work for your specific application.

Testing the Phpadder Class

To avoid complicating the learning process, let’s create a very simple Phpadder.php file which contains a couple methods that we can use to add two numbers together and display their sum.

class Phpadder {

	private $a;
	private $b;
	public $sum;

	public function __construct($a, $b) {
		$this->a = $a;
		$this->b = $b;
	}

	public function add() {
		$this->sum = $this->a + $this->b;
	}

	public function display() {
		return $this->sum;
	}
}

This creates a new class named Phpadder. We have a few properties to hold the first ($a) and second ($b) numbers to be added, as well as a $sum property to hold the values’s sum.

Next, we have our constructor which initializes our properties. Then we have an add method to add the two numbers together and finally a display method to display the sum of the two numbers.

Adder Feature

Let’s now test this Phpadder class. Create a new .feature file along with the following code:

# features/phpadder.feature
Feature: adder
	In order to display the sum of two numbers
	As anybody
	I need to provide two numbers

We start out by giving our feature a name of adder. Then we specify, on three lines, the feature’s benefit, role, and finally the feature itself. It should be fairly self explanatory.

Now that we have our feature, let’s start writing our scenarios.


Creating Scenarios

Anytime we create a feature we can define scenarios that describe how that feature behaves given certain conditions. Scenario’s follow the same basic layout consisting of the scenario’s description, a context, an event, and an outcome.

Let’s create a scenario to test out our Phpadder application:

Scenario: Display the sum of two provided numbers
	Given I have the number 50 and the number 25
	When I add them together
	Then I should get 75

We begin with our scenario description, we then list out that we start with the two numbers of 50 and 25 and when they are added together it should display the sum of 75.

You can also have multiple contexts, events, and outcomes as well using the following keywords: And and But. Here’s a modified example of the previous scenario where we’ll use And:

Scenario: Display the sum of two provided numbers
	Given I have the number 50 and the number 25
	And I have a third number of 25
	When I add them together
	Then I should get 100

Creating Step Definitions

A step is nothing more than a PHP function which is made up of a keyword, a regular expression, and a callback function. Each statement within your scenario will be matched to a step. These steps define what should happen given one of your statements are called within a scenario. You store all of your steps within the features/bootstrap/FeatureContext.php file.

The “Given” Step

In our FeatureContext.php file (you may need to create this), we need to write a step for each of our statements, using its name as the function name. We’ll start with the "Given I have the number" statement:

# features/bootstrap/FeaturesContext.php

require("Phpadder.php");

use Behat\Behat\Context\BehatContext, 
	Behat\Behat\Exception\PendingException;

use Behat\Gherkin\Node\PyStringNode,
	Behat\Gherkin\Node\TableNode;
	
class FeatureContext extends BehatContext {

	private $Adder;
	
	/**
	 * @Given /^I have the number (\d+) and the number (\d+)$/
	 */
	public function iHaveTheNumberAndTheNumber($a, $b) {
		$this->Adder = new Phpadder($a, $b);
	}

First, we create a new PHP file, require in our Phpadder.php file (the file that we’re testing), and then we use a few Behat classes with use statements, right after.

Next, we create our FeatureContext class and have it extend the BehatContext class.

Our class has only one property, $Adder, which will hold a Phpadder object.

Finally, we create a method for our first step using the same name as the statement. Our step has a regular expression, found within the method’s comment. This regular expression is used to match the step to a scenario statement. Within this method we simply assign a new Phpadder object to our $this->Adder property so that the rest of our methods have access to the same Phpadder object.

Now, you’ve probably noticed the @Given keyword within your function’s comment, this is actually an annotation so that the different types of steps can be identified. You can use @Given, @When, and @Then.

Now we just need to write the last two steps.

The “When” Step

/**
 * @When /^I add them together$/
 */
public function iAddThemTogether() {
	$this->Adder->add();
}

This step simply uses our $this->Adder object’s add method to add the two numbers together.

The “Then” Step

/** 
 * @Then /^I should get (\d+)$/ 
 */
public function iShouldGet($sum) {
	if ($this->Adder->sum != $sum) {
		throw new Exception("Actual sum: ".$this->Adder->sum);
	}
	$this->Adder->display();
}

This step starts off by checking if the actual sum (retrieved using our $this->Adder object and its sum property) is not equal to the expected sum. If this evaluates to true that means we need to have Behat show a failure. To do so, we’ll just throw a new exception displaying the actual sum so we can compare. Otherwise, we call our display method.

Time to run the tests.


Running the Tests

Now that we have our features, scenarios, and steps laid out, let’s run our tests using the following command:

bin/behat

You should see the following success messages inside of your terminal:

testing-success

You can ensure that your tests are running correctly, by simply breaking something in your Phpadder.php file so that it doesn’t run quite the same way your test expects it to. For example, if we change the add method to instead use subtraction, like so:

public function add() {
	$this->sum = $this->a - $this->b;
}

And then we rerun our tests: bin/behat. You can see in our terminal, we now have a failing test, because it’s no longer adding our numbers but subtracting them:

testing-fail

Conclusion

In conclusion, you can follow a small four step process for testing your PHP apps using Behat:

  1. Define a Feature
  2. Define a Scenario
  3. Define Step Definitions
  4. Run the tests using bin/behat

So, with just that small amount of code, we should now have a basic understanding of how to work with Behat to test our PHP applications. For more information about working with Behat please checkout their documentation.

December 17 2013

19:25

Sending Emails With Laravel 4 & Gmail

Sending emails is crucial for any web application. Usually, an email is sent to notify the user of some kind of activity that has taken place on the site, for example, such as when updates have been made or when new friends have been found. In this short tutorial, I’ll show you how to send emails with Gmail quickly from within a Laravel sample application by extending the functionality that we built in my last tutorial, Authentication With Laravel 4.

So, we’ll take that authentication application (you can download the previous tutorial’s source code on Github to give you a starting point) that we ended with last time and add in a new feature so that whenever a user registers for the site, we’ll send them a confirmation email, welcoming them to the app!


Mail Configuration

Before we can send emails with Laravel 4 we need to configure the app/config/mail.php file. In this file we can set the following options:

OptionDescriptiondriverThe mailing driver you’d like to use. By default, this is set to SMTP, but you can also change it to use PHPs mail feature or Sendmail instead.hostThis is your SMTP server’s host address.portYour SMTPs port.fromThis allows you to set the from field in your email, so that all emails are sent from the same address.encryptionThis is the encryption protocol that will be used whenever emails are sent.usernameThis is your SMTP username.passwordThis is your SMTP password.sendmailThis is the path to where Sendmail can be found on the server, when using the sendmail driver.pretendWhen set to true, emails will be logged to a log file, rather than actually sending a real email message.

Sending Mail With Gmail

For this tutorial I’m going to be using Gmail to send my email messages as it’s super simple to use. All you need in order to send mail with Gmail is to have an active Gmail account, with a username and password. I’ll provide you with everything else. Let’s edit our app/config/mail.php file to look something like this (I removed the comments to make the code more compact):

return array(

	'driver' => 'smtp',

	'host' => 'smtp.gmail.com',

	'port' => 587,

	'from' => array('address' => 'authapp@awesomeauthapp. com', 'name' => 'Awesome Laravel 4 Auth App'),

	'encryption' => 'tls',

	'username' => 'your_gmail_username',

	'password' => 'your_gmail_password',

	'sendmail' => '/usr/sbin/sendmail -bs',

	'pretend' => false,

);

Here I’ve left the driver set to smtp. I set the host to use smtp.gmail.com which is Gmail’s SMTP server. I set the port to 587, the from to a fake email address which sounds fitting for our application. I left the encryption set to tls and finally you’ll then want to enter in your own Gmail username and password for your account and leave pretend set to false.


Sending Mail

Example Code

For this application, whenever a user successfully registers, we want to send them an email welcoming them to the site. Sending emails with Laravel is done by using the Mail::send() method. Here’s a small snippet of code, for example purposes:

Mail::send('folder.view', $data, function($message) {
	$message->to('registered-user@gmail. com', 'Jon Doe')->subject('Welcome to the Laravel 4 Auth App!');
});

The first argument is the view file we’d like to use in order to format our email message. The second argument is any data that we’d like to pass to that view file. The third argument is a closure which accepts a $message object that we can use to tell the mailer who we’re sending the email to and what the subject of this email will be. In this closure, you can also specify other options such as attachments, etc. This will then send out the email to the user.

Pretty easy right?

Sending Emails Upon Successful Registration

Let’s now modify our UsersController‘s postCreate() action and take what we’ve learned about sending emails to send a welcome email message to our users, whenever they register for the app.

Within our postCreate() action’s if statement, where we check if the validation has passed, right after where we save the user into the database, let’s add in the following code:

if ($validator->passes()) {
	$user = new User;
	$user->firstname = Input::get('firstname');
	$user->lastname = Input::get('lastname');
	$user->email = Input::get('email');
	$user->password = Hash::make(Input::get('password'));
	$user->save();

	Mail::send('users.mails.welcome', array('firstname'=>Input::get('firstname')), function($message){
		$message->to(Input::get('email'), Input::get('firstname').' '.Input::get('lastname'))->subject('Welcome to the Laravel 4 Auth App!');
	});

	return Redirect::to('users/login')->with('message', 'Thanks for registering!');
} else {
	return Redirect::to('users/register')->with('message', 'The following errors occurred')->withErrors($validator)->withInput();
}

Here we’ve called the Mail::send() method and told it to use a users.mails.welcome view file. We then pass in an array as the data that should be available within the view file, in this case we just sent in the users first name, using the Input::get('firstname') method. Next, we create our closure and set this to send the email to the user’s email address. We also set the name using the user’s first and last name from the form. Lastly, we just give this a pretty generic subject(you can use whatever subject you’d like), so the user knows what all the fuss is about.

Creating the Email View File

Now we need to create our welcome email view file. Under app/views/users create a new folder named mails and inside of it create a new file named welcome.blade.php and add in the following code:

<h1>Hi, {{ $firstname }}!</h1>

<p>We'd like to personally welcome you to the Laravel 4 Authentication Application. Thank you for registering!</p>

In this view file we just have some basic HTML, using the $firstname variable that we passed as data from our controller to the view, welcoming the user to the application. There’s not much to it, you can use your view files for emails just like you do for any other view.

Let’s Try It Out

Make sure to start up your webserver using php artisan serve and we can visit localhost:8000/users/register, then create a new user:

laravel-auth-create-user

… and then check that user’s email account to verify that the email was sent successfully:

laravel-auth-emai-sent

Perfect! Our email was sent.


In Conclusion

And that’s all there is to sending email messages with Laravel 4 and Gmail. You can of course customize your email messages as much as you’d like to make the mail more appealing.

Now this is the most basic way to send mail with Laravel and it can slow your app down, as it sends the email, but you do have other options. You’ll continue to use Laravel’s mail class but instead of sending it immediately, you can queue up your emails to have them sent out in the background, without making your users wait. But this topic is best saved for a separate article.

For more information on sending email with Laravel check out the online documentation. Thanks for reading.

December 13 2013

18:28

SOLID: Part 1 – The Single Responsibility Principle

Single Responsibility (SRP), Open/Close, Liskov’s Substitution, Interface Segregation, and Dependency Inversion. Five agile principles that should guide you every time you write code.


The Definition

A class should have only one reason to change.

Defined by Robert C. Martin in his book Agile Software Development, Principles, Patterns, and Practices and later republished in the C# version of the book Agile Principles, Patterns, and Practices in C#, it is one of the five SOLID agile principles. What it states is very simple, however achieving that simplicity can be very tricky. A class should have only one reason to change.

But why? Why is it so important to have only one reason for change?

In statically typed and compiled languages, several reasons may lead to several, unwanted redeployments. If there are two different reasons to change, it is conceivable that two different teams may work on the same code for two different reasons. Each will have to deploy its solution, which in the case of a compiled language (like C++, C# or Java), may lead to incompatible modules with other teams or other parts of the application.

Even though you may not use a compiled language, you may need to retest the same class or module for different reasons. This means more QA work, time, and effort.


The Audience

Determining the one single responsibility a class or module should have is much more complex than just looking at a checklist. For example, one clue to find our reasons for change is to analyze the audience for our class. The users of the application or system we develop who are served by a particular module will be the ones requesting changes to it. Those served will ask for change. Here are a couple of modules and their possible audiences.

  • Persistence Module – Audience include DBAs and software architects.
  • Reporting Module – Audience include clerks, accountants, and operations.
  • Payment Computation Module for a Payroll System – Audience may include lawyers, managers, and accountants.
  • Book Search Module for a Library Management System – Audience may include the librarian and/or the clients themselves.

Roles and Actors

Associating concrete persons to all of these roles may be difficult. In a small company a single person may need to satisfy several roles while in a large company there may be several persons allocated to a single role. So it seems much more reasonable to think about the roles. But roles by themselves are quite difficult to define. What is a role? How do we find it? It is much easier to imagine actors doing those roles and associating our audience with those actors.

So if our audience defines reasons for change, the actors define the audience. This greatly helps us to reduce the concept of concrete persons like “John the architect” to Architecture, or “Mary the referent” to Operations.

So a responsibility is a family of functions that serves one particular actor. (Robert C. Martin)


Source of Change

In the sense of this reasoning, actors become a source of change for the family of functions that serves them. As their needs change, that specific family of functions must also change to accommodate their needs.

An actor for a responsibility is the single source of change for that responsibility. (Robert C. Martin)


Classic Examples

Objects That Can “Print” Themselves

Let’s say we have a Book class encapsulating the concept of a book and its functionalities.

class Book {

	function getTitle() {
		return "A Great Book";
	}

	function getAuthor() {
		return "John Doe";
	}

	function turnPage() {
		// pointer to next page
	}

	function printCurrentPage() {
		echo "current page content";
	}
}

This may look like a reasonable class. We have book, it can provide its title, author and it can turn the page. Finally, it is also able to print the current page on the screen. But there is a little problem. If we think about the actors involved in operating the Book object, who might they be? We can easily think of two different actors here: Book Management (like the librarian) and Data Presentation Mechanism (like the way we want to deliver the content to the user – on-screen, graphical UI, text-only UI, maybe printing). These are two very different actors.

Mixing business logic with presentation is bad because it is against the Single Responsibility Principle (SRP). Take a look at the following code:

class Book {

	function getTitle() {
		return "A Great Book";
	}

	function getAuthor() {
		return "John Doe";
	}

	function turnPage() {
		// pointer to next page
	}

	function getCurrentPage() {
		return "current page content";
	}

}

interface Printer {

	function printPage($page);
}

class PlainTextPrinter implements Printer {

	function printPage($page) {
		echo $page;
	}

}

class HtmlPrinter implements Printer {

	function printPage($page) {
		echo '<div style="single-page">' . $page . '</div>';
	}

}

Even this very basic example shows how separating presentation from business logic, and respecting SRP, gives great advantages in our design’s flexibility.

Objects That Can “Save” Themselves

A similar example to the one above is when an object can save and retrieve itself from presentation.

class Book {

	function getTitle() {
		return "A Great Book";
	}

	function getAuthor() {
		return "John Doe";
	}

	function turnPage() {
		// pointer to next page
	}

	function getCurrentPage() {
		return "current page content";
	}

	function save() {
		$filename = '/documents/'. $this->getTitle(). ' - ' . $this->getAuthor();
		file_put_contents($filename, serialize($this));
	}

}

We can, again identify several actors like Book Management System and Persistence. Whenever we want to change persistence, we need to change this class. Whenever we want to change how we get from one page to the next, we have to modify this class. There are several axis of change here.

class Book {

	function getTitle() {
		return "A Great Book";
	}

	function getAuthor() {
		return "John Doe";
	}

	function turnPage() {
		// pointer to next page
	}

	function getCurrentPage() {
		return "current page content";
	}

}

class SimpleFilePersistence {

	function save(Book $book) {
		$filename = '/documents/' . $book->getTitle() . ' - ' . $book->getAuthor();
		file_put_contents($filename, serialize($book));
	}

}

Moving the persistence operation to another class will clearly separate the responsibilities and we will be free to exchange persistence methods without affecting our Book class. For example implementing a DatabasePersistence class would be trivial and our business logic built around operations with books will not change.


A Higher Level View

In my previous articles I frequently mentioned and presented the high level architectural schema that can be seen below.

HighLevelDesign

If we analyze this schema, you can see how the Single Responsibility Principle is respected. Object creation is separated on the right in Factories and the main entry point of our application, one actor one responsibility. Persistence is also taken care of at the bottom. A separate module for the separate responsibility. Finally, on the left, we have presentation or the delivery mechanism if you wish, in the form of an MVC or any other type of UI. SRP respected again. All that remains is to figure out what to do inside of our business logic.


Software Design Considerations

When we think about the software that we need to write, we can analyze many different aspects. For example, several requirements affecting the same class may represent an axis of change. This axes of change may be a clue for a single responsibility. There is a high probability that groups of requirements that are affecting the same group of functions will have reasons to change or be specified in the first place.

The primary value of software is ease of change. The secondary is functionality, in the sense of satisfying as much requirements as possible, meeting the user’s needs. However, in order to achieve a high secondary value, a primary value is mandatory. To keep our primary value high, we must have a design that is easy to change, to extend, to accommodate new functionalities and to ensure that SRP is respected.

We can reason in a step by step manner:

  1. High primary value leads in time to high secondary value.
  2. Secondary value means needs of the users.
  3. Needs of the users means needs of the actors.
  4. Needs of the actors determines the needs of changes of these actors.
  5. Needs of change of actors defines our responsibilities.

So when we design our software we should:

  1. Find and define the actors.
  2. Identify the responsibilities that serve those actors.
  3. Group our functions and classes so that each has only one allocated responsibility.

A Less Obvious Example

class Book {

	function getTitle() {
		return "A Great Book";
	}

	function getAuthor() {
		return "John Doe";
	}

	function turnPage() {
		// pointer to next page
	}

	function getCurrentPage() {
		return "current page content";
	}

	function getLocation() {
		// returns the position in the library
		// ie. shelf number & room number
	}

}

Now this may appear perfectly reasonable. We have no method dealing with persistence, or presentation. We have our turnPage() functionality and a few methods to provide different information about the book. However, we may have a problem. To find out, we might want to analyze our application. The function getLocation() may be the problem.

All of the methods of the Book class are about business logic. So our perspective must be from the business’s point of view. If our application is written to be used by real librarians who are searching for books and giving us a physical book, then SRP might be violated.

We can reason that the actor operations are the ones interested in the methods getTitle(), getAuthor() and getLocation(). The clients may also have access to the application to select a book and read the first few pages to get an idea about the book and decide if they want it or not. So the actor readers may be interested in all the methods except getLocations(). An ordinary client doesn’t care where the book is kept in the library. The book will be handed over to the client by the librarian. So, we do indeed have a violation of SRP.

class Book {

	function getTitle() {
		return "A Great Book";
	}

	function getAuthor() {
		return "John Doe";
	}

	function turnPage() {
		// pointer to next page
	}

	function getCurrentPage() {
		return "current page content";
	}

}

class BookLocator {

	function locate(Book $book) {
		// returns the position in the library
		// ie. shelf number & room number
		$libraryMap->findBookBy($book->getTitle(), $book->getAuthor());
	}

}

Introducing the BookLocator, the librarian will be interested in the BookLocator. The client will be interested in the Book only. Of course, there are several ways to implement a BookLocator. It can use the author and title or a book object and get the required information from the Book. It always depends on our business. What is important is that if the library is changed, and the librarian will have to find books in a differently organized library, the Book object will not be affected. In the same way, if we decide to provide a pre-compiled summary to the readers instead of letting them browse the pages, that will not affect the librarian nor the process of finding the shelf the books sits on.

However, if our business is to eliminate the librarian and create a self-service mechanism in our library, then we may consider that SRP is respected in our first example. The readers are our librarians also, they need to go and find the book themselves and then check it out at the automated system. This is also a possibility. What is important to remember here is that you must always consider your business carefully.


Final Thoughts

The Single Responsibility Principle should always be considered when we write code. Class and module design is highly affected by it and it leads to a low coupled design with less and lighter dependencies. But as any coin, it has two faces. It is tempting to design from the beginning of our application with SRP in mind. It is also tempting to identify as many actors as we want or need. But this is actually dangerous – from a design point of view – to try and think of all the parties from the very beginning. Excessive SRP consideration can easily lead to premature optimization and instead of a better design, it may lead to a scattered one where the clear responsibilities of classes or modules may be hard to understand.

So, whenever you observe that a class or module starts to change for different reasons, don’t hesitate, take the necessary steps to respect SRP, however don’t overdue it because premature optimization can easily trick you.

December 10 2013

20:00

Statamic 101

Statamic is a modern PHP CMS which really makes an effort to be easy and intuitive to use. From its flat-file design to its use of technologies, like markdown and Yaml, you can accomplish an outstanding amount of work without writing any code at all.

In this article we will take a look at the process from installation to setting up a basic portfolio.

Having a flat-file design, setup is as simple as extracting the zip file you’ll download from their site. There is no database involved, all the content and settings are stored locally in a host of different files, this also means you have automatic backups and versioning on all of your content, if you use something like GIT.

With the contents extracted, let's take a look at Statamic’s structure.


The File Structure

There are more or less five different folders you will most likely be interacting with, and they are:

  • _config is where all your settings are held
  • _content is where you will put your Markdown files
  • _add-ons is for Statamic add-ons
  • _themes is where you build your theme
  • assets is where you can stick resources for your site

Besides these, you have the following four folders that you probably won't touch directly:

  • _app – Statamic’s own source code
  • _cache – Where Statamic caches all your content
  • _logs – Where Statamic will store your logs
  • admin – The Statamic admin panel

But the first step in every Statamic site is to configure its options.


Configuration

All the configuration files are inside the _config folder like we just saw, the main file you should take a look at is the settings.yaml.

If you are new to Yaml, then all you really need to know, is that it's a data format similar to JSON except that it's meant to be a more human-readable format. It accomplishes this by not requiring any separating characters like semi-colons or quotation marks, instead it get's its structure from placement and indentation.

The settings.yaml file is really well documented so you shouldn't have a problem filling it out, some of the options you will probably want to look at are the following:

_license_key: Enter your License Key
_site_name: My Portfolio
_site_url: http://localhost:7000
_theme: portfolio
_taxonomy: 
   - language
_log_enabled: true
_cookies.secret_key: Some Random Key

Most of these are pretty straight forward, like setting the license key, your site's name and URL. The theme option sets which theme folder to load. We will get into this in a moment, but a theme is essentially the place where you specify how the different pages on your site will work. We will be creating our own theme so you can name it whatever you want, I chose ‘portfolio’.

The next option is an array called taxonomy, if you have ever used something like WordPress, then you should know what this is for, basically it allows you to add a setting or 'type' to each post, which you can then use these taxonomies to filter your content and create custom pages for these groupings.

I am just adding one taxonomy; the language taxonomy, because in our example portfolio we are going to specify each work’s programming languages. You don’t need to create a taxonomy for each custom property, we are going to want other things in our portfolio, like links and descriptions. A taxonomy is for fields that multiple entries have in common, and for fields that you may want to create a custom page for.

The log_enabled setting turns on logging, so you can view problems which come up from the admin panel, they will be stored in the _logs folder we saw earlier. Finally the last option I mentioned is the secret key used to encrypt the cookie.

This file can now be saved out, but before we move onto content, let's take a moment to setup the portfolio template so we can see what we are doing.


Theme Basics

The template is a specific view for a single page.

Like most modern frameworks, when you load a page, you can build it up from multiple reusable components. A page in Statamic is made up of a layout a template and a content file. Both the layout files and templates can optionally also be made of even more pieces called partials.

The layout is the outer shell in which your template will be placed; this is usually used to hold the boilerplate HTML code like the head section, and as-well as the basic body that all the pages using this layout will need, like adding common libraries at the bottom of your file.

The template is a specific view for a single page. Like you can have a home page template, a contact page template, etc.. You don't need to create on per page, but I would say one per type of page.

In these templates you have the ability to use variables stored in the actual content files, so say you need a page which displays an index of books you are reading, and then another page to display a list of shows you are watching; instead of replicating most of the code for each one, you can create one template for displaying a list of objects, and then pull in the specifics of which list to retrieve from the content file itself.

The content file – like its name suggests – is the actual resource being displayed, this can range from things like an actual unique web page, to a single blog entry. We will get to these in more details in a moment.

Now instead of manually creating all these different components, Statamic provides a sort of starter template, giving you a basic structure to get started. You can download the theme folder from here.

Just place the entire folder into the _themes directory, and rename it to portfolio (as that's the theme name we declared in the settings file). You also need to rename the kindling.js file from the js folder and the kindling.css file from the css directory, to portfolio.js and portfolio.css respectively, as their is a special tag to pull these in automatically.

That's all the setup we need now, but to get a better idea of what I was talking about regarding the layout/template, let's take a look at those files. To begin with open up the file named default.html from the layouts folder, this corresponds to the default layout as you may have guessed.

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>{{ _site_name }}</title>
        <link rel="stylesheet" href="{{ theme:css }}">
    </head>
    <body>

        {{ layout_content }}

        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
        <script src="{{ theme:js }}"></script>

    </body>
</html>

Like I mentioned earlier, the layout is a good place to put code that is required on multiple pages (or templates rather), which is why the default layout in this file just contains the basic outline of an HTML file. Now we haven't really talked about it yet, but Statamic comes with its own templating engine, which is fairly easy to pick up, you basically just place a tag where you want something to be inserted similar to Handlebars if you are familiar.

This layout contains a couple of tags which I thought I would go through, the first of which is _site_name. This tag actually refers to the property we set up inside of the settings.yaml file. You will find this convention all throughout Statamic, you can set yaml options either globally like this, or even on a per-file basis, you can then get these options just by placing a tag with their names into your templates.

Helpers in Statamic are more like independent modules.

The next tag, which actually comes up twice is the theme tag. Helpers in Statamic are more like independent modules, so they can have multiple different functions attached to the same name; you access the individual functions with a colon and then the name of the command you want.

The theme tag is all about loading in resources specific to this theme, it can be used to pull in things like scripts and stylesheets, but also things like images and partials. It's a helper function that basically allows you to just provide the name of the resource you want and it will fill in the path to the current templates directory. So for instance if you were to write:

{{ theme:js src="underscore.js" }}

It would replace that with a link to a file named underscore.js inside of the current theme’s js folder. By default if no src parameter is set for the js or css command, it will assume you are referring to a js or css file with the name of the current theme, which is why we renamed those files to match; it's just a matter of convenience so we don't need to specify them and it cleans up the source a little bit.

The next tag that comes up is {{ layout_content }}; this is similar to yield in other templating engines, and it basically signifies where the inner template should be inserted.

The last thing I want to do in this file is remove the link to jQuery, just because I won't be using it (if you will then you can of-course leave it).

Next let's move onto the default template file (templates/default.html), it should be blank. For illustrations sake, let's just add a tag called {{content}} which just inserts the contents of the current page being loaded.

So to recap when you goto a page it will first load the layout file, and then wherever the {{layout_content}} tag is placed this template will get inserted. This template will then just output whatever the current page has inside.

With that done, save out these files and let's move onto content.


The Content

Content in Statamic is specified in markdown files by default, and the default file which is loaded is called page.md. What I mean by this is that the same way standard web server will load index.html if no file was specified, Statamic will load page.md.

It's also worth noting that routes, or URL links in your site will be defined by the _content directory. So for example if you create a folder named 'demo' inside of the _content directory, and in it place a file named 'link.md' this will correspond to the URL /demo/link; and if you place a page.md file inside, it will be loaded if you navigate to /demo/ since it is the default file name.

Statamic comes with some demo content, but you can just delete everything inside the _content directory for this example (or move it aside for now).

Let's start with a basic home page, so at the root of the _content directory, create a file named page.md with the following:

---
title: Home
---

# Welcome to the {{title}} Page

All content files are basically split into two sections, the Yaml front-matter and the contents. The top part (between the dashed lines) is where you can put standard Yaml specific to this file, and is a good way for setting options to adjust your template files. The second part is the markdown area, where you put the contents of the actual page. You can use standard markdown as-well as Statamic helper tags.

This page will load with the default layout and template files we just setup, but if you want it to use a different one, you can specify these as options in the Yaml section at the top using _layout and _template respectively.

If you create a server at the root of your Statamic directory:

php -S localhost:7000

and then navigate to http://localhost:7000 in your browser you should see the H1 tag with our welcome message.

This is all you need to know to create pages in Statamic, and if you are building a fairly static site, this would be enough. But in a lot of sites we need to be able to add dynamic data, which can take the form of blog posts, shop items, or in our case portfolio works.


Entries

If you recall there is no database in Statamic, so these kinds of entries are stored in markdown files just like the page we just built, although a couple of things were done to subtly introduce multiple features to optimize things and to make it work in the admin.

First off you can name the files with a special date format so they can be sorted and filtered by date. You do this by pre-pending the title with a year-month-day pattern, so say you want to create a post named 'foobar' you would name it something like:

2013-09-15-foobar.md

Inside you would put all the posts settings inside the front-matter section for use in the template, and then any content underneath; just like in a page.

Now this is pretty cool, but it's the equivalent of manually entering posts into a database of a traditional system; there is another option.

Statamic comes bundled with a really nice admin, which can do all this for you, but in order to get it setup we need to tell it which fields this type of entry is supposed to have. This is done in a file appropriately named fields.yaml.

So for our example let's create a folder inside the _content directory named works, and inside the works folder let's create a file named fields.yaml. Inside the fields.yaml file we need to specify which properties our 'entries' will contain and the individual types for each of these settings.

You can either specify your fieldset (the list of fields) in the _config/fieldsets/ directory and pull in a definition, or you can just enter the definition here (or you can do both to extend an existing definition). For our simple example I am just going to put the definition here since we won't be reusing it anywhere:

type: date
fields:
 language:
   type: tags
   display: Programming Language
   required: true

 description:
    type: text
    display: Description
    required: false

 link:
    type: text
    display: Link
    required: true

 content:
    type: hidden

The first property just tells Statamic that we want these entry files to have a date property and to be named appropriately. Next we open up a YAML object named fields containing all our work entry's properties.

The first is the language field, which if you remember is the taxonomy we created in the settings.yaml. Inside each property we need to specify its type (or it defaults to a text box) its display text (which will default to the properties name) and whether it is required. There are other options you can set as-well like instructions or the default value, which you can view more information about here, besides for these settings different field types can have their own custom options.

For the language input I set it to use the tag type, which basically allows you to set multiple tags for this option, it's just a different type of input for entering its value in the admin. You can view all the different fieldtypes here or from the official cheat sheet under 'Fieldtypes'.

The description and link are pretty much the same, they will both be text boxes except one will be required and one won't be. Besides the fields you specify all entries will come with a title and content field. We don't really want a content field in our works they will be more like links, so I just set it to hidden.

The last step before we go to the admin, is to create a page.md file inside the works directory. This isn't really required but the admin will attempt to get the title of this entry type from here so it's a good idea to just place it. So create a page.md file inside the works folder with just the title set to 'Works':

---
title: Works
---  

The Admin

To get into the admin we need to first create a user; again this is a simple yaml file inside of the config folder. The name of the file is the username you will use to login, and inside you configure the user's details and password.

So let's create a new user with a username of editor, again we do this by creating a file called 'editor.yaml' inside of the _config/users/ folder. Insert the following data (except with your info):

--- 
first_name: Gabriel
last_name: Manricks
roles: [admin]
email: gmanricks@gmail.com
password: password
---

The Editor of this Portfolio

Most of these columns are pretty straight forward and I don't think they require any explanation. The only field worth mentioning is the roles setting. Currently admin is the only option available, but in the future this will be where you would be able to adjust who can edit what.

It's also worth mentioning that the password will not stay in plain-text. After the first login, Statamic will hash the password along with a salt and include those here instead.

Everything after the dashed lines will just be stored as the content for this user, and can be used as a sort of bio for them.

Now save this file, and if your web server is still running, navigate to /admin in your browser. This will open up the login console where you can enter these properties. Like I mentioned the first time you login you will need to do this twice, once to hash the password, and the second time to actually login.

Admin Login The Statamic Login

Once in you will see a list of our pages, included is our home page as-well as the 'Works' entry type. Let's take a look at what our fields declaration did for us; click on the Create link inside of the 'Works' bar.

Pages Admin

You should see a nice form which includes all the fields we specified along with the tite, for this demos sake, just add a few posts.

Demo Post

With some posts stored, we have completed round one; you now know how to create pages, themes, users, and entries, it's a great first step. But there is alot more Statamic has to offer.


The Templating Engine

Having some posts created is nice, but what would be better is if we could actually display them on a page. For this we will need to edit the default template.

This will be our first real interaction with the included templating engine, but not to worry, Statamic's intuitive design makes it almost 'obvious' to pick up.

To view a full list of the available tags you can take a look at the official doc page on the matter. But all we really need in our example is the entries tag, which is used to pull in entries from a specific folder in the _content directory. There are a lot of optional properties, allowing you to filter by date, or conditions like taxonomies or even standard properties. We are going to keep it simple and just list the properties by date (which is the default).

Here is the complete new default template (templates/default.html):

<h1>Portfolio</h1>

<table>
 {{ entries:listing folder="works" }}
     <tr>
         <td class="lang"><p>{{ language }}</p></td>
         <td class="work">
             <a href="{{ link }}">
                 <span class="title">{{ title }} - </span>
                 <span class="desc">{{ description }}</span>
             </a>
         </td>
     </tr>
 {{ /entries:listing }}
</table>

In this code we are creating a table and just looping through all posts in the 'works' directory. These kind of block tags, where you place more HTML inside, basically assign new placeholders. Besides for providing access to things like all the post's attributes, you also get special helper variables which can tell you things like the current index, or whether this is the first or last post. We won't be using any of those variables, all we need is to display the title / language / description and link. However if you load up the page in your browser, you will probably realize that instead of showing the language it just says "Array".

This is because we set this property to be of type tag, which means it could hold more than one language, so even though you may have only put one language, it is still being stored in an array. Luckily besides for these tag helpers, Statamic comes with modifiers.


Modifiers

To finish off this guide, let's take a look at a few modifiers which will allow us to make this page even better.

The first and biggest problem is making the language show up. If you take a look at the following cheat sheet, all the way at the bottom left, you will see a section named List Shortcuts. While not technically being modifiers, Statamic allows you to append these words to the end of a list variable, and it will instead return a string representation. The one I want to use in this situation is the standard _list helper. What this will do is separate multiple values in the array with a comma and space, and is what we would want in our situation.

To try it out, replace the {{ language }} tag to {{ language_list }}. Refreshing your browser it should be displaying the languages correctly now.

Next let's add a modifier to the title to make it all uppercase. If you have ever used something like the smarty templating engine, then it works the same way. You add a pipe to the end of the variable name and then add a modifier. In our example you just need to replace the call to {{ title }} with {{ title|upper }} and these are chainable so you can keep adding pipes indefinitely.

Now let's just add some CSS to style everything up (remember this goes in the css/portfolio.css file:

body { background: #FAFAF5; }

h1 {
 font: 800 64px 'Raleway', sans-serif;
 margin-bottom: 28px;
}

table { font: 15px 'Coustard', serif; }

td { padding: 10px 10px 0 10px; }
p { margin-bottom: 15px; }

.lang p {
 background: #CA9F53;
 color: #FFF;
 padding: 3px 5px;
 text-align: right;
}

.work { text-align:left; }
.work a{
 border-bottom: 1px solid #000;
 text-decoration: none;
}

.title {
 font-weight: 600;
 color: #000;
}

.desc { color: #666; }

And these two fonts are from Google Fonts, so you will need to add the following link at the top of your default layout file:

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="utf-8" />
 <title>{{ _site_name }}</title>
 <link href='http://fonts.googleapis.com/css?family=Coustard|Raleway:800' rel='stylesheet' type='text/css'>
 <link rel="stylesheet" href="{{ theme:css }}">
</head>
<body>

 {{ layout_content }}

 <script src="{{ theme:js }}"></script>

</body>
</html>

If everything worked out you should see the following page (except with the works you added)

The Demo

Conclusion

Where I think this will thrive is as a blogging platform or CMS.

In this article we have went through the entire process from installing the framework, to setting everything up, creating a new entry type, and building a custom theme. It's a lot to do, and it's only possible because of how easy Statamic makes things.

We have seen alot of functionality already and we haven't even touched on creating your own modules, and extending Statamic with PHP, but I think the most amazing thing is we haven’t even written a single line of PHP in this entire article! And that is something to brag about.

So I think the main question people might have is, should I use it, or what should this replace in my current repertoire? It's important to gauge what Statamic is for. If you are building a new Startup and need the full flexibility of a full fledged framework, I am sure you would be able to get it running in Statamic, but it would be alot of custom code, which may defeat the purpose. Where I think this will thrive is as a blogging platform or CMS.

Coming from a background in WordPress, this feels like a direct predecessor, in that it follows a-lot of the same conventions in theory, but they are all implemented in a much smarter way, in that comparing the amount of code required in each becomes a joke. Moving forward, Statamic has an incredible API for building custom tags, hooks, new fieldtypes and more, and you can imagine Statamic makes it as lean and simple to do as you might have come to expect.

I hope you enjoyed this article, if you have any questions feel free to ask me below, on twitter @gabrielmanricks or on the Nettuts+ IRC channel on freenode (#nettuts).

December 02 2013

11:00

Pico: Free, File-based Content Management System for PHP-Developers


  

Pico is the name of a fairly new CMS, which doesn’t need any database connection at all. Its developer Gilbert Pellegrom calls the system "stupidly simple". I’d object and say, that this is only true for developers. If you are a PHP aficionado and like to write your posts using Markdown, Pico might just be the CMS for you.

November 25 2013

14:00

The Repository Design Pattern

The Repository Design Pattern, defined by Eric Evens in his Domain Driven Design book, is one of the most useful and most widely applicable design patterns ever invented. Any application has to work with persistence and with some kind of list of items. These can be users, products, networks, disks, or whatever your application is about. If you have a blog for example, you have to deal with lists of blog posts and lists of comments. The problem that all of these list management logics have in common is how to connect business logic, factories and persistence.


The Factory Design Pattern

As we mentioned in the introductory paragraph, a Repository will connect Factories with Gateways (persistence). These are also design patterns and if you are not familiar with them, this paragraph will shed some light on the subject.

A factory is a simple design pattern that defines a convenient way to create objects. It is a class or set of classes responsible for creating the objects our business logic needs. A factory traditionally has a method called "make()" and it will know how to take all the information needed to build an object and do the object building itself and return a ready-to-use object to the business logic.

Here is a little bit more on the Factory Pattern in an older Nettuts+ tutorial: A Beginner’s Guide to Design Patterns. If you prefer a deeper view on the Factory Pattern, check out the first design pattern in the Agile Design Patterns course we have on Tuts+.


The Gateway Pattern

Also known as “Table Data Gateway” is a simple pattern that offers the connection between the business logic and the database itself. Its main responsibility is to do the queries on the database and provide the retrieved data in a data structure typical for the programming language (like an array in PHP). This data is then usually filtered and modified in the PHP code so that we can obtain the information and variables needed to crate our objects. This information must then be passed to the Factories.

The Gateway Design Pattern is explained and exemplified in quite great detail in a Nettuts+ tutorial about Evolving Toward a Persistence Layer. Also, in the same Agile Design Patterns course the second design pattern lesson is about this subject.


The Problems We Need to Solve

Duplication by Data Handling

It may not be obvious at first sight, but connecting Gateways to Factories can lead to a lot of duplication. Any considerable sized software needs to create the same objects from different places. In each place you will need to use the Gateway to retrieve a set of raw data, filter and work that data to be ready to be sent to the Factories. From all these places, you will call the same factories with the same data structures but obviously with different data. Your objects will be created and provided to you by the Factories. This will, inevitably lead to a lot of duplication in time. And the duplication will be spread throughout distant classes or modules and will be difficult to notice and to fix.

Duplication by Data Retrieval Logic Reimplementation

Another problem we have is how to express the queries we need to do with the help of the Gateways. Each time we need some information from the Gateway we need to think about what do we exactly need? Do we need all the data about a single subject? Do we need only some specific information? Do we want to retrieve a specific group from the database and do the sorting or refined filtering in our programming language? All of these questions need to be addressed each time we retrieve information from the persistence layer through our Gateway. Each time we do this, we will have to come up with a solution. In time, as our application grows, we will be confronted with the same dilemmas in different places of our application. Inadvertently we will come up with slightly different solutions to the same problems. This not only takes extra time and effort but also leads to a subtle, mostly very difficult to recognize, duplication. This is the most dangerous type of duplication.

Duplication by Data Persistence Logic Reimplementation

In the previous two paragraphs we talked only about data retrieval. But the Gateway is bidirectional. Our business logic is bidirectional. We have to somehow persist our objects. This again leads to a lot of repetition if we want to implement this logic as needed throughout different modules and classes of our application.


The Main Concepts

Repository for Data Retrieval

A Repository can function in two ways: data retrieval and data persistence.

UMLRepoQuery

When used to retrieve objects from persistence, a Repository will be called with a custom query. This query can be a specific method by name or a more common method with parameters. The Repository is responsible to provide and implement these query methods. When such a method is called, the Repository will contact the Gateway to retrieve the raw data from the persistence. The Gateway will provide raw object data (like an array with values). Then the Repository will take this data, do the necessary transformations and call the appropriate Factory methods. The Factories will provide the objects constructed with the data provided by the Repository. The Repository will collect these objects and return them as a set of objects (like an array of objects or a collection object as defined in the Composite Pattern lesson in the Agile Design Patterns course).

Repository for Data Persistence

The second way a Repository can work is to provide the logic needed to be done in order to extract the information from an object and persist it. This can be as simple as serializing the object and sending the serialized data to the Gateway to persist it or as sophisticated as creating arrays of information with all the fields and state of an object.

UMLRepoPersist

When used to persist information the client class is the one directly communicating with the Factory. Imagine a scenario when a new comment is posted to a blog post. A Comment object is created by our business logic (the Client class) and then sent to the Repository to be persisted. The repository will persist the objects using the Gateway and optionally cache them in a local in memory list. Data needs to be transformed because there are only rare cases when real objects can be directly saved to a persistence system.


Connecting the Dots

The image below is a higher level view on how to integrate the Repository between the Factories, the Gateway and the Client.

UMLRepository

In the center of the schema is our Repository. On the left, is an Interface for the Gateway, an implementation and the persistence itself. On the right, there is an Interface for the Factories and a Factory implementation. Finally, on the top there is the client class.

As it can be observed from the direction of the arrows, the dependencies are inverted. Repository only depend on the abstract interfaces for Factories and Gateways. Gateway depends on its interface and the persistence it offers. The Factory depends only on its Interface. The client depends on Repository, which is acceptable because the Repository tends to be less concrete than the Client.

HighLevelDesign

Put in perspective, the paragraph above respects our high level architecture and the direction of dependencies we want to achieve.


Managing Comments to Blog Posts With a Repository

Now that we’ve seen the theory, it is time for a practical example. Imagine we have a blog where we have Post objects and Comment objects. Comments belong to Posts and we have to find a way to persist them and to retrieve them.

The Comment

We will start with a test that will force us to think about what our Comment object should contain.

class RepositoryTest extends PHPUnit_Framework_TestCase {

	function testACommentHasAllItsComposingParts() {
		$postId = 1;
		$commentAuthor = "Joe";
		$commentAuthorEmail = "joe@gmail.com";
		$commentSubject = "Joe Has an Opinion about the Repository Pattern";
		$commentBody = "I think it is a good idea to use the Repository Pattern to persist and retrieve objects.";

		$comment = new Comment($postId, $commentAuthor, $commentAuthorEmail, $commentSubject, $commentBody);
	}

}

At first glance, a Comment will just be a data object. It may not have any functionality, but that is up to the context of our application to decide. For this example just assume it is a simple data object. Constructed with a set of variables.

class Comment {

}

Just by creating an empty class and requiring it in the test makes it pass.

require_once '../Comment.php';

class RepositoryTest extends PHPUnit_Framework_TestCase {

[ ... ]

}

But that’s far from perfect. Our test does not test anything yet. Let’s force ourselves to write all the getters on the Comment class.

function testACommentsHasAllItsComposingParts() {
	$postId = 1;
	$commentAuthor = "Joe";
	$commentAuthorEmail = "joe@gmail.com";
	$commentSubject = "Joe Has an Opinion about the Repository Pattern";
	$commentBody = "I think it is a good idea to use the Repository Pattern to persist and retrieve objects.";

	$comment = new Comment($postId, $commentAuthor, $commentAuthorEmail, $commentSubject, $commentBody);

	$this->assertEquals($postId, $comment->getPostId());
	$this->assertEquals($commentAuthor, $comment->getAuthor());
	$this->assertEquals($commentAuthorEmail, $comment->getAuthorEmail());
	$this->assertEquals($commentSubject, $comment->getSubject());
	$this->assertEquals($commentBody, $comment->getBody());
}

To control the length of the tutorial, I wrote all the assertions at once and we will implement them at once as well. In real life, take them one by one.

class Comment {

	private $postId;
	private $author;
	private $authorEmail;
	private $subject;
	private $body;

	function __construct($postId, $author, $authorEmail, $subject, $body) {
		$this->postId = $postId;
		$this->author = $author;
		$this->authorEmail = $authorEmail;
		$this->subject = $subject;
		$this->body = $body;
	}

	public function getPostId() {
		return $this->postId;
	}

	public function getAuthor() {
		return $this->author;
	}

	public function getAuthorEmail() {
		return $this->authorEmail;
	}

	public function getSubject() {
		return $this->subject;
	}

	public function getBody() {
		return $this->body;
	}

}

Except for the list of private variables, the rest of the code was generated by my IDE, NetBeans, so testing the auto generated code may be a little bit of overhead some times. If you are not writing these lines by yourself, feel free to do them directly and don’t bother with tests for setters and constructors. Nevertheless, the test helped us better expose our ideas and better document what our Comment class will contain.

We can also consider these test methods and test classes as our “Client” classes from the schemas.


Our Gateway to Persistence

To keep this example as simple as possible, we will implement only an InMemoryPersistence so that we do not complicate our existence with file systems or databases.

require_once '../InMemoryPersistence.php';

class InMemoryPersistenceTest extends PHPUnit_Framework_TestCase {

	function testItCanPerisistAndRetrieveASingleDataArray() {
		$data = array('data');

		$persistence = new InMemoryPersistence();
		$persistence->persist($data);

		$this->assertEquals($data, $persistence->retrieve(0));
	}

}

As usual, we start with the simplest test that could possibly fail and also force us to write some code. This test creates a new InMemoryPersistence object and tries to persist and retrieve an array called data.

require_once __DIR__ . '/Persistence.php';

class InMemoryPersistence implements Persistence {

	private $data = array();

	function persist($data) {
		$this->data = $data;
	}

	function retrieve($id) {
		return $this->data;
	}

}

The simplest code to make it pass is just to keep the incoming $data in a private variable and return it in the retrieve method. The code as it is right now does not care about the sent in $id variable. It is the simplest thing that could possibly make the test pass. We also took the liberty to introduce and implement an interface called Persistence.

interface Persistence {

	function persist($data);
	function retrieve($ids);

}

This interface defines the two methods any Gateway needs to implement. Persist and retrieve. As you probably already guessed, our Gateway is our InMemoryPersistence class and our physical persistence is the private variable holding our data in the memory. But let’s get back to the implementation of this in memory persistence.

function testItCanPerisistSeveralElementsAndRetrieveAnyOfThem() {
	$data1 = array('data1');
	$data2 = array('data2');

	$persistence = new InMemoryPersistence();
	$persistence->persist($data1);
	$persistence->persist($data2);

	$this->assertEquals($data1, $persistence->retrieve(0));
	$this->assertEquals($data2, $persistence->retrieve(1));
}

We added another test. In this one we persist two different data arrays. We expect to be able to retrieve each of them individually.

require_once __DIR__ . '/Persistence.php';

class InMemoryPersistence implements Persistence {
	private $data = array();
	function persist($data) {
		$this->data[] = $data;
	}

	function retrieve($id) {
		return $this->data[$id];
	}
}

The test forced us to slightly alter our code. We now need to add data to our array, not just replace it with the one sent in to persists(). We also need to consider the $id parameter and return the element at that index.

This is enough for our InMemoryPersistence. If needed, we can modify it later.


Our Factory

We have a Client (our tests), a persistence with a Gateway, and Comment objects to persists. The next missing thing is our Factory.

We started our coding with a RepositoryTest file. This test, however, actually created a Comment object. Now we need to create tests to verify if our Factory will be able to create Comment objects. It seems like we had an error in judgment and our test is more likely a test for our upcoming Factory than for our Repository. We can move it into another test file, CommentFactoryTest.

require_once '../Comment.php';

class CommentFactoryTest extends PHPUnit_Framework_TestCase {

	function testACommentsHasAllItsComposingParts() {
		$postId = 1;
		$commentAuthor = "Joe";
		$commentAuthorEmail = "joe@gmail.com";
		$commentSubject = "Joe Has an Opinion about the Repository Pattern";
		$commentBody = "I think it is a good idea to use the Repository Pattern to persist and retrieve objects.";

		$comment = new Comment($postId, $commentAuthor, $commentAuthorEmail, $commentSubject, $commentBody);

		$this->assertEquals($postId, $comment->getPostId());
		$this->assertEquals($commentAuthor, $comment->getAuthor());
		$this->assertEquals($commentAuthorEmail, $comment->getAuthorEmail());
		$this->assertEquals($commentSubject, $comment->getSubject());
		$this->assertEquals($commentBody, $comment->getBody());
	}
}

Now, this test obviously passes. And while it is a correct test, we should consider modifying it. We want to create a Factory object, pass in an array and ask it to create a Comment for us.

require_once '../CommentFactory.php';

class CommentFactoryTest extends PHPUnit_Framework_TestCase {

	function testACommentsHasAllItsComposingParts() {
		$postId = 1;
		$commentAuthor = "Joe";
		$commentAuthorEmail = "joe@gmail.com";
		$commentSubject = "Joe Has an Opinion about the Repository Pattern";
		$commentBody = "I think it is a good idea to use the Repository Pattern to persist and retrieve objects.";

		$commentData = array($postId, $commentAuthor, $commentAuthorEmail, $commentSubject, $commentBody);

		$comment = (new CommentFactory())->make($commentData);

		$this->assertEquals($postId, $comment->getPostId());
		$this->assertEquals($commentAuthor, $comment->getAuthor());
		$this->assertEquals($commentAuthorEmail, $comment->getAuthorEmail());
		$this->assertEquals($commentSubject, $comment->getSubject());
		$this->assertEquals($commentBody, $comment->getBody());
	}
}

We should never name our classes based on the design pattern they implement, but Factory and Repository represent more than just the design pattern itself. I personally have nothing against including these two words in our class’s names. However I still strongly recommend and respect the concept of not naming our classes after the design patterns we use for the rest of the patterns.

This test is just slightly different from the previous one, but it fails. It tries to create a CommentFactory object. That class does not exist yet. We also try to call a make() method on it with an array containing all the information of a comment as an array. This method is defined in the Factory interface.

interface Factory {
	function make($data);
}

This is a very common Factory interface. It defined the only required method for a factory, the method that actually creates the objects we want.

require_once __DIR__ . '/Factory.php';
require_once __DIR__ . '/Comment.php';

class CommentFactory implements Factory {

	function make($components) {
		return new Comment($components[0], $components[1], $components[2], $components[3], $components[4]);
	}

}

And CommentFactory implements the Factory interface successfully by taking the $components parameter in its make() method, creates and returns a new Comment object with the information from there.

We will keep our persistence and object creation logic as simple as possible. We can, for this tutorial, safely ignore any error handling, validation and exception throwing. We will stop here with the persistence and object creation implementation.


Using a Repository to Persist Comments

As we’ve seen above, we can use a Repository in two ways. To retrieve information from persistence and also to persist information on the persistence layer. Using TDD it is, most of the time, easier to start with the saving (persisting) part of the logic and then use that existing implementation to test data retrieval.

require_once '../../../vendor/autoload.php';
require_once '../CommentRepository.php';
require_once '../CommentFactory.php';

class RepositoryTest extends PHPUnit_Framework_TestCase {

	protected function tearDown() {
		\Mockery::close();
	}

	function testItCallsThePersistenceWhenAddingAComment() {

		$persistanceGateway = \Mockery::mock('Persistence');
		$commentRepository = new CommentRepository($persistanceGateway);

		$commentData = array(1, 'x', 'x', 'x', 'x');
		$comment = (new CommentFactory())->make($commentData);

		$persistanceGateway->shouldReceive('persist')->once()->with($commentData);

		$commentRepository->add($comment);
	}

}

We use Mockery to mock our persistence and inject that mocked object to the Repository. Then we call add() on the repository. This method has a parameter of type Comment. We expect the persistence to be called with an array of data similar to $commentData.

require_once __DIR__ . '/InMemoryPersistence.php';

class CommentRepository {

	private $persistence;

	function __construct(Persistence $persistence = null) {
		$this->persistence = $persistence ? : new InMemoryPersistence();
	}

	function add(Comment $comment) {
		$this->persistence->persist(array(
			$comment->getPostId(),
			$comment->getAuthor(),
			$comment->getAuthorEmail(),
			$comment->getSubject(),
			$comment->getBody()
		));
	}

}

As you can see, the add() method is quite smart. It encapsulates the knowledge about how to transform a PHP object into a plain array usable by the persistence. Remember, our persistence gateway usually is a general object for all of our data. It can and will persist all the data of our application, so sending to it objects would make it do too much: both conversion and effective persistence.

When you have an InMemoryPersistence class like we do, it is very fast. We can use it as an alternative to mocking the gateway.

function testAPersistedCommentCanBeRetrievedFromTheGateway() {

	$persistanceGateway = new InMemoryPersistence();
	$commentRepository = new CommentRepository($persistanceGateway);

	$commentData = array(1, 'x', 'x', 'x', 'x');
	$comment = (new CommentFactory())->make($commentData);

	$commentRepository->add($comment);

	$this->assertEquals($commentData, $persistanceGateway->retrieve(0));
}

Of course if you do not have an in-memory implementation of your persistence, mocking is the only reasonable way to go. Otherwise your test will be just too slow to be practical.

function testItCanAddMultipleCommentsAtOnce() {

	$persistanceGateway = \Mockery::mock('Persistence');
	$commentRepository = new CommentRepository($persistanceGateway);

	$commentData1 = array(1, 'x', 'x', 'x', 'x');
	$comment1 = (new CommentFactory())->make($commentData1);
	$commentData2 = array(2, 'y', 'y', 'y', 'y');
	$comment2 = (new CommentFactory())->make($commentData2);

	$persistanceGateway->shouldReceive('persist')->once()->with($commentData1);
	$persistanceGateway->shouldReceive('persist')->once()->with($commentData2);

	$commentRepository->add(array($comment1, $comment2));
}

Our next logical step is to implement a way to add several comments at once. Your project may not require this functionality and it is not something required by the pattern. In fact, the Repository Pattern only says that it will provide a custom query and persistence language for our business logic. So if our bushiness logic feels the need of adding several comments at once, the Repository is the place where the logic should reside.

function add($commentData) {
	if (is_array($commentData))
		foreach ($commentData as $comment)
			$this->persistence->persist(array(
				$comment->getPostId(),
				$comment->getAuthor(),
				$comment->getAuthorEmail(),
				$comment->getSubject(),
				$comment->getBody()
			));
	else
		$this->persistence->persist(array(
			$commentData->getPostId(),
			$commentData->getAuthor(),
			$commentData->getAuthorEmail(),
			$commentData->getSubject(),
			$commentData->getBody()
		));
}

And the simplest way to make the test pass is to just verify if the parameter we are getting is an array or not. If it is an array, we will cycle through each element and call the persistence with the array we generate from one single Comment object. And while this code is syntactically correct and makes the test pass, it introduces a slight duplication that we can get rid of quite easily.

function add($commentData) {
	if (is_array($commentData))
		foreach ($commentData as $comment)
			$this->addOne($comment);
	else
		$this->addOne($commentData);
}

private function addOne(Comment $comment) {
	$this->persistence->persist(array(
		$comment->getPostId(),
		$comment->getAuthor(),
		$comment->getAuthorEmail(),
		$comment->getSubject(),
		$comment->getBody()
	));
}

When all the tests are green, it is alway time for refactoring before we continue with the next failing test. And we did just that with the add() method. We extracted the addition of a single comment into a private method and called it from two different places in our public add() method. This not only reduced duplication but also opened the possibility of making the addOne() method public and letting the business logic decide if it wants to add one or several comments at a time. This would lead to a different implementation of our Repository, with an addOne() and another addMany() methods. It would be a perfectly legitimate implementation of the Repository Pattern.


Retrieving Comments With Our Repository

A Repository provides a custom query language for the business logic. So the names and functionalities of the query methods of a Repository is hugely up to the requirements of the business logic. You build your repository as you build your business logic, as you need another custom query method. However, there are at least one or two methods that you will find on almost any Repository.

function testItCanFindAllComments() {
	$repository = new CommentRepository();

	$commentData1 = array(1, 'x', 'x', 'x', 'x');
	$comment1 = (new CommentFactory())->make($commentData1);
	$commentData2 = array(2, 'y', 'y', 'y', 'y');
	$comment2 = (new CommentFactory())->make($commentData2);

	$repository->add($comment1);
	$repository->add($comment2);

	$this->assertEquals(array($comment1, $comment2), $repository->findAll());
}

The first such method is called findAll(). This should return all the objects the repository is responsible for, in our case Comments. The test is simple, we add a comment, then another one, and finally we want to call findAll() and get a list containing both comments. This is however not accomplish-able with our InMemoryPersistence as it is at this point. A small update is required.

function retrieveAll() {
	return $this->data;
}

That’s it. We added a retrieveAll() method which just returns the whole $data array from the class. Simple and effective. It’s time to implement findAll() on the CommentRepository now.

function findAll() {
	$allCommentsData = $this->persistence->retrieveAll();
	$comments = array();
	foreach ($allCommentsData as $commentData)
		$comments[] = $this->commentFactory->make($commentData);
	return $comments;
}

findAll() will call the retrieveAll() method on our persistence. That method provides a raw array of data. findAll() will cycle through each element and use the data as necessary to be passed to the Factory. The factory will provide one Comment a time. An array with these comments will be built and returned at the end of findAll(). Simple and effective.

Another common method you will find on repositories is to search for a specific object or group of objects based on their characteristic key. For example, all of our comments are connected to a blog post by a $postId internal variable. I can imagine that in our blog’s business logic we would almost always want to find all the comments related to a blog post when that blog post is displayed. So a method called findByPostId($id) sounds reasonable to me.

function testItCanFindCommentsByBlogPostId() {
	$repository = new CommentRepository();

	$commentData1 = array(1, 'x', 'x', 'x', 'x');
	$comment1 = (new CommentFactory())->make($commentData1);
	$commentData2 = array(1, 'y', 'y', 'y', 'y');
	$comment2 = (new CommentFactory())->make($commentData2);
	$commentData3 = array(3, 'y', 'y', 'y', 'y');
	$comment3 = (new CommentFactory())->make($commentData3);

	$repository->add(array($comment1, $comment2));
	$repository->add($comment3);

	$this->assertEquals(array($comment1, $comment2), $repository->findByPostId(1));
}

We just create three simple comments. The first two have the same $postId = 1, the third one has $postID = 3. We add all of them to the repository and then we expect an array with the first two ones when we do a findByPostId() for the $postId = 1.

function findByPostId($postId) {
	return array_filter($this->findAll(), function ($comment) use ($postId){
		return $comment->getPostId() == $postId;
	});
}

The implementation couldn’t be simpler. We find all the comments using our already implemented findAll() method and we filter the array. We have no way to ask the persistence to do the filtering for us, so we will do it here. The code will query each Comment object and compare its $postId with the one we sent in as parameter. Great. The test passes. But I feel we missed something.

function testItCanFindCommentsByBlogPostId() {
	$repository = new CommentRepository();

	$commentData1 = array(1, 'x', 'x', 'x', 'x');
	$comment1 = (new CommentFactory())->make($commentData1);
	$commentData2 = array(1, 'y', 'y', 'y', 'y');
	$comment2 = (new CommentFactory())->make($commentData2);
	$commentData3 = array(3, 'y', 'y', 'y', 'y');
	$comment3 = (new CommentFactory())->make($commentData3);

	$repository->add(array($comment1, $comment2));
	$repository->add($comment3);

	$this->assertEquals(array($comment1, $comment2), $repository->findByPostId(1));
	$this->assertEquals(array($comment3), $repository->findByPostId(3));
}

Adding a second assertion to obtain the third comment with the findByPostID() method reveals our mistake. Whenever you can easily test extra paths or cases, like in our case with a simple extra assertion, you should. These simple extra assertions or test methods can reveal hidden problems. Like in our case, array_filter() does not reindex the resulting array. And while we have an array with the correct elements, the indexes are messed up.

1) RepositoryTest::testItCanFindCommentsByBlogPostId
Failed asserting that two arrays are equal.
--- Expected
+++ Actual
@@ @@
 Array (
-    0 => Comment Object (...)
+    2 => Comment Object (...)
 )

Now, you may consider this a shortcoming of PHPUnit or a shortcoming of your business logic. I tend to be rigorous with array indexes because I burned my hands with them a few times. So we should consider the error a problem with our logic in the CommentRepository.

function findByPostId($postId) {
	return array_values(
		array_filter($this->findAll(), function ($comment) use ($postId) {
			return $comment->getPostId() == $postId;
		})
	);
}

Yep. That simple. We just run the result through array_values() before returning it. It will nicely reindex our array. Mission accomplished.


Final Thoughts

And that’s mission accomplished for our Repository also. We have a class usable by any other business logic class which offers an easy way to persist and retrieve objects. It also decouples the business logic from the factories and data persistence gateways. It reduced logic duplication and significantly simplifies the persistence and retrieval operations for our comments.

Remember, this design pattern can be used for all types of lists and as you start using it, you will see its usefulness. Basically, whenever you have to work with several objects of the same type, you should consider introducing a Repository for them. Repositories are specialized by object type and not general. So for a blog application, you may have distinct repositories for blog posts, for comments, for users, for user configurations, for themes, for designs, for or anything you may have multiple instances of.

And before concluding this, a Repository may have its own list of objects and it may do a local caching of objects. If an object can not be found in the local list, we retrieve it from the persistence, otherwise we serve it from our list. If used with caching, a Repository can be successfully combined with the Singleton Design Pattern.

As usual, thank you for your time and I sincerely hope I taught you something new today.

November 22 2013

17:37

Deploying a Laravel Application Using Capistrano

So you’ve just built a fancy web application and you’re planning to put it online. This can be done in many ways. In this article, we’ll cover one approach to deploy your backend system to your production server. We’ll go through the following steps through the example of a Laravel application, but this can be applied to any other language or technology.


The Past

Perhaps you have already put some websites online in the past. You’ve probably used an FTP client and uploaded the bits and bytes by hand. Or perhaps you always logged into your server via SSH and pulled the changes manually.


The Idea

Our goal is to simplify this process as much as possible. The idea is to use your code repository as a source for every deployment. The deployment tool, in our case capistrano, will automatically log into your server and build your system right out of your repository.

Software deployment is all of the activities that make a software system available for use. – Wikipedia


What You’ll Need

On Your Remote Server

Your remote server needs to provide SSH access. It also should have installed all necessary dependencies for your project such as GIT, PHP, MySQL, Composer, etc. Aside from this, you don’t need any extra software on your production server.

On Your Local Machine

In order to install and use Capistrano, you need at least Ruby 1.8.7 (if you don’t have Ruby installed, I recommend installing it using rbenv). To install capistrano, you simply have to run:

gem install capistrano

So, why capistrano? You may ask. As always, there are many ways to accomplish a task but in my case, Capistrano always seemed to be the easiest and most flexible approach. You can configure it to all your needs and there are a lot of plugins out there which simplify your work again.

Capistrano is a utility framework for executing commands in parallel on multiple remote machines, via SSH. It uses a simple DSL (borrowed in part from Rake) that allows you to define tasks, which may be applied to machines in certain roles. It also supports tunneling connections via some gateway machine to allow operations to be performed behind VPNs and firewalls.


Prepare

Now that we have everything we need, let’s set up our deployment settings. But first we have to create a folder on the remote server where all the files should be deployed to. Log into your server with SSH and create a folder. A common place is /var/www/. So let’s do this:

$ sudo mkdir /var/www/my-app
$ sudo chown -R username:group /var/www/my-app

That’s it. There is nothing more to do on the remote server, so you can close the SSH connection and move on. Go into your project (or any other folder, that doesn’t matter right now) and run:

$ cd my-project
$ capify .

This command will create the basic files we need. The Capfile is like the mount point for Capistrano, but for now we’ll just need to edit the config/deploy.rb file, which, as the name tells, is responsible for all the configuration. Open this file in your favorite text editor and replace the content with the following snippet. We’ll go through the code afterwards.

set :application, "Your app name"  # EDIT your app name

set :scm, :git
set :deploy_via, :remote_cache
set :repository,  "https://github.com/laravel/laravel.git" # EDIT your git repository

role :app, "12.456.789.123" # EDIT server ip address 
set :deploy_to, "/var/www/my-app" # EDIT folder where files should be deployed

set :user, "" # EDIT your ssh user name
set :password, "" # EDIT your ssh password
set :use_sudo, false
set :ssh_options, {
	:forward_agent => true
}

default_run_options[:pty] = true # needed for the password prompt from git to work

namespace :deploy do

	task :update do
		transaction do
			update_code # built-in function
			composer_install
			prepare_artisan
			symlink # built-in function
		end
	end

	task :composer_install do
		transaction do
			run "cd #{current_release} && composer install --no-dev --quiet"
		end
	end

	task :prepare_artisan do
		transaction do
			run "chmod u+x #{current_release}/artisan"
		end
	end

	task :restart do
		transaction do
			run "chmod -R g+w #{releases_path}/#{release_name}"
			run "chmod -R 777 #{current_release}/app/storage/cache"
			run "chmod -R 777 #{current_release}/app/storage/logs"
			run "chmod -R 777 #{current_release}/app/storage/meta"
			run "chmod -R 777 #{current_release}/app/storage/sessions"
			run "chmod -R 777 #{current_release}/app/storage/views"
		end
	end

end

You now have to put your data in every line with an #EDIT comment (ip address, git repo, ssh user, password, …). The :deploy_to variable should be the folder we just created. Your webserver (Apache, nginx, …) should point to /var/www/my-app/current/public. In the first part of the deploy.rb file, you can set up all your data. In the namespace :deploy block, you specify what actually should happen for each deployment.

So let’s have a quick walk-through on what those task‘s mean:

  • update_code is a built-in method of Capistrano and pulls in your latest version from your git repository.
  • composer_install fetches all your PHP dependencies, just like you’re used to during development.
  • prepare_artisan makes the artisan file executable in order to use it for migrations.
  • Every deployment is stored in /var/www/my-app/releases/. The built-in task symlink creates a symbolic link of the recent deployment to the current folder. This way you can keep older releases and switch versions without going offline for a second. When this task ran, your newest version is online.

Here you can easily add your own tasks if your build process requires some extra steps. For more detailed information, I recommend reading the Wiki on Github.

Now it’s time to initiate the server and test if everything works. To do this, run the following commands:

$ cap deploy:setup
$ cap deploy:check

You should see the message You appear to have all necessary dependencies installed. That means were are prepared for our first deploy.


Fire!

This is the moment you were waiting for. The hardest part is done. From now on, every time you want to update your application, you only have to run the following magical command. Capistrano will read your config/deploy.rb file and run each task. If a task fails, the deploy will stop and the old version will still be online.

$ cap deploy

You will see a bunch of text output and after little time (depending on your server) everything should be complete. That was easy, wasn’t it?


Further Thoughts

Security

Perhaps you might be a little worried with having to put your plain-text password in the configuration file. I only chose that way to make the demonstration as straight forward as possible, but in the real world, you might want to use an SSH key. You can import one like this:

set :user, "" # EDIT your ssh user name
set :use_sudo, false
set :ssh_options, {
	:forward_agent => true,
	:auth_methods => ["publickey"],
	:keys => ["/path/to/your/key.pem"] # EDIT your ssh key
}

Database

So far, we have focused on deploying the actual files to their new home, but in many scenarios you might also do something with your database. Laravel has a perfect tool for that: migrations. To run your migrations, you can just define an extra task. Let’s do so:

	task :laravel_migrate do
		transaction do
			run "#{current_release}/artisan migrate"
		end
	end

You also have to add this task in the transaction block of the update task. Now every time you deploy, the database will be updated to your latest migrations.

Rollback

Sometimes you deploy a non-working version of your application and you need to undo this changes. Capsitrano has a built-in feature for that called “rollback”. Just run:

cap deploy:rollback

Conclusion

You’ve just learned a very simple way of deploying your application to your production server(s) with Capistrano. Once the configuration work is done, it just takes one command to deploy your latest version in seconds. But as mentioned earlier, this is not the only way to do this.

You should also check out the task runner grunt which suits perfectly for building and deploying JavaScript applications. A complete different approach takes docker which acts like a lightweight VM. The idea here is to deploy your whole environment as a virtual machine. Check them out!

Tags: PHP deployment

November 11 2013

18:19

Authentication With Laravel 4

Authentication is required for virtually any type of web application. In this tutorial, I’d like to show you how you can go about creating a small authentication application using Laravel 4. We’ll start from the very beginning by creating our Laravel app using composer, creating the database, loading in the Twitter Bootstrap, creating a main layout, registering users, logging in and out, and protecting routes using filters. We’ve got a lot of code to cover, so let’s get started!


Installation

Let’s start off this tutorial by setting up everything that we’ll need in order to build our authentication application. We’ll first need to download and install Laravel plus all of its dependencies. We’ll also utilize the popular Twitter Bootstrap to make our app look pretty. Then we’ll do a tad bit of configuration, connect to our database and create the required table and finally, start up our server to make sure everything is working as expected.

Download

Let’s use composer to create a new Laravel application. I’ll first change directories into my Sites folder as that’s where I prefer to store all of my apps:

cd Sites

Then run the following command to download and install Laravel (I named my app laravel-auth) and all of its dependencies:

composer create-project laravel/laravel laravel-auth

Add In Twitter Bootstrap

Now to keep our app from suffering a horrible and ugly fate of being styled by yours truly, we’ll include the Twitter bootstrap within our composer.json file:

{
	"name": "laravel/laravel",
	"description": "The Laravel Framework.",
	"keywords": ["framework", "laravel"],
	"require": {
		"laravel/framework": "4.0.*",
		"twitter/bootstrap": "*"
	},

	// The rest of your composer.json file below ....

… and then we can install it:

composer update

Now if you open up your app into your text editor, I’m using Sublime, and if you look in the vendor folder you’ll see we have the Twitter Bootstrap here.

laravel-auth-twitter-bootstrap-installed

Now by default our Twitter Bootstrap is composed of .less files and before we can compile them into .CSS files, we need to install all of the bootstrap dependencies. This will also allow us to use the Makefile that is included with the Twitter bootstrap for working with the framework (such as compiling files and running tests).

Note: You will need npm in order to install these dependencies.

In your terminal, let’s change directories into vendor/twitter/bootstrap and run npm install:

cd ~/Sites/laravel-auth/vendor/twitter/bootstrap
npm install

With everything ready to go, we can now use the Makefile to compile the .less files into CSS. Let’s run the following command:

make bootstrap-css

You should now notice that we have two new folders inside our vendor/twitter/bootstrap directory named bootstrap/css which contain our bootstrap CSS files.

laravel-auth-css-compiled

Now we can use the bootstrap CSS files later on, in our layout, to style our app.

But, we have a problem! We need these CSS files to be publicly accessible, currently they are located in our vendor folder. But this is an easy fix! We can use artisan to publish (move) them to our public/packages folder, that way we can link in the required CSS files into our main layout template, which we’ll create later on.

First, we’ll change back into the root of our Laravel application and then run artisan to move the files:

cd ~/Sites/laravel-auth
php artisan asset:publish --path="vendor/twitter/bootstrap/bootstrap/css" bootstrap/css

The artisan command asset:publish allows us to provide a --path option for which files we want to move into our public/packages directory. In this case, we tell it to publish all of the CSS files that we compiled earlier and place them inside of two new folders named bootstrap/css. Your public directory should now look like the screenshot below, with our Twitter Bootstrap CSS files now publicly accessible:

laravel-auth-bootstrap-css-moved-to-public

Set Permissions

Next we need to ensure our web server has the appropriate permissions to write to our applications app/storage directory. From within your app, run the following command:

chmod -R 755 app/storage

Connect To Our Database

Next, we need a database that our authentication app can use to store our users in. So fire up whichever database you are more comfortable using, personally, I prefer MySQL along with PHPMyAdmin. I’ve created a new, empty database named: laravel-auth.

laravel-auth-database-creation

Now let’s connect this database to our application. Under app/config open up database.php. Enter in your appropriate database credentials, mine are as follows:

// Default Database Connection Name

'default' => 'mysql',

// Database Connections

	'connections' => array(

		'mysql' => array(
			'driver'    => 'mysql',
			'host'      => '127.0.0.1',
			'database'  => 'laravel-auth',
			'username'  => 'root',
			'password'  => '',
			'charset'   => 'utf8',
			'collation' => 'utf8_unicode_ci',
			'prefix'    => '',
		),

		// the rest of your database.php file's code ...

Create the Users Table

With our database created, it won’t be very useful unless we have a table to store our users in. Let’s use artisan to create a new migration file named: create-users-table:

php artisan migrate:make create-users-table

Let’s now edit our newly created migration file to create our userstable using the Schema Builder. We’ll start with the up() method:

public function up()
{
	$table->increments('id');
	$table->string('firstname', 20);
	$table->string('lastname', 20);
	$table->string('email', 100)->unique();
	$table->string('password', 64);
	$table->timestamps();
}

This will create a table named users and it will have an id field as the primary key, firstname and lastname fields, an email field which requires the email to be unique, and finally a field for the password (must be at least 64 characters in length) as well as a few timestamps.

Now we need to fill in the down() method in case we need to revert our migration, to drop the users table:

public function down()
{
	Schema::drop('users');
}

And now we can run the migration to create our users table:

php artisan migrate

Start Server & Test It Out

Alright, our authentication application is coming along nicely. We’ve done quite a bit of preparation, let’s start up our server and preview our app in the browser:

php artisan serve

Great, the server starts up and we can see our home page:

laravel-auth-home-page

Making the App Look Pretty

Before we go any further, it’s time to create a main layout file, which will use the Twitter Bootstrap to give our authentication application a little style!

Creating a Main Layout File

Under app/views/ create a new folder named layouts and inside it, create a new file named main.blade.php and let’s place in the following basic HTML structure:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Authentication App With Laravel 4</title>
  </head>

  <body>

  </body>
</html>

Linking In the CSS Files

Next, we need to link in our bootstrap CSS file as well as our own main CSS file, in our head tag, right below our title:

	<head>
    	<meta charset="utf-8">
    	<meta name="viewport" content="width=device-width, initial-scale=1.0">

    	<title>Authentication App With Laravel 4</title>
    	{{ HTML::style('packages/bootstrap/css/bootstrap.min.css') }}
    	{{ HTML::style('css/main.css')}}
  	</head>

Now we just need to create this main.css file where we can add our own customized styling for our app. Under the public directory create a new folder named css and within it create a new file named main.css.

laravel-auth-add-main-css-file

Finishing the Main Layout

Inside of our body tag, let’s create a small navigation menu with a few links for registering and logging in to our application:

<body>

  	<div class="navbar navbar-fixed-top">
	  	<div class="navbar-inner">
	    	<div class="container">
				<ul class="nav">  
					<li>{{ HTML::link('users/register', 'Register') }}</li>   
					<li>{{ HTML::link('users/login', 'Login') }}</li>   
				</ul>  
	    	</div>
	  	</div>
	</div> 

</body>

Notice the use of several Bootstrap classes in order to style the navbar appropriately. Here we’re just using a couple of DIVs to wrap an unordered list of navigation links, pretty simple.

For our application, we’re going to want to give our users simple flash messages, like a success message when the user registers. We’ll set this flash message from within our controller, but we’ll echo out the message’s value here in our layout. So let’s create another div with a class of .container and display any available flash messages right after our navbar:

<body>

  	<div class="navbar navbar-fixed-top">
	  	<div class="navbar-inner">
	    	<div class="container">
				<ul class="nav">  
					<li>{{ HTML::link('users/register', 'Register') }}</li>   
					<li>{{ HTML::link('users/login', 'Login') }}</li>   
				</ul>  
	    	</div>
	  	</div>
	</div> 
            

    <div class="container">
    	@if(Session::has('message'))
			<p class="alert">{{ Session::get('message') }}</p>
		@endif
    </div>

	</body>

To display the flash message, I’ve first used a Blade if statement to check if we have a flash message to display. Our flash message will be available in the Session under message. So we can use the Session::has() method to check for that message. If that evaluates to true, we create a paragraph with the Twitter bootstrap class of alert and we call the Session::get() method to display the message’s value.

Now lastly, at least for our layout file, let’s echo out a $content variable, right after our flash message. This will allow us to tell our controller to use this layout file, and our views will be displayed in place of this $content variable, right here in the layout:

<body>

  	<div class="navbar navbar-fixed-top">
	  	<div class="navbar-inner">
	    	<div class="container">
				<ul class="nav">  
					<li>{{ HTML::link('users/register', 'Register') }}</li>   
					<li>{{ HTML::link('users/login', 'Login') }}</li>   
				</ul>  
	    	</div>
	  	</div>
	</div> 
            

    <div class="container">
    	@if(Session::has('message'))
			<p class="alert">{{ Session::get('message') }}</p>
		@endif

		{{ $content }}
    </div>

	</body>

Custom Styling

Now that we have our layout complete, we just need to add a few small custom CSS rules to our main.css file to customize our layout a little bit more. Go ahead and add in the following bit of CSS, it’s pretty self explanatory:

body {
	padding-top: 40px;
}

.form-signup, .form-signin {
	width: 400px;
	margin: 0 auto;
}

I added just a small amount of padding to the top of the body tag in order to prevent our navbar from overlapping our main content. Then I target the Bootstrap’s .form-signup and .form-signin classes, which we’ll be applying to our register and login forms in order to set their width and center them on the page.


Creating the Register Page

It’s now time to start building the first part of our authentication application and that is our Register page.

The Users Controller

We’ll start by creating a new UsersController within our app/controllers folder and in it, we define our UsersController class:

<?php

class UsersController extends BaseController {

}
?>

Next, let’s tell this controller to use our main.blade.php layout. At the top of our controller set the $layout property:

<?php

class UsersController extends BaseController {
	protected $layout = "layouts.main";
}
?>

Now within our UsersController, we need an action for our register page. I named my action getRegister:

public function getRegister() {
	$this->layout->content = View::make('users.register');
}

Here we just set the content layout property (this is the $content variable we echo’d out in our layout file) to display a users.register view file.

The Users Controller Routes

With our controller created next we need to setup the routes for all of the actions we might create within our controller. Inside of our app/routes.php file let’s first remove the default / route and then add in the following code to create our UsersController routes:

Route::controller('users', 'UsersController');

Now anytime that we create a new action, it will be available using a URI in the following format: /users/actionName. For example, we have a getRegister action, we can access this using the following URI: /users/register.

Note that we don’t include the “get” part of the action name in the URI, “get” is just the HTTP verb that the action responds to.

Creating the Register View

Inside of app/views create a new folder named users. This will hold all of our UsersController‘s view files. Inside the users folder create a new file named register.blade.php and place the following code inside of it:

{{ Form::open(array('url'=>'users/create', 'class'=>'form-signup')) }}
	<h2 class="form-signup-heading">Please Register</h2>

	<ul>
		@foreach($errors->all() as $error)
			<li>{{ $error }}</li>
		@endforeach
	</ul>

	{{ Form::text('firstname', null, array('class'=>'input-block-level', 'placeholder'=>'First Name')) }}
	{{ Form::text('lastname', null, array('class'=>'input-block-level', 'placeholder'=>'Last Name')) }}
	{{ Form::text('email', null, array('class'=>'input-block-level', 'placeholder'=>'Email Address')) }}
	{{ Form::password('password', array('class'=>'input-block-level', 'placeholder'=>'Password')) }}
	{{ Form::password('password_confirmation', array('class'=>'input-block-level', 'placeholder'=>'Confirm Password')) }}

	{{ Form::submit('Register', array('class'=>'btn btn-large btn-primary btn-block'))}}
{{ Form::close() }}

Here we use the Form class to create our register form. First we call the open() method, passing in an array of options. We tell the form to submit to a URI of users/create by setting the url key. This URI will be used to process the registration of the user. We’ll handle this next. After setting the url we then give the form a class of form-signup.

After opening the form, we just have an h2 heading with the .form-signup-heading class.

Next, we use a @foreach loop, looping over all of the form validation error messages and displaying each $error in the unordered list.

After the form validation error messages, we then we create several form input fields, each with a class of input-block-level and a placeholder value. We have inputs for the firstname, lastname, email, password, and password confirmation fields. The second argument to the text() method is set to null, since we’re using a placeholder, we don’t need to set the input fields value attribute, so I just set it to null in this case.

After the input fields, we then create our submit button and apply several different classes to it so the Twitter bootstrap handles the styling for us.

Lastly, we just close the form using the close() method.

Make sure to start up your server, switch to your favorite browser, and if we browse to http://localhost:8000/users/register you should see your register page:

laravel-auth-register-page

Processing the Register Form Submission

Now if you tried filling out the register form’s fields and hitting the Register button you would have been greeted with a NotFoundHttpException, and this is because we have no route that matches the users/create URI, because we do not have an action to process the form submission. So that’s our next step!

Creating a postCreate Action

Inside of your UsersController let’s create another action named postCreate:

public function postCreate() {
		
}

Now this action needs to handle processing the form submission by validating the data and either displaying validation error messages or it should create the new user, hashing the user’s password, and saving the user into the database.

Form Validation

Let’s start with validating the form submission’s data. We first need to create our validation rules that we’ll validate the form data against. I prefer storing my validation rules in my model as that’s the convention I’m used to, from working with other frameworks. By default, Laravel ships with a User.php model already created for you.

Make sure you don’t delete this User model or remove any of the preexisting code, as it contains new code that is required for Laravel 4′s authentication to work correctly. Your User model must implement UserInterface and RemindableInterface as well as implement the getAuthIdentifier() and getAuthPassword() methods.

Under app/models open up that User.php file and at the top, add in the following code:

public static $rules = array(
	'firstname'=>'required|alpha|min:2',
	'lastname'=>'required|alpha|min:2',
	'email'=>'required|email|unique:users',
	'password'=>'required|alpha_num|between:6,12|confirmed',
	'password_confirmation'=>'required|alpha_num|between:6,12'
	);

Here I’m validating the firstname and lastname fields to ensure they are present, only contain alpha characters, and that they are at least two characters in length. Next, I validate the email field to ensure that it’s present, that it is a valid email address, and that it is unique to the users table, as we don’t want to have duplicate email addresses for our users. Lastly, I validate the password and password_confirmation fields. I ensure they are both present, contain only alpha-numeric characters and that they are between six and twelve characters in length. Additionally, notice the confirmed validation rule, this makes sure that the password field is exactly the same as the matching password_confirmation field, to ensure users have entered in the correct password.

Now that we have our validation rules, we can use these in our UsersController to validate the form submission. In your UsersController‘s postCreate action, let’s start by checking if the data passes validation, add in the following code:

public function postCreate() {
	$validator = Validator::make(Input::all(), User::$rules);

	if ($validator->passes()) {
		// validation has passed, save user in DB
	} else {
		// validation has failed, display error messages	
	}
}
}

We start by creating a validator object named $validator by calling the User::validate() method. This accepts the two arguments, the submitted form input that should be validated and the validation rules that the data should be validated against. We can grab the submitted form data by calling the Input::all() method and we pass that in as the first argument. We can get our validation rules that we created in our User model by accessing the static User::$rules property and passing that in as the second argument.

Once we’ve created our validator object, we call its passes() method. This will return either true or false and we use this within an if statement to check whether our data has passed validation.

Within our if statement, if the validation has passed, add in the following code:

if ($validator->passes()) {
	$user = new User;
	$user->firstname = Input::get('firstname');
	$user->lastname = Input::get('lastname');
	$user->email = Input::get('email');
	$user->password = Hash::make(Input::get('password'));
	$user->save();

	return Redirect::to('users/login')->with('message', 'Thanks for registering!');
} else {
	// validation has failed, display error messages	
}

As long as the data that the user submits has passed validation, we create a new instance of our User model: new User; storing it into a $user variable. We can then use the $user object and set each of the user’s properties using the submitted form data. We can grab the submitted data individually using the Input::get('fieldName') method. Where fieldName is the field’s value you want to retrieve. Here we’ve grabbed the firstname, lastname, and email fields to use for our new user. We also grabbed the password field’s value, but we don’t just want to store the password in the database as plain text, so we use the Hash::make() method to hash the submitted password for us before saving it. Lastly, we save the user into the database by calling the $user object’s save() method.

After creating the new user, we then redirect the user to the login page (we’ll create the login page in a few moments) using the Redirect::to() method. This just takes in the URI of where you’d like to redirect to. We also chain on the with() method call in order to give the user a flash message letting them know that their registration was successful.

Now if the validation does not pass, we need to redisplay the register page, along with some validation error messages, with the old input, so the user can correct their mistakes. Within your else statement, add in the following code:

if ($validator->passes()) {
	$user = new User;
	$user->firstname = Input::get('firstname');
	$user->lastname = Input::get('lastname');
	$user->email = Input::get('email');
	$user->password = Hash::make(Input::get('password'));
	$user->save();

	return Redirect::to('users/login')->with('message', 'Thanks for registering!');
} else {
	return Redirect::to('users/register')->with('message', 'The following errors occurred')->withErrors($validator)->withInput();
}

Here we just redirect the user back to the register page with a flash message letting them know some errors have occurred. We make sure to display the validation error messages by calling the withErrors($validator) method and passing in our $validator object to it. Finally, we call the withInput() method so the form remembers what the user originally typed in and that will make it nice and easy for the user to correct the errors.

Adding In the CSRF Before Filter

Now we need to make sure to protect our POST actions from CSRF attacks by setting the CSRF before filter within our UsersController‘s constructor method. At the top of your UsersController add in the following code:

public function __construct() {
	$this->beforeFilter('csrf', array('on'=>'post'));
}

Within our constructor, we call the beforeFilter() method and pass in the string csrf, as the first argument. csrf is the filter that we want to apply to our actions. Then we pass in an array as the second argument and tell it to only apply this filter on POST requests. By doing this, our forms will pass along a CSRF token whenever they are submitted. This CSRF before filter will ensure that all POST requests to our app contain this token, giving us confidence that POST requests are not being issued to our application from other external sources.


Creating the Login Page

Before you run off and try out your register page, we first need to create the Login page so that when our register form submission is successful, we don’t get an error. Remember, if the form validation passes, we save the user and redirect them to the login page. We currently don’t have this login page though, so let’s create it!

Still inside of your UsersController, create a new action named getLogin and place in the following code:

public function getLogin() {
	$this->layout->content = View::make('users.login');
}

This will display a users.login view file. We now need to create that view file. Under app/views/users create a new file named login.blade.php and add in the following code:

{{ Form::open(array('url'=>'users/signin', 'class'=>'form-signin')) }}
	<h2 class="form-signin-heading">Please Login</h2>

	{{ Form::text('email', null, array('class'=>'input-block-level', 'placeholder'=>'Email Address')) }}
	{{ Form::password('password', array('class'=>'input-block-level', 'placeholder'=>'Password')) }}

	{{ Form::submit('Login', array('class'=>'btn btn-large btn-primary btn-block'))}}
{{ Form::close() }}

This code is very similar to the code we used in our register view, so I’ll simplify the explanation this time to only what is different. For this form, we have it submit to a users/signin URI and we changed the form’s class to .form-signin. The h2 has been changed to say “Please Login” and its class was also changed to .form-signin-heading. Next, we have two form fields so the user can enter in their email and password, and then finally our submit button which just says “Login”.

Let’s Register a New User!

We’re finally at a point to where we can try out our registration form. Of course, the login functionality doesn’t work just yet, but we’ll get to that soon enough. We only needed the login page to exist so that our register page would work properly. Make sure your server is still running, switch into your browser, and visit http://localhost:8000/users/register. Try entering in some invalid user data to test out the form validation error messages. Here’s what my page looks like with an invalid user:

laravel-auth-displaying-errors

Now try registering with valid user data. This time we get redirected to our login page along with our success message, excellent!

laravel-auth-successful-registration

Logging In

So we’ve successfully registered a new user and we have a login page, but we still can’t login. We now need to create the postSignin action for our users/signin URI, that our login form submits to. Let’s go back into our UsersController and create a new action named postSignin:

public function postSignin() {
			
}

Now let’s log the user in, using the submitted data from the login form. Add the following code into your postSignin() action:

if (Auth::attempt(array('email'=>Input::get('email'), 'password'=>Input::get('password')))) {
	return Redirect::to('users/dashboard')->with('message', 'You are now logged in!');
} else {
	return Redirect::to('users/login')
		->with('message', 'Your username/password combination was incorrect')
		->withInput();
}

Here we attempt to log the user in, using the Auth::attempt() method. We simply pass in an array containing the user’s email and password that they submitted from the login form. This method will return either true or false if the user’s credentials validate. So we can use this attempt() method within an if statement. If the user was logged in, we just redirect them to a dashboard view page and give them a success message. Otherwise, the user’s credentials did not validate and in that case we redirect them back to the login page, with an error message, and display the old input so the user can try again.

Creating the Dashboard

Now before you attempt to login with your newly registered user, we need to create that dashboard page and protect it from unauthorized, non logged in users. The dashboard page should only be accessible to those users who have registered and logged in to our application. Otherwise, if a non authorized user attempts to visit the dashboard we’ll redirect them and request that they log in first.

While still inside of your UsersController let’s create a new action named getDashboard:

public function getDashboard() {
	
}

And inside of this action we’ll just display a users.dashboard view file:

public function getDashboard() {
	$this->layout->content = View::make('users.dashboard');
}

Next, we need to protect it from unauthorized users by using the auth before filter. In our UsersController‘s constructor, add in the following code:

public function __construct() {
	$this->beforeFilter('csrf', array('on'=>'post'));
	$this->beforeFilter('auth', array('only'=>array('getDashboard')));
}

This will use the auth filter, which checks if the current user is logged in. If the user is not logged in, they get redirected to the login page, essentially denying the user access. Notice that I’m also passing in an array as a second argument, by setting the only key, I can tell this before filter to only apply it to the provided actions. In this case, I’m saying to protect only the getDashboard action.

Customizing Filters

By default the auth filter will redirect users to a /login URI, this does not work for our application though. We need to modify this filter so that it redirects to a users/login URI instead, otherwise get an error. Open up app/filters.php and in the Authentication Filters section, change the auth filter to redirect to users/login, like this:

/*
|--------------------------------------------------------------------------
| Authentication Filters
|--------------------------------------------------------------------------
|
| The following filters are used to verify that the user of the current
| session is logged into this application. The "basic" filter easily
| integrates HTTP Basic authentication for quick, simple checking.
|
*/

Route::filter('auth', function()
{
	if (Auth::guest()) return Redirect::guest('users/login');
});

Creating the Dashboard View

Before we can log users into our application we need to create that dashboard view file. Under app/views/users create a new file named dashboard.blade.php and insert the following snippet of code:

<h1>Dashboard</h1>

<p>Welcome to your Dashboard. You rock!</p>

Here I’m displaying a very simple paragraph to let the user know they are now in their Dashboard.

Let’s Login!

We should now be able to login. Browse to http://localhost:8000/users/login, enter in your user’s credentials, and give it a try.

laravel-auth-logged-in

Success!


Displaying the Appropriate Navigation Links

Ok, we can now register and login to our application, very cool! But we have a little quirk here, if you look at our navigation menu, even though we’re logged in, you can see that the register and login buttons are still viewable. Ideally, we want these to only display when the user is not logged in. Once the user does login though, we want to display a logout link. To make this change, let’s open up our main.blade.php file again. Here’s what our navbar code looks like at the moment:

<div class="navbar navbar-fixed-top">
  	<div class="navbar-inner">
    	<div class="container">
			<ul class="nav">  
				<li>{{ HTML::link('users/register', 'Register') }}</li>   
				<li>{{ HTML::link('users/login', 'Login') }}</li>   
			</ul>  
    	</div>
  	</div>
</div> 

Let’s modify this slightly, replacing our original navbar code, with the following:

<div class="navbar navbar-fixed-top">
  	<div class="navbar-inner">
    	<div class="container">
			<ul class="nav">  
				@if(!Auth::check())
					<li>{{ HTML::link('users/register', 'Register') }}</li>   
					<li>{{ HTML::link('users/login', 'Login') }}</li>   
				@else
					<li>{{ HTML::link('users/logout', 'logout') }}</li>
				@endif
			</ul>  
    	</div>
  	</div>
</div> 

All I’ve done is wrapped our li tags for our navbar in an if statement to check if the user is not logged in, using the !Auth::check() method. This method returns true if the user is logged in, otherwise, false. So if the user is not logged in, we display the register and login links, otherwise, the user is logged in and we display a logout link, instead.

laravel-auth-logout-link

Logging Out

Now that our navbar displays the appropriate links, based on the user’s logged in status, let’s wrap up this application by creating the getLogout action, to actually log the user out. Within your UsersController create a new action named getLogout:

public function getLogout() {
	
}

Now add in the following snippet of code to log the user out:

public function getLogout() {
	Auth::logout();
	return Redirect::to('users/login')->with('message', 'Your are now logged out!');
}

Here we call the Auth::logout() method, which handles logging the user out for us. Afterwards, we redirect the user back to the login page and give them a flash message letting them know that they have been logged out.

laravel-auth-logged-out

Conclusion

And that concludes this Laravel 4 Authentication tutorial. I hope you’ve found this helpful in setting up auth for your Laravel apps. If you have any problems or questions, feel free to ask in the comments and I’ll try my best to help you out. You can checkout the complete source code for the small demo app that we built throughout this tutorial on Github. Thanks for reading.

November 04 2013

17:00

Money Pattern: The Right Way to Represent Value-Unit Pairs

The Money Pattern, defined by Martin Fowler and published in Patterns of Enterprise Application Architecture, is a great way to represent value-unit pairs. It is called Money Pattern because it emerged in a financial context and we will illustrate its use mainly in this context using PHP.


A PayPal Like Account

I have no idea how PayPal is implemented, but I think it is a good idea to take its functionality as an example. Let me show you what I mean, my PayPal account has two currencies: US Dollars and Euro. It keeps the two values separated, but I can receive money in any currency, I can see my total amount in any of the two currencies and I can extract in any of the two. For the sake of this example, imagine that we extract in any of the currencies and automatic conversion is done if the balance of that specific currency is less than what we want to transfer but yet there is still enough money in the other currency. Also, we will limit the example to only two currencies.


Getting an Account

If I were to create and use an Account object, I would like to initialize it with an account number.

function testItCanCrateANewAccount() {
	$this->assertInstanceOf("Account", new Account(123));
}

This will obviously fail because we have no Account class, yet.

class Account {

}

Well, writing that in a new "Account.php" file and requiring it in the test, made it pass. However, this is all being done just to make ourselves comfortable with the idea. Next, I am thinking of getting the account’s id.

function testItCanCrateANewAccountWithId() {
	$this->assertEquals(123, (new Account(123))->getId());
}

I actually changed the previous test into this one. There is no reason to keep the first one. It lived it’s life, meaning it forced me to think about the Account class and actually create it. We can now move on.

class Account {

	private $id;

	function __construct($id) {
		$this->id = $id;
	}

	public function getId() {
		return $this->id;
	}

}

The test is passing and Account is starting to look like a real class.


Currencies

Based on our PayPal analogy, we may want to define a primary and a secondary currency for our account.

private $account;

protected function setUp() {
	$this->account = new Account(123);
}

[...]

function testItCanHavePrimaryAndSecondaryCurrencies() {
	$this->account->setPrimaryCurrency("EUR");
	$this->account->setSecondaryCurrency('USD');

	$this->assertEquals(array('primary' => 'EUR', 'secondary' => 'USD'), $this->account->getCurrencies());
}

Now the above test will force us to write the following code.

class Account {

	private $id;
	private $primaryCurrency;
	private $secondaryCurrency;

[...]

	function setPrimaryCurrency($currency) {
		$this->primaryCurrency = $currency;
	}

	function setSecondaryCurrency($currency) {
		$this->secondaryCurrency = $currency;
	}

	function getCurrencies() {
		return array('primary' => $this->primaryCurrency, 'secondary' => $this->secondaryCurrency);
	}

}

For the time being, we are keeping currency as a simple string. This may change in the future, but we are not there yet.


Gimme the Money

There are endless reasons why not to represent money as a simple value. Floating point calculations? Anyone? What about currency fractionals? Should we have 10, 100 or 1000 cents in some exotic currency? Well, this is another problem we will have to avoid. What about allocating indivisible cents?

There are just too many and exotic problems when working with money to write them down in code, so we will go directly on to the solution, the Money Pattern. This is quite a simple pattern, with great advantages and many use cases, far out of the financial domain. Whenever you have to represent a value-unit pair you should probably use this pattern.

UML

The Money Pattern is basically a class encapsulating an amount and currency. Then it defines all the mathematical operations on the value with respect to the currency. "allocate()" is a special function to distribute a specific amount of money between two or more recipients.

So, as a user of Money I would like to be able to do this in a test:

class MoneyTest extends PHPUnit_Framework_TestCase {

	function testWeCanCreateAMoneyObject() {
		$money = new Money(100, Currency::USD());
	}

}

But that won’t work yet. We need both Money and Currency. Even more, we need Currency before Money. This will be a simple class, so I will skip testing it for now. I am pretty sure the IDE can generate most of the code for me.

class Currency {

	private $centFactor;
	private $stringRepresentation;

	private function __construct($centFactor, $stringRepresentation) {
		$this->centFactor = $centFactor;
		$this->stringRepresentation = $stringRepresentation;
	}

	public function getCentFactor() {
		return $this->centFactor;
	}

	function getStringRepresentation() {
		return $this->stringRepresentation;
	}

	static function USD() {
		return new self(100, 'USD');
	}

	static function EUR() {
		return new self(100, 'EUR');
	}

}

That’s enough for our example. We have two static functions for USD and EUR currencies. In a real application, we would probably have a general constructor with a parameter and load all the currencies from a database table or, even better, from a text file.

Next, include the two new files in the test:

require_once '../Currency.php';
require_once '../Money.php';

class MoneyTest extends PHPUnit_Framework_TestCase {

	function testWeCanCreateAMoneyObject() {
		$money = new Money(100, Currency::USD());
	}

}

This test still fails, but at least it can find Currency now. We continue with a minimal Money implementation. A little bit more than what this test strictly requires since it is, again, mostly auto-generated code.

class Money {

	private $amount;
	private $currency;

	function __construct($amount, Currency $currency) {
		$this->amount = $amount;
		$this->currency = $currency;
	}

}

Please note, we enforce the type Currency for the second parameter in our constructor. This is a nice way to avoid our clients sending in junk as currency.


Comparing Money

The first thing that came into my mind after having the minimal object up and running was that I will have to compare money objects somehow. Then I remembered that PHP is quite smart when it comes to comparing objects, so I wrote this test.

function testItCanTellTwoMoneyObjectAreEqual() {
	$m1 = new Money(100, Currency::USD());
	$m2 = new Money(100, Currency::USD());

	$this->assertEquals($m1,$m2);
	$this->assertTrue($m1 == $m2);
}

Well, that actually passes. The "assertEquals" function can compare the two objects and even the built-in equality condition from PHP "==" is telling me what I expect. Nice.

But, what about if we are interested in one being bigger than the other? To my even greater surprise, the following test also passes without any problems.

function testOneMoneyIsBiggerThanTheOther() {
	$m1 = new Money(200, Currency::USD());
	$m2 = new Money(100, Currency::USD());

	$this->assertGreaterThan($m2, $m1);
	$this->assertTrue($m1 > $m2);
}

Which leads us to…

function testOneMoneyIsLessThanTheOther() {
	$m1 = new Money(100, Currency::USD());
	$m2 = new Money(200, Currency::USD());

	$this->assertLessThan($m2, $m1);
	$this->assertTrue($m1 < $m2);
}

… a test that passes immediately.


Plus, Minus, Multiply

Seeing so much PHP magic actually working with comparisons, I could not resist to try this one.

function testTwoMoneyObjectsCanBeAdded() {
	$m1 = new Money(100, Currency::USD());
	$m2 = new Money(200, Currency::USD());
	$sum = new Money(300, Currency::USD());

	$this->assertEquals($sum, $m1 + $m2);
}

Which fails and says:

Object of class Money could not be converted to int

Hmm. That sounds pretty obvious. At this point we have to make a decision. It is possible to continue this exercise with even more PHP magic, but this approach will, at some point, transform this tutorial into a PHP cheatsheet instead of a design pattern. So, let’s make the decision to implement the actual methods to add, subtract and multiply money objects.

function testTwoMoneyObjectsCanBeAdded() {
	$m1 = new Money(100, Currency::USD());
	$m2 = new Money(200, Currency::USD());
	$sum = new Money(300, Currency::USD());

	$this->assertEquals($sum, $m1->add($m2));
}

This test fails as well, but with an error telling us there is no "add" method on Money.

public function getAmount() {
	return $this->amount;
}

function add($other) {
	return new Money($this->amount + $other->getAmount(), $this->currency);
}

To sum up two Money objects, we need a way to retrieve the amount of the object we pass in as the argument. I prefer to write a getter, but setting the class variable to be public would also be an acceptable solution. But what if we want to add Dollars to Euros?

/**
 * @expectedException Exception
 * @expectedExceptionMessage Both Moneys must be of same currency
 */
function testItThrowsExceptionIfWeTryToAddTwoMoneysWithDifferentCurrency() {
	$m1 = new Money(100, Currency::USD());
	$m2 = new Money(100, Currency::EUR());

	$m1->add($m2);
}

There are several ways to deal with operations on Money objects with different currencies. We will throw an exception and expect it in the test. Alternatively, we could implement a currency conversion mechanism in our application, call it, convert both Money objects into some default currency and compare them. Or, if we would have a more sophisticated currency conversion algorithm, we could always convert from one to another and compare in that converted currency. The thing is, that when conversion comes into place, conversion fees have to be considered and things will be getting quite complicated. So let’s just throw that exception and move on.

public function getCurrency() {
	return $this->currency;
}

function add(Money $other) {
	$this->ensureSameCurrencyWith($other);
	return new Money($this->amount + $other->getAmount(), $this->currency);
}

private function ensureSameCurrencyWith(Money $other) {
	if ($this->currency != $other->getCurrency())
		throw new Exception("Both Moneys must be of same currency");
}

That’s better. We do a check to see if the currencies are different and throw an exception. I already wrote it as a separate private method, because I know we will need it in the other mathematical operations as well.

Subtraction and multiplication are very similar to addition, so here is the code and you can find the tests in the attached source code.

function subtract(Money $other) {
	$this->ensureSameCurrencyWith($other);
	if ($other > $this)
		throw new Exception("Subtracted money is more than what we have");
	return new Money($this->amount - $other->getAmount(), $this->currency);
}

function multiplyBy($multiplier, $roundMethod = PHP_ROUND_HALF_UP) {
	$product = round($this->amount * $multiplier, 0, $roundMethod);
	return new Money($product, $this->currency);
}

With subtraction, we have to make sure we have enough money and with multiplication, we must take actions to round things up or down so that division (multiplication with numbers less than one) will not produce “half cents”. We keep our amount in cents, the lowest possible factor of the currency. We can not divide it more.


Introducing Currency to Our Account

We have an almost complete Money and Currency. It is time to introduce these objects to Account. We will start with Currency, and change our tests accordingly.

function testItCanHavePrimaryAndSecondaryCurrencies() {
	$this->account->setPrimaryCurrency(Currency::EUR());
	$this->account->setSecondaryCurrency(Currency::USD());

	$this->assertEquals(array('primary' => Currency::EUR(), 'secondary' => Currency::USD()), $this->account->getCurrencies());
}

Because of the dynamic typing nature of PHP, this test passes without any problems. However I would like to force the methods in Account to use Currency objects and do not accept anything else. This is not mandatory, but I find these kinds of type hintings extremely useful when someone else needs to understand our code.

function setPrimaryCurrency(Currency $currency) {
	$this->primaryCurrency = $currency;
}

function setSecondaryCurrency(Currency $currency) {
	$this->secondaryCurrency = $currency;
}

Now it is obvious to anyone reading this code for the first time that Account works with Currency.


Introducing Money to Our Account

The two basic actions any account must provide is: deposit – meaning adding money to an account – and withdraw – meaning removing money from an account. Depositing has a source and withdrawing has a destination other than our current account. We will not go into details about how to implement these transactions, we will only concentrate on implementing the effects these have on our account. So, we can imagine a test like this for depositing.

function testAccountCanDepositMoney() {
	$this->account->setPrimaryCurrency(Currency::EUR());
	$money = new Money(100, Currency::EUR()); //That's 1 EURO
	$this->account->deposit($money);

	$this->assertEquals($money, $this->account->getPrimaryBalance());
}

This will force us to write quite a lot of implementation code.

class Account {

	private $id;
	private $primaryCurrency;
	private $secondaryCurrency;
	private $secondaryBalance;
	private $primaryBalance;

	function getSecondaryBalance() {
		return $this->secondaryBalance;
	}

	function getPrimaryBalance() {
		return $this->primaryBalance;
	}

	function __construct($id) {
		$this->id = $id;
	}

	[...]

	function deposit(Money $money) {
		$this->primaryCurrency == $money->getCurrency() ? $this->primaryBalance = $money : $this->secondaryBalance = $money;
	}

}

OK, OK. I know, I wrote more than what was absolutely necessary, for production. But I don’t want to bore you to death with baby-steps and I am also fairly sure the code for secondaryBalance will work correctly. It was almost entirely generated by the IDE. I will even skip testing it. While this code makes our test pass, we have to ask ourselves what happens when we do subsequent deposits? We want our money to be added to the previous balance.

function testSubsequentDepositsAddUpTheMoney() {
	$this->account->setPrimaryCurrency(Currency::EUR());
	$money = new Money(100, Currency::EUR()); //That's 1 EURO
	$this->account->deposit($money); //One euro in the account
	$this->account->deposit($money); //Two euros in the account

	$this->assertEquals($money->multiplyBy(2), $this->account->getPrimaryBalance());
}

Well, that fails. So we have to update our production code.

function deposit(Money $money) {
	if ($this->primaryCurrency == $money->getCurrency()){
		$this->primaryBalance = $this->primaryBalance ? : new Money(0, $this->primaryCurrency);
		$this->primaryBalance = $this->primaryBalance->add($money);
	}else {
		$this->secondaryBalance = $this->secondaryBalance ? : new Money(0, $this->secondaryCurrency);
		$this->secondaryBalance = $this->secondaryBalance->add($money);
	}
}

This is much better. We are probably done with the deposit method and we can continue with withdraw.

function testAccountCanWithdrawMoneyOfSameCurrency() {
	$this->account->setPrimaryCurrency(Currency::EUR());
	$money = new Money(100, Currency::EUR()); //That's 1 EURO
	$this->account->deposit($money);
	$this->account->withdraw(new Money(70, Currency::EUR()));

	$this->assertEquals(new Money(30, Currency::EUR()), $this->account->getPrimaryBalance());

}

This is just a simple test. The solution is simple, also.

function withdraw(Money $money) {
	$this->primaryCurrency == $money->getCurrency() ?
		$this->primaryBalance = $this->primaryBalance->subtract($money) :
		$this->secondaryBalance = $this->secondaryBalance->subtract($money);
}

Well, that works, but what if we want to use a Currency that is not in our account? We should throw an Excpetion for that.

/**
 * @expectedException Exception
 * @expectedExceptionMessage This account has no currency USD
 */

function testThrowsExceptionForInexistentCurrencyOnWithdraw() {
	$this->account->setPrimaryCurrency(Currency::EUR());
	$money = new Money(100, Currency::EUR()); //That's 1 EURO
	$this->account->deposit($money);
	$this->account->withdraw(new Money(70, Currency::USD()));
}

That will also force us to check our currencies.

function withdraw(Money $money) {
	$this->validateCurrencyFor($money);
	$this->primaryCurrency == $money->getCurrency() ?
		$this->primaryBalance = $this->primaryBalance->subtract($money) :
		$this->secondaryBalance = $this->secondaryBalance->subtract($money);
}

private function validateCurrencyFor(Money $money) {
	if (!in_array($money->getCurrency(), $this->getCurrencies()))
			throw new Exception(
				sprintf(
					'This account has no currency %s',
					$money->getCurrency()->getStringRepresentation()
				)
			);
}

But what if we want to withdraw more than what we have? That case was already addressed when we implemented subtraction on Money. Here is the test that proves it.

/**
 * @expectedException Exception
 * @expectedExceptionMessage Subtracted money is more than what we have
 */
function testItThrowsExceptionIfWeTryToSubtractMoreMoneyThanWeHave() {
	$this->account->setPrimaryCurrency(Currency::EUR());
	$money = new Money(100, Currency::EUR()); //That's 1 EURO
	$this->account->deposit($money);
	$this->account->withdraw(new Money(150, Currency::EUR()));
}

Dealing With Withdraw and Exchange

One of the more difficult things to deal with when we are working with multiple currencies is exchanging between them. The beauty of this design pattern is that it allows us to somewhat simplify this problem by isolating and encapsulating it in its own class. While the logic in an Exchange class may be very sophisticated, its use becomes much easier. For the sake of this tutorial, let’s imagine that we have some very basic Exchange logic only. 1 EUR = 1.5 USD.

class Exchange {

	function convert(Money $money, Currency $toCurrency) {
		if ($toCurrency == Currency::EUR() && $money->getCurrency() == Currency::USD())
			return new Money($money->multiplyBy(0.67)->getAmount(), $toCurrency);
		if ($toCurrency == Currency::USD() && $money->getCurrency() == Currency::EUR())
			return new Money($money->multiplyBy(1.5)->getAmount(), $toCurrency);
		return $money;
	}

}

If we convert from EUR to USD we multiply the value by 1.5, if we convert from USD to EUR we divide the value by 1.5, otherwise we presume we are converting two currencies of the same type, so we do nothing and just return the money. Of course, in reality this would be a much more complicated class.

Now, having an Exchange class, Account can make different decisions when we want to withdraw Money in a currency, but we do not hove enough in that specific currency. Here is a test that better exemplifies it.

function testItConvertsMoneyFromTheOtherCurrencyWhenWeDoNotHaveEnoughInTheCurrentOne() {
	$this->account->setPrimaryCurrency(Currency::USD());
	$money = new Money(100, Currency::USD()); //That's 1 USD
	$this->account->deposit($money);

	$this->account->setSecondaryCurrency(Currency::EUR());
	$money = new Money(100, Currency::EUR()); //That's 1 EURO = 1.5 USD
	$this->account->deposit($money);

	$this->account->withdraw(new Money(200, Currency::USD())); //That's 2 USD

	$this->assertEquals(new Money(0, Currency::USD()), $this->account->getPrimaryBalance());
	$this->assertEquals(new Money(34, Currency::EUR()), $this->account->getSecondaryBalance());
}

We set our account’s primary currency to USD and deposit one dollar. Then we set the secondary currency to EUR and deposit one Euro. Then we withdraw two dollars. Finally, we expect to remain with zero dollars and 0.34 Euros. Of course this test throws an exception, so we have to implement a solution to this dilemma.

function withdraw(Money $money) {
	$this->validateCurrencyFor($money);
	if ($this->primaryCurrency == $money->getCurrency()) {
		if( $this->primaryBalance >= $money ) {
			$this->primaryBalance = $this->primaryBalance->subtract($money);
		}else{
			$ourMoney = $this->primaryBalance->add($this->secondaryToPrimary());
			$remainingMoney = $ourMoney->subtract($money);
			$this->primaryBalance = new Money(0, $this->primaryCurrency);
			$this->secondaryBalance = (new Exchange())->convert($remainingMoney, $this->secondaryCurrency);
		}

	} else {
		$this->secondaryBalance = $this->secondaryBalance->subtract($money);
	}
}

private function secondaryToPrimary() {
	return (new Exchange())->convert($this->secondaryBalance, $this->primaryCurrency);
}

Wow, lots of changes had to be made to support this automatic conversion. What is happening is that if we are in the case of extracting from our primary currency and we don’t have enough money, we convert our balance of the secondary currency to primary and try the subtraction again. If we still do not have enough money, the $ourMoney object will throw the appropriate exception. Otherwise, we will set our primary balance to zero and we will convert the remaining money back to the secondary currency and set our secondary balance to that value.

It remains up to our account’s logic to implement a similar automatic conversion for secondary currency. We will not implement such a symmetrical logic. If you like the idea, consider it as an exercise for you. Also, think about a more generic private method that would do the magic of auto-conversions in both cases.

This complex change to our logic also forces us to update another one of our tests. Whenever we want to auto-convert we must have a balance, even if it is just zero.

/**
 * @expectedException Exception
 * @expectedExceptionMessage Subtracted money is more than what we have
 */
function testItThrowsExceptionIfWeTryToSubtractMoreMoneyThanWeHave() {
	$this->account->setPrimaryCurrency(Currency::EUR());
	$money = new Money(100, Currency::EUR()); //That's 1 EURO
	$this->account->deposit($money);

	$this->account->setSecondaryCurrency(Currency::USD());
	$money = new Money(0, Currency::USD());
	$this->account->deposit($money);
	$this->account->withdraw(new Money(150, Currency::EUR()));
}

Allocating Money Between Accounts

The last method we need to implement on Money is allocate. This is the logic that decides what to do when dividing money between different accounts which can’t be made exactly. For example, if we have 0.10 cents and we want to allocate them between two accounts in a proportion of 30-70 percents, that is easy. One account will get three cents and the other seven. However, if we want to make the same 30-70 ratio allocation of five cents, we have a problem. The exact allocation would be 1.5 cents in one account and 3.5 in the other. But we can not divide cents, so we have to implement our own algorithm to allocate the money.

There can be several solutions to this problem, one common algorithm is to add one cent sequentially to each account. If an account has more cents than its exact mathematical value, it should be eliminated from the allocation list and receive no further money. Here is a graphical representation.

Allocations

And a test to prove our point is below.

function testItCanAllocateMoneyBetween2Accounts() {
	$a1 = $this->anAccount();
	$a2 = $this->anAccount();
	$money = new Money(5, Currency::USD());
	$money->allocate($a1, $a2, 30, 70);

	$this->assertEquals(new Money(2, Currency::USD()), $a1->getPrimaryBalance());
	$this->assertEquals(new Money(3, Currency::USD()), $a2->getPrimaryBalance());
}

private function anAccount() {
	$account = new Account(1);
	$account->setPrimaryCurrency(Currency::USD());
	$account->deposit(new Money(0, Currency::USD()));
	return $account;
}

We just create a Money object with five cents and two accounts. We call allocate and expect the two to three values to be in the two accounts. We also created a helper method to quickly create accounts. The test fails, as expected, but we can make it pass quite easily.

function allocate(Account $a1, Account $a2, $a1Percent, $a2Percent) {
	$exactA1Balance = $this->amount * $a1Percent / 100;
	$exactA2Balance = $this->amount * $a2Percent / 100;

	$oneCent = new Money(1, $this->currency);
	while ($this->amount > 0) {
		if ($a1->getPrimaryBalance()->getAmount() < $exactA1Balance) {
			$a1->deposit($oneCent);
			$this->amount--;
		}
		if ($this->amount <= 0)
			break;
		if ($a2->getPrimaryBalance()->getAmount() < $exactA2Balance) {
			$a2->deposit($oneCent);
			$this->amount--;
		}
	}
}

Well, not the simplest code, but it is working correctly, as the passing of our test proves it. The only thing we can still do to this code is to reduce the small duplication inside the while loop.

function allocate(Account $a1, Account $a2, $a1Percent, $a2Percent) {
	$exactA1Balance = $this->amount * $a1Percent / 100;
	$exactA2Balance = $this->amount * $a2Percent / 100;

	while ($this->amount > 0) {
		$this->allocateTo($a1, $exactA1Balance);
		if ($this->amount <= 0)
			break;
		$this->allocateTo($a2, $exactA2Balance);
	}
}

private function allocateTo($account, $exactBalance) {
	if ($account->getPrimaryBalance()->getAmount() < $exactBalance) {
		$account->deposit(new Money(1, $this->currency));
		$this->amount--;
	}
}

Final Thoughts

What I find amazing with this little pattern is the large range of cases where we can apply it.

We are done with our Money Pattern. We saw that it is quite a simple pattern, which encapsulates the specifics of the money concept. We also saw that this encapsulation alleviates the burden of computations from Account. Account can concentrate on representing the concept from a higher level, from the point of view of the bank. Account can implement methods like connection with account holders, IDs, transactions and money. It will be an orchestrator not a calculator. Money will take care of calculations.

What I find amazing with this little pattern is the large range of cases where we can apply it. Basically, every time you have a value-unit pair, you can use it. Imagine you have a weather application and you want to implement a representation for temperature. That would be the equivalent of our Money object. You can use Fahrenheit or Celsius as currencies.

Another use case is when you have a mapping application and you want to represent distances between points. You can easily use this pattern to switch between Metric or Imperial measurements. When you work with simple units, you can drop the Exchange object and implement the simple conversion logic inside your “Money” object.

So, I hope you enjoyed this tutorial and I am eager to hear about the different ways that you might use this concept. Thank you for reading.

October 28 2013

07:30

Shrink the Web: Automated Screenshots Enrich the User Experience of Your Web Projects


  

An image is worth a thousand words. We here at Noupe Design Magazine live up to this saying every day. Thus, services that visually break up the gray by adding imagery to long texts are always appreciated. Shrink The Web by Neosys Consulting is one of those services. It automates the use of recent screenshots for any given URL in your web projects. The service is free, yet can be leveled up with the help of a few paid extensions, if need be. We have taken a closer look at Shrink The Web…

October 23 2013

14:00

Dates and Time – The OOP Way

The Date/Time PHP extension is a set of classes that allow you to work with almost all of the date and time related tasks. It’s been available since the release of PHP 5.2 and the extension introduced several new classes, all of which are mapped to real life scenarios:

  • A date or a time is represented by a DateTime object.
  • A timezone of the world is represented by a DateTimeZone object.
  • DateInterval objects represent an interval. For example, when we say two days from now on, the “two days” is the interval. The DateInterval object doesn’t rely on a specific date or time.
  • DatePeriod objects represent a period between two dates.

Now don’t let the last two tip you off, we’ll be looking at real world usage of these two in a moment.


From date() to DateTime

Whenever we want to show a date we used date(), it’s simple and it works. You just need to pass the date format you need. But it’s a real pain to manipulate, a good example is formatting dates and times according to a custom timezone.

DateTime does more than just return a formatted date, but before we go any further, you need to initiate a new DateTime object which represents your date and or time. Then we can do all sorts of cool stuff with it. A new instance is created just like any other PHP class.

$date = new DateTime();

The constructor of DateTime accepts a string parameter which defaults to “now”, the current time and date. To create an object for a specific date, you should pass the specific date and time to it. Formatting for the parameter is self explanatory in most cases. Below you can find a few different examples of constructing your DateTime object:

new DateTime('2013, March 24') //DateTime representing 2013, March 24
new DateTime('2013-03-24') //DateTime representing 2013, March 24
new DateTime('+2 days') //DateTime representing 2 days from now on.
new DateTime('tomorrow')

When PHP is having a hard time understanding the format, it will throw an exception. A full list of the available formatting can be found in in the documentation

If there is no formatting that matches your needs, you can specify your own format by using DateTime::createFromFormat

DateTime::createFromFormat('j-M-Y', '24-Mar-2013');

Now that we have a DateTime object in hand we can do whole bunch of stuff, rather easily.

Unix Timestamp

$date->getTimestamp(); //returns a unix timestamp

Modifying Date/Times

$date->setDate(2013, 12, 30); //yyyy, mm, dd will set the the specified date
$date->setTime(12, 3, 20); //hh, mm, ss (optional) will modify the time
$date->modify('tomorrow'); //string based manipulation
$date->setTimestamp(1364798550); //modify using a unix timestamp

Note that when out-of-range values are set, PHP will modify the date accordingly. For example, $date->setDate(2013, 12, 35); will generate 2014-01-04, the same goes for time.


Working With Multiple Dates

Now that you’re obsessed with DateTime, the next thing you know, your apps will be filled with DateTime objects. You’ll start to love dates and times like never before. From now on, you’ll be dealing with DateTime objects, not “strings” that you have to pass to the strtotime function when you need to do a little math.

Say for example that you need to compare two birthdays:

$sheldon = new DateTime('May 20th, 1980');
$neo     = new DateTime('March 11th, 1962');

if ($sheldon > $neo)
    echo 'Sheldon is younger than neo';

Another scenario might be comparing two dates. We can compare dates against one another like so:

$diff = $neo->diff($sheldon);

The diff call returns a DateInterval object. If we dump out the return value:

DateInterval Object
(
    [y] => 18
    [m] => 2
    [d] => 9
    [h] => 0
    [i] => 0
    [s] => 0
    [invert] => 0
    [days] => 6645
)

These are public properties. You can generate some friendly output from a DateInterval object:

$diff->format('Neo is older by %Y years and %m months older'); //Neo is older by 18 years and 2 months

What’s best about the DateInterval object is that you can apply the interval to another DateTime object:

$neo->add($diff); //neo's birthday changed to sheldon's

Note: Modifications to DateTime, such as adding doesn’t return new DateTime objects, it affects the original object. Always keep this in mind when passing around DateTime objects throughout your app. PHP 5.5 introduced a new class that returns new objects upon modification.

diff isn’t the only place where you can generate a DateInterval object. Since it’s a class, new objects can be initiated as usual:

$new_diff = new DateInterval('P2Y');

The amount of years/months/days etc., are passed in as a string to the constructor. More information can be found in the constructor’s documentation.


Working With Timezones

When creating new DateTime objects, the second argument of the constructor defines a timezone. If we skip this, a default timezone will be grabbed from the php.ini‘s date.timezone. You can modify this at runtime by calling date_default_timezone_set:

date_default_timezone_set('America/New_York');
new DateTime('today'); //datetime object is on New York time

You can also change timezones on the fly. As you may have guessed, first we need a Timezone object.

$timezone = new DateTimeZone('America/New_York');
$sheldon->setTimezone($timezone); //sheldon's birthday now on to New York

You can define the timezone while creating your new DateTime object:

$sheldon = new DateTime('May 20th, 1980', $timezone);

However, an important thing to note is that setTimezone modifies the original DateTime object. What we’re basically asking is, “format this date, to this timezone” whenever we call the setTimezone method. Now on the other hand, in the last example where we pass the timezone into the DateTime constructor, we’re saying, “the date I’m creating is in this timezone”.

A list of valid timezones are available in the online documentation.


DatePeriods

I think the official manual provides the best explanation:

A date period allows iteration over a set of dates and times, recurring at regular intervals, over a given period.

DatePeriod allows us to generate a set of DateTimes using two days that we define between an interval. We pass a starting date, an interval and an ending date. On each interval a new DateTime object is created.

Let’s say that we want to get all of Sheldon’s birth dates, since his birth:

//since birthdays occur every year, the interval is one year
$interval = new DateInterval('P1Y');

//third argument is the end date, new DateTime() == right now
$period   = new DatePeriod($sheldon, $interval, new DateTime());

foreach($period as $dt) {
    //DateTime objects
    echo $dt->format('Y-m-d - D'), "\n";    
}

The result would be:

1981-05-20 - Wed
1982-05-20 - Thu
1983-05-20 - Fri
1984-05-20 - Sun
1985-05-20 - Mon
1986-05-20 - Tue
...

Now by default, the DatePeriod includes the starting date that we pass in. However, the fourth argument to the constructor allows us to skip the start date:

$period   = new DatePeriod($sheldon, $interval, new DateTime(), DatePeriod::EXCLUDE_START_DATE);

Let’s see how many birthday parties Neo has had before Sheldon was born:

$bdays   = new DatePeriod($neo, $interval, $sheldon, DatePeriod::EXCLUDE_START_DATE);
echo iterator_count($bdays);

Extending

All of the classes that we’ve covered today can be extended to use with your own methods. One popular usage is extending the DateTime with a __toString method so that you can properly print out a DateTime object without calling format.


A Couple Usage Scenarios

  • One of my personal approaches to using DateTime objects, is when dealing with date/time columns in databases. All of the dates are stored as UTC timezone dates. The app code only works with DateTime objects, but before the end query is generated, all of the dates are formatted to UTC. This approach has allowed me to work with multiple timezone inputs easily.

    I can pass in a New York time object and completely forget about formatting it, before going to the database. I can easily switch between Unix timestamps and regular date-time formatting in my database at anytime, my app code doesn’t care as long as it gets a DateTime object.

  • I’ve also used DateInterval to simplify subscription payment logic. Using DateInterval objects to define the time between the subscription has made things really easy. I just need to apply the interval to last payment date.

Do you have any good date/time usage examples? Share them in the comments.


Wrap Up

The date time extension has so much to offer, if you’re on the bleeding edge, there are new classes and interfaces introduced since PHP 5.5. Be sure to checkout the manual. Thanks for reading.

Tags: PHP DateTime

October 15 2013

06:30

One-Stop Shop: PHP-Tool Munee Cares for All your Website’s Assets


  

Cody Lundquist, Australian with a Swedish sounding name, created a free asset-management based on PHP 5.3. Its feature-set is astounding, yet demands a special preliminary treatment of the websites, it’s supposed to be working on. Munee is able to manage any kind of possible asset, be it images or other files, JavaScript, CSS, LESS, SCSS or even CoffeeScript.

Older posts are this way If this message doesn't go away, click anywhere on the page to continue loading posts.
Could not load more posts
Maybe Soup is currently being updated? I'll try again automatically in a few seconds...
Just a second, loading more posts...
You've reached the end.
Get rid of the ads (sfw)

Don't be the product, buy the product!

Schweinderl