2017 © Pedro Peláez
 

cakephp-plugin cakephp-tactician

CakePHP Tactician plugin

image

robotusers/cakephp-tactician

CakePHP Tactician plugin

  • Monday, April 9, 2018
  • by robertpustulka
  • Repository
  • 1 Watchers
  • 6 Stars
  • 603 Installations
  • PHP
  • 0 Dependents
  • 0 Suggesters
  • 0 Forks
  • 3 Open issues
  • 5 Versions
  • 10 % Grown

The README.md

CakePHP Tactician

Software License Build Status codecov, (*1)

CakePHP plugin for league/tactician., (*2)

NOTE: The plugin is under development., (*3)

Installation

composer require robotusers/cakephp-tactician
bin/cake plugin load Robotusers/Tactician

Using the plugin

CakePHP integration

This plugin provides Controller and Model integration through Commander library., (*4)

Commander is a command bus abstraction library for PHP which enables you to decouple your code from a concrete command bus implementation., (*5)

Using the Commander (PHP 7.1+)

Install robotusers/commander:, (*6)

composer require robotusers/commander

Set up your controllers:, (*7)

use Cake\Controller\Controller;
use Robotusers\Commander\CommandBusAwareInterface;
use Robotusers\Tactician\Bus\CommandBusAwareTrait;

class OrdersController extends Controller implements CommandBusAwareInterface
{
   use CommandBusAwareTrait;

   public function makeOrder()
   {
        // ...
        $command = new MakeOrderCommand($data);
        $this->handleCommand($command);
        // ...

        // or using quick convention enabled command handling:
        $this->handleCommand('MakeOrder', $data);
        // ...
   }

}

For more information, read the docs., (*8)

Next you should configure the command bus which will be injected into your controllers and models that implement the CommandBusAwareInterface., (*9)

Console (CakePHP 3.6+)

For console integration Tactician plugin provides a CommandFactory that injects a command bus into compatible console shells and commands., (*10)

Set up your CommandRunner as below:, (*11)


use App\Application; use Cake\Console\CommandRunner; use Cake\Console\CommandFactory; use Tactician\Console\CommandFactory as TacticianCommandFactory; $application = new Application(dirname(__DIR__) . '/config'); $cakeFactory = new CommandFactory(); // or any other custom factory (ie. CakePHP DI plugin DIC-compatible factory) $factory = new TacticianCommandFactory($cakeFactory, $application); $runner = new CommandRunner($application, 'cake', $factory); exit($runner->run($argv));

Application hook (CakePHP 3.3+)

If your application supports middleware you can configure the command bus using an application hook., (*12)

use Cake\Http\BaseApplication;
use League\Tactician\CommandBus;
use Robotusers\Tactician\Core\BusApplicationInterface;
use Robotusers\Tactician\Core\BusMiddleware;

class Application extends BaseApplication implements BusApplicationInterface
{
    public function commandBus()
    {
        $bus = new CommandBus([
            // your middleware
        ]);

        return $bus;
    }

    public function middleware($middleware)
    {
        // ...
        $middleware->add(new BusMiddleware($this));
        // ...

        return $middleware;
    }
}

You can use helper factory methods for building CommandBus or CakePHP convention enabled CommandHandlerMiddleware:, (*13)

use Robotusers\Tactician\Bus\Factory;

public function commandBus()
{
    return Factory::createCommandBus([
        // your middleware
        Factory::createCommandHandlerMiddleware();
    ]);
}

The command bus configured here will be injected into controllers and models in Model.initialize and Controller.initialize event listener., (*14)

Bootstrap

If you're still on pre 3.3 stack you can set up the listener in your bootstrap.php file., (*15)

You can use build in quick start class:, (*16)

// bootstrap.php

use Robotusers\Tactician\Event\QuickStart;

QuickStart::setUp($commandBus);

QuickStart can load simple CakePHP convention enabled bus if it hasn't been provided:, (*17)

// bootstrap.php

use Robotusers\Tactician\Event\QuickStart;

QuickStart::setUp();

Conventions locator

CakePHP Conventions locator will look for command handlers based on a convention, that commands should reside under App\Model\Command\ namespace and be suffixed with Command string and handlers should reside under App\Model\Handler\ namespace and be suffixed with Handler string., (*18)


//CakePHP convention locator $locator = new ConventionsLocator(); $extractor = new ClassNameExtractor(); $inflector = new HandleClassNameInflector(); $commandBus = new CommandBus( [ new CommandHandlerMiddleware($extractor, $locator, $inflector) ] );

In this example App\Model\Command\MakeOrderCommand command will map to App\Model\Handler\MakeOrderHandler handler., (*19)

You can change default namespace and suffix using configuration options:, (*20)

$locator = new ConventionsLocator([
    'commandNamespace' => 'Command',
    'commandSuffix' => '',
    'handlerNamespace' => 'Handler',
    'handlerSuffix' => '',
]);

In this example App\Command\MakeOrder command will map to App\Handler\MakeOrder handler. Note a different namespace and no suffix., (*21)

Transaction middleware

Transaction middleware is a wrapper for CakePHP ConnectionInterface::transactional(). You need to provide a list of supported commands., (*22)

A list supports FQCN or convention supported name (eq Plugin.Name)., (*23)

This will wrap only Foo and Bar commands in a transaction:, (*24)


//default connection $connection = ConnectionManager::get('default'); $commandBus = new CommandBus( [ //CakePHP transaction middleware with a connection and a list of commands. new TransactionMiddleware($connection, [ FooCommand::class, 'My/Plugin.Bar', ]), $commandHandlerMiddleware ] );

You can include all commands by setting the $commands argument to true and exclude only some commands., (*25)

This will wrap all commands in a transaction with an exception for Foo and Bar commands:, (*26)

$middleware = new TransactionMiddleware($connection, true, [
    FooCommand::class,
    'My/Plugin.Bar',
]),

The Versions