# Developing a plugin using DI and TDD 01

Implementing a DI52 powered PHP 5.2 compatible plugin.

## Why?

To demonstrate how and why a dependency injection container can be used to develop a PHP 5.2 compatible WordPress plugin that sticks to WordPress minimum requirements and tries to follow some modern programming techniques.

## What?

The plugin will be simple in its functions:

• add a shortcode that allows the site admin to add an “I’d like this” button that shows the number of people that would like something
• the admin should be able to add a short description to each button in a post to have contextual feedback
• the admin should be shown a counter for each “I’d like this” in the post edit screen

It should allow someone publishing a post to have user feedback on one or more ideas expressed in the post; as an example someone editing a post should be able to write this:

And have the following result on the page

Yes: useless.

## What’s to wire?

Before any code is put in place I’ll define what’s to attach where in the WordPress flow:

• a shortcode handler in charge of rendering the shortcode markup on the page, one for each version of the shortcode
• a metabox that will show up on the post edit screen and display either a list of “I’d like this” button clicks or an empty placeholder message
• an ajax call handler to handle the user click as we do not want the page to reload

I will probably find more dependencies along the way but that’s enough by now.

## Compose me something

I’m using Composer to manage the project dependencies and will init it first thing

composer init

After some routine questions I will have the following composer.json file produced for me:

{
"name": "lucatume/idlikethis",
"description": "Add an \"I'd like this\" button anywhere.",
"type": "wordpress-plugin",
"authors": [
{
"name": "Luca Tumedei",
"email": "luca@theaveragedev.com"
}
],
"minimum-stability": "stable",
"require": {}
}

DI52 will be required as a dependency

composer require lucatume/di52

it will, in turn, require the composer-php52 package that will allow me to generate PHP 5.2 compatible autoload files for the project.
This will require a small addition to the composer.json file to have the PHP 5.2 version generated

{
"name": "lucatume/idlikethis",
"description": "Add an \"I'd like this\" button anywhere.",
"type": "wordpress-plugin",
"authors": [
{
"name": "Luca Tumedei",
"email": "luca@theaveragedev.com"
}
],
"minimum-stability": "stable",
"require": {
"lucatume/di52": "^1.2"
},
"scripts": {
"post-install-cmd": [
"xrstf\\Composer52\\Generator::onPostInstallCmd"
],
"post-update-cmd": [
"xrstf\\Composer52\\Generator::onPostInstallCmd"
],
"xrstf\\Composer52\\Generator::onPostInstallCmd"
]
}
}

and a composer update to have the vendor/autoload_52.php put in place.

## Plugin file

The plugin file will grow over time but for the time being it’s doing nothing more but define the plugin and call the autoload file.

<?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
*/

include dirname(__FILE__) . '/vendor/autoload_52.php';

## Tests

I’m not going anywhere without putting some tests in place and it’s time to get hold of the testing suite

composer require --dev lucatume/wp-browser

after a long dependency resolution Composer will download the wp-browser test suite in the vendor folder; scaffolding the tests is matter of another command

wpcept boostrap

I jump to the codeception.yml file to configure the modules to work in my current set up and specify my database and domain details.
I will run WordPress unit tests using the WPLoader module: that’s destructive on the database it works on so I will have a database set up just for it; another database will serve the site I can experiment on “by hand”.
In the end:

• wp is the database that’s powering the local wp.dev installation
• wp-tests is the database that will be used by WPLoader (and shredded by it)

Here it’s the updated codeception.yml file set up to match my local set up:

actor: Tester
paths:
tests: tests
log: tests/_output
data: tests/_data
helpers: tests/_support
settings:
bootstrap: _bootstrap.php
colors: true
memory_limit: 1024M
modules:
config:
Db:
dsn: 'mysql:host=127.0.0.1;dbname=wp-tests'
user: root
dump: tests/_data/dump.sql
WPBrowser:
url: 'http://wp.dev'
WPDb:
dsn: 'mysql:host=127.0.0.1;dbname=wp-tests'
user: root
dump: tests/_data/dump.sql
populate: true
cleanup: true
url: 'http://wp.dev'
tablePrefix: wp_
wpRootFolder: /Users/Luca/Sites/wp
dbName: wp-tests
dbHost: 127.0.0.1
dbUser: root
wpDebug: true
dbCharset: utf8
dbCollate: ''
tablePrefix: wp_
domain: wp.dev
title: 'WP Tests'
phpBinary: php
language: ''
plugins: ["idlikethis/idlikethis.php"]
activatePlugins: ["idlikethis/idlikethis.php"]
WPWebDriver:
url: 'http://wp.dev'
browser: phantomjs
port: 4444
restart: true
wait: 2
adminUrl: /wp-admin
codecept run
In the modules > config > WPLoader > plugins and activatePlugins module I’m instructing WPLoader to include the main plugin file and activate it before the tests.