Creating Custom ZFTool Diagnostic Classes

writing a custom zftool diagnostic class

Introduction

In last week’s tutorial, we covered using the Diagnostics component of ZFTool and how it makes it really simple to add diagnostic support to Zend Framework 2 Modules.

Specifically, we stepped through using the in-built classes to check that:

  • required PHP extensions were loaded
  • required services, such as Apache and PostgreSQL were running
  • and that PHP was over a specific revision, 5.3.0

In this week’s tutorial, we’re going to see how to step beyond the in-built classes and write our own custom checks. Specifically, we’re going to write a check which runs php lint on the module’s config file, module.config.php.

The reason for doing this is because this file is so important in the configuration of a ZF2 module, that we should have a helpful sanity check for it.

Module Dependencies

Before we get in to the code, make sure you have the dependencies in place. In the require section of composer.json, ensure you have the following two lines present:

"zendframework/zftool": "dev-master",
"zendframework/zenddiagnostics": "1.0.*@dev"

If not, add them and run composer update. Ok, I’m assuming, for the sakes of simplicity, that you’re working with the ZF2 Skeleton Application, which has the Application module, by default. So in module/Application, create a new file ModuleConfigFileLints.php under module/Application/src/Application/Diagnostics/Check. If this directory path doesn’t exist, make sure you create it.

In there, first add the following code:

namespace BabyMonitor\Diagnostics\Check;

use ZendDiagnostics\Check\CheckInterface;
use ZendDiagnostics\Result\Success;
use ZendDiagnostics\Result\Failure;

This includes the three required classes Check\CheckInterface, Result\Success and Result\Failure from the ZendDiagnostics package. These ensure that we create a diagnostics check compatible class and that we can return the expected Success and Failure types as and when needed.

class ModuleConfigFileLints implements CheckInterface
{
    protected $configFile;

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

Then, in the class constructor we accept one argument, `$configFile`, which is the absolute path to the module’s configuration file. Alternatively, we could have automatically have determined where the file was instead.

    public function check()
    {
        exec('php -l ' . $this->configFile, $output, $return);

        if ($return == 1) {
            return new Failure(sprintf(
                'Could not parse module configuration file: %s. Reason: %s',
                $this->configFile,
                $output[0]
            ));
        }

        return new Success();
    }

Next we implement the first of the two required functions, defined in CheckInterface, check; this is called when the check is run, and performs the core of the diagnostic process. What I’ve done is to call exec which runs php in the shell and lints the file passed in. I’ve then stored the process’ output and return value. This helps us determine whether the check succeeded or failed.

If the return value was 1, we know that something went wrong. In that case we then return a new Failure object, specifying what went wrong, based on the information available in the first element of $output.

If $return was anything other than 1, we know that the process succeeded and return a new Success object. Not much to it really.

    public function getLabel()
    {
        return "Check if the module's configuration file parses a lint test";
    }
}

Finally, we implemented the second of the two required functions, getLabel. This function provides the informational label which you see when the diagnostics are run. When doing so, make sure what you output is indicative of the purpose of the diagnostic.

Enabling The Module’s Diagnostic Check

    public function getDiagnostics()
    {
        return array(
            'Lint Module Configuration File' => function() {
                $diagnostic = new ModuleConfigFileLints(
                    __DIR__ . '/../../config/application.config.php'
                );
                return $diagnostic->check();
            },
        );
    }

Now there’s just one thing left to do, activate the module’s diagnostics. Similar to how we did this last week, add the getDiagnostics function in Module.php, adding in the code above.

Implementing the Diagnostic Check

Right, with the dependencies satisfied in composer.json and the code in place, let’s run it and see what it looks like. From the project root directory, run vendor/bin/zf.php diag --debug Application. All being well, you’ll see output as in the screenshot below:

writing a custom zftool diagnostic class

Wrapping Up

So there you have it. Creating custom Check classes for ZFTool is quite a straight-forward process. Using the in-built classes of Success and Failure and implementing the two required functions, check and getLabel, we can use all that PHP has to offer to create the required diagnostic functions for our modules.

What do you think? What custom classes will you use to check your modules? Tell me in the comments.

ZFTool