Skip to content

PHP Cody Tutorial Exercise I

Alexander Miertsch edited this page Feb 12, 2021 · 11 revisions

In the tutorial preparation we've set up folder structure, exercises, InspectIO tutorial board and Cody. Your folder structure should look like this:

cody-tutorial
|__ cody-bot
|__ exercises

The Cody Server should be running and listen on http://localhost:3311:

cd cody-tutorial/cody-bot
docker-compose ps

         Name                        Command               State           Ports         
-----------------------------------------------------------------------------------------
iio_iio-ic-react-http_1   docker-php-entrypoint vend ...   Up      0.0.0.0:3311->8080/tcp

Note: Use dev.sh to start Cody. After that you can use docker-compose commands to stop, start again, inspect logs, etc. A file watcher restarts the server on changes. If something does not work as expected try to restart the server manually and take a look at the logs: docker-compose stop && docker-compose up -d && docker-compose logs -f

Test-Driven Exercises

Navigate to the tutorial project in a second console cd cody-tutorial/exercises and run the first exercise using docker-compose run --rm composer exercise1

Of course the test case is failing. it is looking for a Command called AddBuilding and that's the first class we want to generate from an InspectIO event map. You might have noticed the commented hooks in codyconfig.php. What we need is a CommandHook, so let's create one!

Create Command Hook

# current dir: cody-tutorial/cody-bot
# Create a Hook folder
mkdir src/Hook
# Create CommandHook.php
touch src/Hook/CommandHook.php

Open src/Hook/CommandHook.php in your favorite editor and copy this content into it:

<?php
declare(strict_types=1);

namespace EventEngine\InspectioCody\Hook;

use EventEngine\InspectioCody\Board\BaseHook;
use EventEngine\InspectioCody\Http\Message\CodyResponse;
use EventEngine\InspectioCody\Http\Message\Response;
use EventEngine\InspectioGraphCody\Node;
use stdClass;

final class CommandHook extends BaseHook //BaseHook provides some helper methods like writeFile()
{
    /**
     * @param  Node     $command Information about Command sticky received from InspectIO event map
     * @param  stdClass $context Context object populated in codyconfig.php
     * @return CodyResponse      Response sent back to InspectIO, shown in Cody Console
     */
    public function __invoke(Node $command, stdClass $context): CodyResponse
    {
        $commandName = $command->name();
        $commandFile = $commandName . '.php';
        $commandPath = $context->path . '/Command/' . $commandFile;

        $code = <<<CODE
        <?php
        declare(strict_types=1);
        
        namespace Cody\Tutorial\Command;
        
        class $commandName
        {
            
        }
        CODE;

        $this->writeFile($code, $commandPath);

        return Response::fromCody(
            "Command \"{$commandName}\" generated", 
            ["Command written to {$commandPath}"]
        );
    }
}

Register Hook in codyconfig

To activate the hook, we need to register it in codyconfig.php:

<?php

/**
 * @see       https://github.com/event-engine/php-inspectio-cody for the canonical source repository
 * @copyright https://github.com/event-engine/php-inspectio-cody/blob/master/COPYRIGHT.md
 * @license   https://github.com/event-engine/php-inspectio-cody/blob/master/LICENSE.md MIT License
 */

declare(strict_types=1);

use EventEngine\InspectioCody\CodyConfig;
// IMPORT COMMAND HOOK
use EventEngine\InspectioCody\Hook\CommandHook;

$context = new stdClass(); // replace it with your own context class

$context->path = '/exercises/src';

return new CodyConfig(
    $context,
    [
//        CodyConfig::HOOK_ON_AGGREGATE => new AggregateHook(),
        // UNCOMMENT COMMAND HOOK    
        CodyConfig::HOOK_ON_COMMAND => new CommandHook(),
//        CodyConfig::HOOK_ON_EVENT => new EventHook(),
//        CodyConfig::HOOK_ON_POLICY => new PolicyHook(),
//        CodyConfig::HOOK_ON_DOCUMENT => new DocumentHook(),
    ]
);

Modeling On Event Map

Cody is now able to turn information from command stickies (on an InspectIO event map) into PHP classes. Switch to the Cody Tutorial board in InspectIO and add a command sticky (blue one) with label AddBuilding. Right click on the newly created sticky and choose Trigger Cody from context menu. In the Cody Console you can check the response. Cody should tell you: Command "AddBuilding" generated.

Awesome, it works! Rerun docker-compose run --rm composer exercise1 in cody-tutorial/exercises. It should turn green now. The test verifies that a Cody\Tutorial\Command\AddBuilding has been generated by Cody and put into cody-tutorial/exercises/src/Command/AddBuilding.php.

Recap Exercise I

In exercise I we implemented our first Cody Hook and registered it in codyconfig.php. The hook is called with information received from an InspectIO event map and with a user defined context object, which can be used to pass configuration options (like a source path) to each hook. We can trigger the hook from InspectIO by selecting an appropriate sticky on an event map and Trigger Cody from context menu.

Next - Exercise II