Horizontal Code Reuse Through Traits

As of version 5.4, PHP has exposed horizontal code reuse through Traits. Horizontal code reuse allows developers to bypass class hierarchies and reuse bits and pieces of code in other classes. Prior to traits, developers would often put functionality in parent class as shown below.

<?php

class BaseModel
{
    protected $fillable = array();

    public function hydrate(array $rawData)
    {
        foreach($this->fillable as $attribute) {
            $this->$attribute = $rawData[$attribute];
        }
    }

    // Other Model specific code
}

class User extends BaseModel
{
    protected $fillable = ['id', 'username', 'password'];
    protected $id;
    protected $username;
    protected $password;
}

$user = new User;
$user->hydrate(array(
    'id' => 1,
    'username' => 'baileylo',
    'password' => 'password'
));

There doesn’t appear to be anything wrong with this code and it doesn’t look all that different from the trait implementation. But the benefit of traits is it allows you to avoid this class hierarchy. At some point you will find yourself writing a class that would benefit from the hydrate function, but it wouldn’t require the other code found in BaseModel. Before Traits you only had two options, copy and paste code or update your class hierarchy to look like this

<?php

class Hydrate
{
    // Implements hydrate method
}

class BaseModel extends Hydrate {}

class User extends BaseModel {}

class OtherObject extends Hydrate{}

While this is some what maintainable with one hydrate method, it will become unruly in the future. If you were to implement this in traits it could look like this:

<?php

trait HydrateTrait
{
    protected $fillable = [];

    public function hydrate(array $raw_data)
    {
        foreach ($this->fillable as $attribute) {
            if (array_key_exists($attribute, $raw_data)) {
                $func = 'set' . lcfirst($attribute);

                if (method_exists($this, $func)) {
                    $this->$func($raw_data[$attribute]);
                } else {
                    $this->$attribute = $raw_data[$attribute];
                }
            }
        }
    }
}

trait DateColumnTrait
{
    protected $createdOn;
    protected $updatedOn;

    public function setCreatedOn($mysqlDateString)
    {
        $this->createdOn = new DateTime($mysqlDateString);
    }

    public function setUpdatedOn($mysqlDateString)
    {
        $this->updatedOn = new DateTime($mysqlDateString);
    }
}

class User
{
    use HydrateTrait;
    use DateColumnTrait;

    protected $id;
    protected $slug;
    protected $name;

    public function __construct()
    {
        $this->fillable = ['id', 'slug', 'name', 'createdOn', 'updatedOn'];
    }
}

class OtherObject
{
    use HydrateTrait;

    protected $fillable = ['name', 'variable', 'parameter'];
    protected $name;
    protected $variable;
    protected $parameter;
}

From this implementation you can see the benefits of traits. I no longer have the larger than necessary class hierarchy. Also the names of traits themselves allude to the functionality provided. In my original example BaseModel does not inform the user of any specific functionality; instead the name implies that all models should extend this BaseModel. With HydrateTrait the reader has a good idea of what the trait does.

Traits have the same privilege as the object that uses it, if an attribute is private, the trait will be able to access it. In my playing with traits, I’ve decided to define attributes specifically used by the trait(fillable, createdOn, updatedOn) on the trait itself. While this hides attributes from the object, it makes the trait clearer. I believe it also makes testing easier to some extent. If you define the attribute in both the trait and the object it will generate a PHP strict error.

Testing Traits in PHPUnit

Testing for traits can be done in a couple different ways, Florian Wolters has written a good blog post on the subject. PHPUnit >= 3.7 has a function, getObjectForTrait, which will create classes that implement a trait. The test for DateColumnTrait could look something like this:

<?php

class DateColumnTraitTest extends PHPUnit_Framework_TestCase
{
    protected $traitObject;

    public function setUp()
    {
        $this->traitObject = $this->getObjectForTrait('DateColumnTrait');
    }

    public function testSetCreatedOn()
    {
        $dt = new DateTime();
        $this->traitObject->setCreatedOn($dt->format('Y-m-d H:i:s'));
        $this->assertAttributeEquals($dt, 'createdOn', $this->traitObject);
    }
}

Cleaning up your templates with array_chunk

array_chunk splits an array into a series of arrays of a given size or as the docs say “array_chunk — Split an array into chunks”. This is useful when you want to display an array in multiple columns. Take the following template:

