PHPackages                             mmalessa/saga - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. mmalessa/saga

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

mmalessa/saga
=============

Saga pattern implementation

03PHPCI failing

Since Oct 21Pushed 6y ago1 watchersCompare

[ Source](https://github.com/mmalessa/saga)[ Packagist](https://packagist.org/packages/mmalessa/saga)[ RSS](/packages/mmalessa-saga/feed)WikiDiscussions master Synced 4d ago

READMEChangelogDependenciesVersions (1)Used By (0)

Saga
====

[](#saga)

Saga pattern simple implementation in Symfony 4.3+
Development vertion. Use it at your own risk.

Install
=======

[](#install)

```
composer req mmalessa/saga
```

Symfony services.yaml - add something like this:

```
services:
    app.saga.state_repository:
        class: 'Mmalessa\Saga\InMemoryStateRepository'

    App\Saga\MySaga:
        arguments:
            $stateRepository: '@app.saga.state_repository'
            $type: 'mysaga'
        tags: ['kernel.event_subscriber']
```

Usage
=====

[](#usage)

```
use Symfony\Component\EventDispatcher\EventDispatcher;

class X {
    [...]
    method() {
        [...]
        $this->eventDispatcher->dispatch(new SomethingHappened('a7933354-d489-4522-bd59-111a985cbf7c', new \DateTime(), 'My description'));
        $this->eventDispatcher->dispatch(new SomethingElseHappened('a7933354-d489-4522-bd59-111a985cbf7c', new \DateTime(), 'My second description'));
        [...]
    }
}
```

```
use App\Command\DoSomething;
use App\Event\SomethingElseHappened;
use App\Event\SomethingHappened;
use Broadway\CommandHandling\CommandBus;
use Mmalessa\Saga\Saga;
use Mmalessa\Saga\State;
use Mmalessa\Saga\StateRepository;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class MySaga extends Saga implements EventSubscriberInterface
{
    const EVENTS = [
        SomethingHappened::class => ['somethingHappened', 1],
        SomethingElseHappened::class => ['somethingElseHappened', 1]
    ];

    private $commandBus;

    public function __construct(StateRepository $stateRepository, string $type, CommandBus $commandBus)
    {
        $this->commandBus = $commandBus;
        parent::__construct($stateRepository, $type);
    }

    public function somethingHappened(SomethingHappened $event, State $state): State
    {
        $state->set('id', $event->getId());
        $state->set('something', 'OK');
        $this->tryToDoSomething($state);
        return $state;
    }
    public function somethingElseHappened(SomethingElseHappened $event, State $state): State
    {
        $state->set('id', $event->getId());
        $state->set('somethingElse', 'OK');
        $this->tryToDoSomething($state);
        return $state;
    }

    public function tryToDoSomething(State &$state)
    {
        print_r($state); echo PHP_EOL;
        $condition1 = $state->get('something') === 'OK';
        $condition2 = $state->get('somethingElse') === 'OK';
        if ($condition1 && $condition2) {
            $state->setDone();
            $this->commandBus->dispatch(new DoSomething((string)$state->get('id')));
        }
    }
}
```

```
use Mmalessa\Saga\Identifiable;

class SomethingHappened implements Identifiable
{
    private $id;
    private $dateTime;
    private $description;

    public function __construct(string $Id, \DateTime $dateTime, string $description)
    {
        $this->id = $Id;
        $this->dateTime = $dateTime;
        $this->description = $description;
    }

    public function getId(): string
    {
        return $this->id;
    }

    public function getDateTime(): \DateTime
    {
        return $this->dateTime;
    }

    public function getDescription(): string
    {
        return $this->description;
    }
}
```

###  Health Score

17

—

LowBetter than 6% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity3

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity35

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

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.

### Community

Maintainers

![](https://www.gravatar.com/avatar/002ff67dd90c9245daea55d065039f10790fd1c46d1b016ad120b761da294b8f?d=identicon)[mmalessa](/maintainers/mmalessa)

---

Top Contributors

[![mmalessa](https://avatars.githubusercontent.com/u/3789506?v=4)](https://github.com/mmalessa "mmalessa (3 commits)")

### Embed Badge

![Health badge](/badges/mmalessa-saga/health.svg)

```
[![Health](https://phpackages.com/badges/mmalessa-saga/health.svg)](https://phpackages.com/packages/mmalessa-saga)
```

###  Alternatives

[felixnagel/t3extblog

A record based blog extension for TYPO3 CMS. Easy to use and packed with features (incl. comments, subscriptions for comments and posts, Wordpress like subscription manager, reasonable email sending in FE and BE, GDPR ready, BE modules, Dashboard widgets, RSS, Sitemap, ...). Flexible and powerful!

3421.6k](/packages/felixnagel-t3extblog)

PHPackages © 2026

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