PHPackages                             mikemix/tactician-module - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Framework](/categories/framework)
4. /
5. mikemix/tactician-module

ActiveLibrary[Framework](/categories/framework)

mikemix/tactician-module
========================

Laminas/Mezzio Module to use the League of Extraordinary Packages' Tactician library - flexible command bus implementation

3.3.0(2y ago)17159.3k↓31.1%10MITPHPPHP ^7.1 || ^8.0CI failing

Since May 20Pushed 2y ago3 watchersCompare

[ Source](https://github.com/mikemix/TacticianModule)[ Packagist](https://packagist.org/packages/mikemix/tactician-module)[ RSS](/packages/mikemix-tactician-module/feed)WikiDiscussions master Synced 2d ago

READMEChangelog (10)Dependencies (7)Versions (31)Used By (0)

Tactician Laminas/Mezzio Module
===============================

[](#tactician-laminasmezzio-module)

Wrapper module for easy use of the [Tactician](http://tactician.thephpleague.com/) Command Bus in your Laminas or Mezzio applications.

[![Build Status](https://camo.githubusercontent.com/730a494395bf3ce1117508c337168c37a27e4517cc3737c5aeedc2406a120b30/68747470733a2f2f7472617669732d63692e6f72672f6d696b656d69782f54616374696369616e4d6f64756c652e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/mikemix/TacticianModule) [![Scrutinizer Code Quality](https://camo.githubusercontent.com/50e36140228d4aac1e677923289380dd5f68eabc0b862430d8d6c98799297cb3/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f6d696b656d69782f54616374696369616e4d6f64756c652f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/mikemix/TacticianModule/?branch=master) [![Code Coverage](https://camo.githubusercontent.com/70210778584d49afb2040e138060b475b9b203f248e1042ee2fa36a45b27f036/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f6d696b656d69782f54616374696369616e4d6f64756c652f6261646765732f636f7665726167652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/mikemix/TacticianModule/?branch=master) [![Latest Stable Version](https://camo.githubusercontent.com/c3dd4ffc497a1462bc958a3522f7783f0fbd3e021fb95b1f8828afc3e2cc172a/68747470733a2f2f706f7365722e707567782e6f72672f6d696b656d69782f74616374696369616e2d6d6f64756c652f762f737461626c65)](https://packagist.org/packages/mikemix/tactician-module) [![Total Downloads](https://camo.githubusercontent.com/819294c1da53fee29e1dbb422462fe2b91921b8aba2f2887fc25a7d8cb95569f/68747470733a2f2f706f7365722e707567782e6f72672f6d696b656d69782f74616374696369616e2d6d6f64756c652f646f776e6c6f616473)](https://packagist.org/packages/mikemix/tactician-module) [![License](https://camo.githubusercontent.com/26529d3b4befa087cd65871199a350538c7d064742adb17e54afb5720fc67c5b/68747470733a2f2f706f7365722e707567782e6f72672f6d696b656d69782f74616374696369616e2d6d6f64756c652f6c6963656e7365)](https://packagist.org/packages/mikemix/tactician-module)

Installation
------------

[](#installation)

Best install with Composer:

```
composer require mikemix/tactician-module

```

Register as Laminas Framework module inside your `config/application.config.php` file using `TacticianModule` name.

You can also use this package as [Mezzio](https://docs.zendframework.com/zend-expressive/v3/features/modular-applications/) module by `TacticianModule\ConfigProvider`

Using
-----

[](#using)

The module presents a **Controller Plugin** called `tacticianCommandBus()` for easy use of dispatching commands. If no command object is passed to it, the CommandBus object will be returned. If you pass the command however, it will be passed over to the CommandBus and handled, and the output from the handler will be returned.

You can type hint this plugin in your controller, for example: `@method \League\Tactician\CommandBus|mixed tacticianCommandBus(object $command)`.

```
// Real life example.
// Namespaces, imports, class properties skipped for brevity

class LoginController extends AbstractActionController
{
    public function indexAction()
    {
        if ($this->request->isPost()) {
            $this->form->setData($this->request->getPost());

            if ($this->form->isValid()) {
                $command = new UserLoginCommand(
                    $this->form->getLogin(),
                    $this->form->getPassword()
                ));

                try {
                    $this->tacticianCommandBus($command);
                    return $this->redirect()->toRoute('home');
                } catch (\Some\Kind\Of\Login\Failure $exception) {
                    $this->flashMessenger()->addErrorMessage($exception->getMessage());
                    return $this->redirect()->refresh();
                }
            }
        }

        $view = new ViewModel();
        $view->setVariable('form', $this->form);
        $view->setTemplate('app/login/index');

        return $view;
    }
}

final class UserLoginCommand
{
    public function __construct($login, $password)
    {
        $this->login = $login;
        $this->password = $password;
    }
}

final class UserLoginHandler
{
    // constructor skipped for brevity

    public function handle(UserLoginCommand $command)
    {
        $this->authenticationService->login($command->username, $command->password);
    }
}
```

You can inject the `CommandBus` into yout service layer through a factory by simply requesting the `League\Tactician\CommandBus::class` from the **Container**.

Configuring
-----------

[](#configuring)

The module ships with a `LaminasLocator` and a `CommandHandlerMiddleware` and a `HandlerInflector` configured as default. If you wish to override the default locator or default command bus implementations, then simply use the `tactician` key in the merged config.

```
'tactician' => [
    'default-extractor'  => League\Tactician\Handler\CommandNameExtractor\ClassNameExtractor::class,
    'default-locator'    => TacticianModule\Locator\LaminasLocator::class,
    'default-inflector'  => League\Tactician\Handler\HandleInflector::class,
    'handler-map'        => [],
    'middleware'         => [
        CommandHandlerMiddleware::class => 0,
    ],
],
```

`default-extractor`, `default-locator` and `default-inflector` are service manager keys to registered services.

`LaminasLocator` expects handlers in the `handler-map` to be `commandName => serviceManagerKey` or `commandName => Handler_FQCN`, altough to prevent additional costly checks, use serviceManagerKey and make sure it is available as a Laminas Service.

To add custom middleware to the middleware stack, add it to the `middleware` array as `ServiceName` =&gt; `priority` in which the middleware are supposed to be executed (higher the number, earlier it will execute). For example

```
// ... your module config
'tactician' => [
    'middleware'         => [
        YourAnotherMiddleware::class => 100, // execute early
        YourCustomMiddleware::class  => 50,  // execute last
    ],
],
```

Basic usage
-----------

[](#basic-usage)

Basicly, all you probably will want to do, is to define the `handler-map` array in your module's configuration. For example:

```
// module.config.php file

    return [
        // other keys
        'tactician' => [
            'handler-map' => [
                App\Command\SomeCommand::class => App\Handler\SomeCommandHandler::class,
            ],
        ],
    ];
```

Plugins
-------

[](#plugins)

### LockingMiddleware

[](#lockingmiddleware)

The [LockingMiddleware](http://tactician.thephpleague.com/plugins/locking-middleware/) can now be used out of the box. Simply add the `League\Tactician\Plugins\LockingMiddleware` FQCN to the TacticianModule's middleware configuration with appropriate priority. You probably want to execute it before the `CommandHandlerMiddleware`:

```
// module.config.php file

    return [
        // other keys
        'tactician' => [
            'middleware' => [
                \League\Tactician\Plugins\LockingMiddleware::class => 500,
            ],
        ],
    ];
```

### TransactionMiddleware

[](#transactionmiddleware)

The [TransactionMiddleware](http://tactician.thephpleague.com/plugins/doctrine/) can now be used out of the box. Simply add the `League\Tactician\Doctrine\ORM\TransactionMiddleware` FQCN to the TacticianModule's middleware configuration with appropriate priority. You probably want to execute it before the `CommandHandlerMiddleware` and after the `LockingMiddleware`:

```
// module.config.php file

    return [
        // other keys
        'tactician' => [
            'middleware' => [
                \League\Tactician\Doctrine\ORM\TransactionMiddleware::class => 250,
            ],
        ],
    ];
```

Changing the Handler Locator
----------------------------

[](#changing-the-handler-locator)

### ClassnameLaminasLocator

[](#classnamelaminaslocator)

This locator simply appends the word `Handler` to the command's FQCN so you don't have to define any handler map. For example, if you request command `App\Commands\LoginCommand`, locator will try to get `App\Command\LoginCommandHandler` from the Service Manager.

Locator will work with FQCN's not registered in the Service Manager, altough to prevent additional costly checks, make sure the locator is registered as a invokable or factory.

To change the locator from LaminasLocator to ClassnameLaminasLocator simply set it in the config:

```
// ... your module config
'tactician' => [
    'default-locator' => TacticianModule\Locator\ClassnameLaminasLocator::class,
],
```

###  Health Score

44

—

FairBetter than 90% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity42

Moderate usage in the ecosystem

Community19

Small or concentrated contributor base

Maturity79

Established project with proven stability

 Bus Factor2

2 contributors hold 50%+ of commits

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~145 days

Recently: every ~380 days

Total

23

Last Release

851d ago

Major Versions

1.2.2 → 2.0.02016-09-08

2.1.2 → 3.0.02020-10-31

PHP version history (5 changes)1.0PHP &gt;=5.5

1.2.2PHP ^5.5 || ^7.0

2.0.1PHP ^5.6 || ^7.0

3.0.0PHP ^7.1

3.1.0PHP ^7.1 || ^8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/7f120faf0f68744fbc357d36e55bb78ec43fa3c2c81eb70f476893540ef1621f?d=identicon)[mikemix](/maintainers/mikemix)

---

Top Contributors

[![snapshotpl](https://avatars.githubusercontent.com/u/312655?v=4)](https://github.com/snapshotpl "snapshotpl (19 commits)")[![GeeH](https://avatars.githubusercontent.com/u/613376?v=4)](https://github.com/GeeH "GeeH (14 commits)")[![mikemix](https://avatars.githubusercontent.com/u/2399452?v=4)](https://github.com/mikemix "mikemix (7 commits)")[![tonivdv](https://avatars.githubusercontent.com/u/1267658?v=4)](https://github.com/tonivdv "tonivdv (1 commits)")[![rosstuck](https://avatars.githubusercontent.com/u/146766?v=4)](https://github.com/rosstuck "rosstuck (1 commits)")[![carnage](https://avatars.githubusercontent.com/u/846596?v=4)](https://github.com/carnage "carnage (1 commits)")[![scrutinizer-auto-fixer](https://avatars.githubusercontent.com/u/6253494?v=4)](https://github.com/scrutinizer-auto-fixer "scrutinizer-auto-fixer (1 commits)")

---

Tags

command bustacticianthephpleaguelaminas framework

###  Code Quality

TestsPHPUnit

Code StylePHP\_CodeSniffer

### Embed Badge

![Health badge](/badges/mikemix-tactician-module/health.svg)

```
[![Health](https://phpackages.com/badges/mikemix-tactician-module/health.svg)](https://phpackages.com/packages/mikemix-tactician-module)
```

###  Alternatives

[laravel/framework

The Laravel Framework.

34.8k543.8M20.1k](/packages/laravel-framework)[symfony/symfony

The Symfony PHP framework

31.4k87.2M2.2k](/packages/symfony-symfony)[tempest/framework

The PHP framework that gets out of your way.

2.2k34.4k15](/packages/tempest-framework)[typo3/cms

TYPO3 CMS is a free open source Content Management Framework initially created by Kasper Skaarhoj and licensed under GNU/GPL.

1.2k1.9M122](/packages/typo3-cms)[drupal/core-recommended

Locked core dependencies; require this project INSTEAD OF drupal/core.

6942.5M421](/packages/drupal-core-recommended)[concrete5/core

Concrete core subtree split

20166.1k52](/packages/concrete5-core)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