<?php $total = count($posts) ?>

<?php foreach($posts as $k => $post): ?>

    <?php if($k == 0): ?>
        <div class="row">
    <?php elseif ($k % 3 == 0): ?>
        </div><div class="row">
    <?php endif; ?>

    <!-- $post dom here -->

    <?php if($total === $k - 1): ?>
        </div>
    <?php endif; ?>
<?php endforeach; ?>

This code displays posts in a series of rows. Each row contains 3 posts and is wrapped in <div class="row"></div>. The code works, but it’s not the easiest on the eyes. The if else at the top of the loop is confusing. Below we write the same code but using array_chunk instead of index math.

<?php foreach(array_chunk($posts, 3) as $postsInRow): ?>
    <div class="row">
        <?php foreach($postsInRow as $post): ?>
            <!-- $post dom here -->
        <?php endforeach; ?>
    </div>
<?php endforeach; ?>

There are a couple of benefits here. Since we’re using array_chunk the row length, 3, is easy to find and change. We no longer rely on index math, this prevents potential issues when $posts is an associative array. Finally the dom structure inside the loop matches the output structure. There is no longer a closing div tag at the top of our loop.

Redirecting http to https using Symfony 2 Routes

Symfony 2′s Routing Component route matching works off the simple concept; return the matching route or throw an exception. It comes with 5 standard exceptions, the most common being RouteNotFoundException.

Unfortunately, the standard Symfony UrlMatcher throws a RouteNotFoundException if the url does not match any routes or if a routes protocol was set HTTPS and the request was HTTP. This prevents developers from correctly redirecting HTTP to HTTPS urls. Luckily, the routing component ships with another matcher, RedirectableUrlMatcher. Since this is an abstract class, you must define your own child class and implement redirect method. The method takes 3 parameters $path, $route, and $scheme; the return value will be the return value of the match method. In Silex’s implementation the correct URL is returned with some sugar to make the page redirect; I prefer to throw a custom exception. I believe that this is more consistent with the how the match method handles other invalid requests; which throws an MethodNotAllowedException when POST is used on a GET request. I’ve included my code on how I would handle such an exception. The Silex example shows a good way to build the correct URL.

use MyApp\RedirectableUrlMatcher;
use MyApp\Exception\HTTPRedirectException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Exception\RouteNotFoundException;

$context = new RequestContext();
$context->fromRequest(Request::createFromGlobals());

// $routes is an instance of RouteCollection

try {
    $matcher = new RedirectableUrlMatcher($routes, $context);
    $route = $matcher->match($context->getPathInfo());
} catch (RouteNotFoundException $e) {
    // Show 404 Page
} catch (HTTPRedirectException $e) {
    // HTTPRedirectException is a child of Exception
    // where the message is the URL to redirect to
    header('location: ' . $e->getMessage());
    exit;
}

An alternative to confirmation email links

Everybody has suffered through the tedious process of account registration and email confirmation. You want to join a cool new site your friend told you about. But before you can do anything you have to click a stupid link in what otherwise is the worlds most useless email. The entire process hinges on an email that’s only value is a link that reads “Click me”.

Confirmation emails have one goal: make sure the recipient clicks the “verify your email address” link. These emails do not provide the recipient with any useful information about the site or places they should visit. This is by design – its imperative that the user clicks the verify your account link; but there’s a better solution. For years sites have employed tracking pixels, a 1×1 pixel image, to record information, such as open rates, to the servers. This same technology could be used for email verification.

The email would contain tracking pixel, but instead of tracking information the email would verify the recipients email address. Text-only email recipients would still require an authentication link. And it would not be a bad idea to include the old boring “Verify Account” link for email clients that don’t load images by default. Either way, the verification email could be redesigned for user engagement rather than the singular goal of verify an email.

Using the tracking pixel to handle email authentication will change the way new users are first introduced to the site. Where users were once greeted with a “verify account” link, they can now see trending articles, essential new features, or other essential site information.

Stop using separate URLs for mobile sites!

Today my friend emailed me a link to an article on TheVerge. Unfortunately my friend had been browsing on his smart phone and linked the mobile specific URL. When I opened the article on my iMac I was greeted with a 450×300 pixel image stretched to over 400% its natural width. For a less painful user experience TheVerge should redirect users using non mobile devices to the standard site.

