Developing a plugin using DI and TDD 13

Setting up the stage for the meta boxes.

Tagging

I’ve tried to blatantly copy the excellent Laravel DI container and its service providers while implementing the latest iteration of DI52 and did not leave the powerful tagging feature out.
The task at hand in the ongoing development of the [“I’d like this” plugin](https://github.com/lucatume/idlikethis ‘“I’d like this” plugin’) is the registration and rendering of a meta box displaying the results of the vote cast by users using the buttons on the front-end and another one to allow the post author some measure of control on the plugin behaviour.
Three I’d like this buttons To handle the meta boxes registration I’ve added the idlikethis_ServiceProviders_MetaBoxes service provider to the project in the bootstrap.php file

$container = new tad_DI52_Container();

$container->register('idlikethis_ServiceProviders_Shortcodes');
$container->register('idlikethis_ServiceProviders_Endpoints');
$container->register('idlikethis_ServiceProviders_Scripts');
$container->register('idlikethis_ServiceProviders_CommentsTable');
$container->register('idlikethis_ServiceProviders_MetaBoxes');

return $container;

To understand the tagging concept the service provider code is the best place to start

class idlikethis_ServiceProviders_MetaBoxes extends tad_DI52_ServiceProvider
{

    /**
     * Binds and sets up implementations.
     */
    public function register()
    {
        add_action('add_meta_boxes', array($this, 'add_meta_boxes'));
    }

Throughout the plugin I’m leaving any set up code in the service providers: hooking into actions and filters falls into this category.

    public function add_meta_boxes()
    {
        $this->container->bind('idlikethis_MetaBoxes_VotesDisplayMetaBoxInterface', 'idlikethis_MetaBoxes_VotesDisplayMetaBox');
        $this->container->bind('idlikethis_MetaBoxes_PostControlMetaBoxInterface', 'idlikethis_MetaBoxes_PostControlMetaBox');

I’m binding the meta boxes implementations to allow the container to know how to resolve interface requests to concrete implementations.

        $this->container->tag(array(
            'idlikethis_MetaBoxes_VotesDisplayMetaBoxInterface',
            'idlikethis_MetaBoxes_PostControlMetaBoxInterface',
        ), 'meta-boxes');

Here is the tagging: I’m telling the container that I will reference an array of concrete implementations with the collective name of meta-boxes.
In the code below I’m leveraging the implicit implementation resolution of the container to iterate over all the metaboxes and call the add_meta_box function for each.

        /** @var idlikethis_MetaBoxes_MetaBoxInterface $meta_box */
        foreach($this->container->tagged('meta-boxes') as $meta_box){
            add_meta_box($meta_box->id(),$meta_box->title(),array($meta_box,'render'),$meta_box->screen(),$meta_box->context(),$meta_box->priority());
        }
    }

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

Meta boxes code

The meta boxes will be subject of the next post and define some mere scaffold code, the first one as an example

class idlikethis_MetaBoxes_VotesDisplayMetaBox implements idlikethis_MetaBoxes_VotesDisplayMetaBoxInterface
{

    /**
     * Returns the meta box id.
     *
     * @return string
     */
    public function id()
    {
        return 'idlikethis-vote-display';
    }

    /**
     * Returns the meta box title.
     *
     * @return string
     */
    public function title()
    {
        return __("I'd like to see the votes", 'idlikethis');
    }

    /**
     * Returns the screen(s) the meta box should display on.
     *
     * @return string|array|WP_Screen
     */
    public function screen()
    {
        return array('post', 'page');
    }

    /**
     * Returns the context the meta box should display into.
     *
     * @return string
     */
    public function context()
    {
        return 'side';
    }

    /**
     * Returns the priority for the meta box.
     *
     * @return string
     */
    public function priority()
    {
        return 'high';
    }

    /**
     * Echoes the meta box markup to the page.
     *
     * @param string|WP_Post|array $object
     * @param array|mixed $box The metabox registration description.
     * @return void
     */
    public function render($object, $box)
    {
        echo "<h3>Votes</h3>";
    }
}

The code current to this post is on GitHub.

Next

Implementation of the votes meta box.