Developing a plugin using DI and TDD 02

Injecting some dependencies and feeling the overkill.

Starting from the end

The first code I will tackle is the one that will add the shortcodes to the ones supported by WordPress.
I will start from the easier shortcode of the two I’m going to add (see the earlier post): the one that’s displaying a button sporting the “I’d like this” call to action.
I will use a class to manage the shortcode rendering so my call will be like this

add_shortcode('idlikethis', array($shortcode, 'render'));

What’s the $shortcode variable? An instance of the idlikethis_Shortcodes_Simple class; this class will define a render method that will return the shortcode markup.
Where does that class will be instantiated?
Should that class concern itself with the markup?

Planning for the future

Any development technique will seem over rated for a small project but will come in very handy as the project grows; I’m hoping this small plugin will make me famous and want to have a solid and scalable structure in place.
First of all I will delegate anything that’s dependency injection and set up code to a separate file in the plugin root folder, the fill will be called right after the autoload file and be named bootstrap.php

<?php
/**
 * Plugin Name: I'd like this
 * Plugin URI: http://theAverageDev.com
 * Description: Add an "I'd like this" button anywhere.
 * Version: 1.0
 * Author: theAverageDev
 * Author URI: http://theAverageDev.com
 * License: GPL 2.0
 */

$root_dir = dirname(__FILE__);
include $root_dir . '/vendor/autoload_52.php';
include $root_dir . '/bootstrap.php'; 

And before I write any class will modify Composer configuration file to handle autoloading of my plugin classes

{
  "name": "lucatume/idlikethis",
  "description": "Add an \"I'd like this\" button anywhere.",
  "type": "wordpress-plugin",
  "license": "GPL 2.0",
  "authors": [
    {
      "name": "Luca Tumedei",
      "email": "[email protected]"
    }
  ],
  "minimum-stability": "stable",
  "require": {
    "lucatume/di52": "^1.2"
  },
  "scripts": {
    "post-install-cmd": [
      "xrstf\\Composer52\\Generator::onPostInstallCmd"
    ],
    "post-update-cmd": [
      "xrstf\\Composer52\\Generator::onPostInstallCmd"
    ],
    "post-autoload-dump": [
      "xrstf\\Composer52\\Generator::onPostInstallCmd"
    ]
  },
  "require-dev": {
    "lucatume/wp-browser": "^1.9"
  },
  "autoload": {
    "psr-0": {
      "idlikethis_": "src/"
    }
  }
}

I will scaffold the code for the simple shortcode handler class in the /src/idlikethis/Shortcodes/Simple.php file, it’s just a definition now

<?php

class idlikethis_Shortcodes_Simple
{
    public function render()
    {
    }
}

and move in the bootstrap.php file.

Thinking responsibility

What’s the responsibility of this first class?

It returns the markup for the simple version of the shortcode.

So no hooking into WordPress to add the shortcode and no defining the actual shortcode markup.
What the class is not responsible for but needs to use will be a dependency; I will use the PHP 5.2 compatible Smarty templating engine to render the markup and will delegate the hooking into WordPress to a set up class: a service provider.
Requiring the template engine would be a matter of moments with Composer

composer require smarty/smarty

The first service provider

Sticking to the possibilities offered by the DI52 library I’m registering a service provider in the DI container in the bootstrap.php file

<?php
$container = new tad_DI52_Container();

$container->register('idlikethis_ServiceProviders_Shortcodes');

and in turn the idlikethis_ServiceProviders_Shortcodes class is setting up and hooking the shortcode; it provides a service, that service being the shortcode component; the service provider takes care of setting up and binding the dependcies for a sub-set of components.

<?php

class idlikethis_ServiceProviders_Shortcodes extends tad_DI52_ServiceProvider
{

    /**
     * Binds and sets up implementations.
     */
    public function register()
    {
        $smarty = new Smarty();
        $this->container->singleton('Smarty', $smarty);
        $this->container->bind('idlikethis_Interfaces_ShortcodeInterface', 'idlikethis_Shortcodes_Simple');

        $simple_shortcode = $this->container->resolve('idlikethis_Interfaces_ShortcodeInterface');

        add_shortcode($simple_shortcode->get_tag(), array($simple_shortcode, 'render'));
    }

    /**
     * Binds and sets up implementations at boot time.
     */
    public function boot()
    {
        // TODO: Implement boot() method.
    }
}

I’m telling the container that anytime an instance of a Smarty class is requested as a dependency in a class then the container should return a shared (singleton) instance of the Smarty class.
Template engines usually require some set up and doing it every time would be a chore.
Finally the class that’s handling the shortcode rendering is implementing the common shortcode interface

<?php

class idlikethis_Shortcodes_Simple implements idlikethis_Interfaces_ShortcodeInterface
{
    /**
     * @var Smarty
     */
    private $smarty;

    /**
     * @param Smarty $smarty
     */
    public function __construct(Smarty $smarty)
    {

        $this->smarty = $smarty;
    }

    /**
     * Returns the shortcode tag.
     *
     * @return string
     */
    public function get_tag()
    {
        return 'idlikethis';
    }

    /**
     * Returns the shortcode rendered markup code.
     *
     * @return string
     */
    public function render()
    {
    }
}

And it’s doing nothing yet.
And this is where it seems some real overkill.

Next

I will write the first test for the class and see dependency injection in action.

I appreciate your input