If you’re looking for an easy to use server-side browser detection library I highly recommend Jon Ursenbach’s MobileESP fork.

What do normal people do?

I played tennis in college. This meant that there was between a two and a half to three hour long block each day that I spent at tennis practice. The week before finals was always a dead week, the sports teams were not allowed to hold practice. I’d come home from my 2 o’clock class, the one before my practice, and sit around for 3 hours wondering what normal people do with this 3 hour period.
For the better part of the last three and a half years of my life I’ve spent anywhere between 3 to 4 hours a day commuting to and from work. The earliest I get home is 8pm. Today, to celebrate 4th of July, we were allowed to leave earlier from work. As I talked to my wife at 7:30pm, after having mowed the lawn and done other chores, I caught myself wondering again. What do normal people do with all this time after work?

An issue with the full stack framework

I’ve tried several times to learn RoR. I can get around Ruby in a haphazard manner. I’ve even written a few small RoR sites. But there was so much happening behind the scenes, under the hood, that I never felt happy with my knowledge and understanding of what was going on. Today while listening to @funkatron‘s EngineYard podcast, he mentioned that there was a ruby/erlang dev on their team. The dev found the code base much easier to parse and understand after switching from a full stack framework to Slim Framework .

People often post on user boards – “I want to learn php which framework should I use?”. If you’re going about learning a language by using a framework written in that language – stay away from full stack frameworks. You’ll have a much enjoyable time using a simpler more “declarative” framework.

Issues with alternative captchas

Nobody likes captchas, spammers find them annoying and users find them obnoxious. But it’s an easy way to separate out the spammers from the users. There have long been many alternative solutions to the common captcha, and they all have their own issues.

One solution is to show the user an easy math problem: 2 + three =. While this is easier for the user, a quick Google search will give the spammer the answer.

Today I saw another alternative for captchas in Hasin’s blog post Time to put those FUCKING captchas to an end. His alternative captcha theory is to show you an easily identified object, a tree or statue, and have you say what it is. Spammer’s solution: run the image through Google’s photo search. The third example, where the picture asks “There are two ___” and then shows two squares and three triangles, did stump Google. But this image would not be difficult to parse and answer.

The current captcha system is painful, tedious, and can be comical at times, but it does knock off a majority of the spammers.

Date Formatting and Customizing Devise

This week will focus on formatting the rails app to be more user friendly. If this is your first time to this site, please see the first post on making your owns rails blog. Before we start with this weeks topics I made some basic CSS and formatting changes that can be seen here. Currently the blog displays dates in RFC format and only shows the authors email. This week you’ll use Rails I8ln tools to build custom date formatting. We’ll also extend Devise, allowing users to login with a user name.

Custom Date Formatting

There are two main theories to Date Formatting. Building a time_format initializer or adding date formats to your locales file. Since date formats differ between regions it makes sense to place these formats in your locales file.

Open up config/locales/en.yml, app/view/posts/show.html.erb, and app/view/posts/index.html.erb and make these changes. In locales file, the format named “default” will be used if no format is specified. In the view file, those are L’s that have been added prior to the dates. L is a default rails helper method for localize and will apply the localization for that data in our case a timestamp. You can add as many differing formats as you’d like. You can call these by using the following code

<%= l Time.now, :format => :awesome %>

A cheat sheet of all ruby date formats can be found here. If you would like more information on locale files, Ruby on Rails has a good guide on it.

Usernames

Adding usernames is a breeze with Devise. The first step to is create a migration to add the column.
$rails g migration addUsernameToUser username:string
Open up the generated migration and make these changes then run the migration.
Since we plan to allow users to login using their username we’ve made it a unique key, the database will not allow more than 1 User to have the same username. Now that the column is created, modify the User model to allow editing and validation of username. We will also make sure that Devise is validating data in the forms. You can see the changes here, user.rb

Now that our model and database are set to handle usernames, we have to make sure our views can handle them. To do this we need to extend the default Devise views. Run the following commands and then edit the files as seen here.
$ rails generate devise:views
For more information about this as well as how to let user recover their passwords using username or email please see the Devise wiki.
Now that we can edit, login and register with usernames, lets display them on our page. Edit post show and post index templates as seen here.

Check in next week were we will add comments to the posts.