---
title: "DI a akcie — Workflows for Laravel | Roundly"
description: "Bez fasády: injektujte WorkflowsManager alebo zavolajte jednoúčelovú akciu — všetky akcie pre aplikáciu so signatúrou execute() a cestou cez fasádu."
url: https://roundly-consulting.com/sk/open-source/navody/workflows-for-laravel/bez-fasady
language: sk
---

[Všetky balíky](https://roundly-consulting.com/sk/open-source.md)

[Workflows for Laravel](https://roundly-consulting.com/sk/open-source/navody/workflows-for-laravel.md)

# DI a akcie

Fasáda je odporúčaná voľba, nie jediná cesta. Každá operácia je akcia, manažér sprístupňuje každú z nich a fasáda je nadstavba nad manažérom — všetky tri spôsoby spúšťajú rovnaký kód. Manažér je RoundlyConsulting\\Workflows\\WorkflowsManager, koreň fasády, registrovaný ako singleton v kontajneri a injektovateľný podľa názvu triedy:

```php
use RoundlyConsulting\Workflows\Actions\Instances\StartInstanceAction;
use RoundlyConsulting\Workflows\DataTransferObjects\StartData;
use RoundlyConsulting\Workflows\Facades\Workflows;
use RoundlyConsulting\Workflows\WorkflowsManager;

// Facade
$result = Workflows::start('purchase-approval', $request, $team)->input(['reason' => 'laptops'])->by($user)->dispatch();

// Dependency injection — the same API
public function __construct(private WorkflowsManager $workflows) {}
$result = $this->workflows->start('purchase-approval', $request, $team)->input(['reason' => 'laptops'])->by($user)->dispatch();

// The raw action (not recorded by the fake)
$result = app(StartInstanceAction::class)->execute(new StartData('purchase-approval', $request, $team, ['reason' => 'laptops'], $user));
```

Trait HasWorkflows je štvrtý vstup k tomu istému manažérovi — $request->workflows()->start('purchase-approval')->dispatch() sa naň deleguje, takže aj tieto volania fake vidí.

## Injektovanie manažéra

```php
use RoundlyConsulting\Workflows\Exceptions\WorkflowsException;
use RoundlyConsulting\Workflows\WorkflowsManager;

final class RetryWorkflowController
{
    public function __invoke(WorkflowsManager $workflows, string $ulid)
    {
        $instance = $workflows->instances()->find($ulid) ?? abort(404);

        try {
            $workflows->instances()->retry($instance);
        } catch (WorkflowsException $e) {
            return response()->json(['code' => $e->errorCode(), 'message' => $e->getMessage()], $e->status());
        }

        return response()->noContent();
    }
}
```

Workflows::fake() vymení manažéra za Testing\\WorkflowsFake — jeho podtriedu — za fasádou aj v kontajneri, takže fake pokryje aj kód, ktorý injektuje WorkflowsManager.

## Volanie akcie

Každá operácia je final readonly akcia s jednou metódou execute(), získaná z kontajnera — ak ju chcete prepísať, zaregistrujte vlastnú podtriedu. Priame volania akcií fake nezaznamenáva; kód aplikácie bežne volá fasádu alebo manažéra:

```php
use RoundlyConsulting\Workflows\Actions\Instances\RetryInstanceAction;
use RoundlyConsulting\Workflows\Actions\Versions\DiffVersionsAction;

app(RetryInstanceAction::class)->execute($instance);

$diff = app(DiffVersionsAction::class)->execute($v2, $v3);   // VersionDiff
```

## Metóda fasády → akcia

Menné priestory sú relatívne k RoundlyConsulting\\Workflows\\Actions:

| Akcia | execute(…) | Cesta cez fasádu |
| --- | --- | --- |
| `Definitions\CreateDefinitionAction` | `(CreateDefinitionData $data): WorkflowDefinition` | `definitions()->create() / createWith()` |
| `Definitions\RestoreDefinitionAction` | `(string $key, ?Model $owner): WorkflowDefinition` | `definitions()->restore()` |
| `Definitions\SyncDefinitionsAction` | `(string $path, ?Model $owner = null, bool $publish = false, bool $dryRun = false): SyncReport` | `definitions()->sync()` |
| `Definitions\SaveDraftAction` | `(WorkflowDefinition $definition, array $graph, ?string $expectedChecksum = null): WorkflowVersion` | `definition()->edit()` |
| `Definitions\DiscardDraftAction` | `(WorkflowDefinition $definition): WorkflowDefinition` | `definition()->discardDraft()` |
| `Definitions\PublishVersionAction` | `(WorkflowDefinition $definition, ?Model $by = null): WorkflowVersion` | `definition()->publish()` |
| `Definitions\RetireDefinitionAction` | `(WorkflowDefinition $definition): WorkflowDefinition` | `definition()->retire()` |
| `Definitions\ActivateDefinitionAction` | `(WorkflowDefinition $definition): WorkflowDefinition` | `definition()->activate()` |
| `Definitions\ResolveReviewFlagAction` | `(WorkflowDefinition $definition, string $node, string $path): WorkflowVersion` | `definition()->resolveFlag()` |
| `Definitions\RotateWebhookAction` | `(WorkflowDefinition $definition): WorkflowDefinition` | `definition()->rotateWebhook()` |
| `Versions\ValidateGraphAction` | `(array $graph, ?string $subjectType = null, ?Model $owner = null, array $reviewFlags = [], ?string $definitionKey = null): ValidationReport` | `versions()->validate(), definition()->validate(), GraphBuilder::validate()` |
| `Versions\DiffVersionsAction` | `(WorkflowVersion $from, WorkflowVersion $to): VersionDiff` | `versions()->diff()` |
| `Versions\OverlayAction` | `(WorkflowVersion $version): OverlayReport` | `versions()->overlay()` |
| `Versions\ExportTemplateAction` | `(WorkflowVersion $version): TemplatePayload` | `versions()->export(), definition()->export()` |
| `Versions\ImportTemplateAction` | `(TemplatePayload\|array $payload, ?Model $owner = null, ?string $key = null): ImportResult` | `versions()->import()` |
| `DryRun\DryRunAction` | `(DryRunData $data): DryRunResult` | `PendingDryRun::run() / explore()` |
| `Instances\StartInstanceAction` | `(StartData $data): StartResult` | `start()->dispatch(), startWith(), for()->start(), definition()->start()` |
| `Instances\EmitEventAction` | `(EmitData $data): EmitResult` | `emit(), emitWith(), for()->emit()` |
| `Instances\ReceiveWebhookAction` | `(string $hookId, array $payload, array $headers = []): StartResult` | `triggers()->webhook() and the inbound route` |
| `Instances\RetryInstanceAction` | `(WorkflowInstance $instance): WorkflowInstance` | `instances()->retry()` |
| `Instances\CancelInstanceAction` | `(WorkflowInstance $instance, ?string $reason = null): WorkflowInstance` | `instances()->cancel(), for()->cancelAll()` |
| `Instances\TouchSubjectAction` | `(Model $subject): int` | `for()->touch()` |
| `Wake\WakeAction` | `(?CarbonInterface $now = null, ?int $limit = null): WakeReport` | `wake()` |
| `Maintenance\PruneAction` | `(): PruneReport` | `prune()` |

Interné (stavebné bloky enginu, kód aplikácie ich nikdy nevolá): Engine\\RunStepAction, Engine\\ResumeStepAction, Engine\\RecordStepResultAction, Engine\\FireEscalationAction, Instances\\SignalAction, Wake\\EvaluateSchedulesAction, Wake\\ReclaimAction.

## Kontrakty, ktoré môžete implementovať

| Kontrakt | Metódy | Predvolené / kde sa zapája |
| --- | --- | --- |
| `AuthorizesSteps` | `authorize(StepAuthorization $authorization): Response` | GateStepAuthorizer; authorization.authorizer |
| `RestoresOwnerContext` | `run(?Model $owner, Closure $callback): mixed` | Prepojenie s teams, inak NullOwnerContext; owners.context |
| `ChecksOwnerMembership` | `isMember(?Model $owner, Model $user): bool` | Prepojenie s teams, inak povolí všetkých; owners.membership |
| `ResolvesRoles` | `members(?Model $owner, string $role): array` | Prepojenie s teams, inak žiadne; parties.roles |
| `TransitionAdapter` | `attempt(…): TransitionOutcome; hasTransition(…): ?bool; stateAttributes(string $subjectClass): array` | Prepojenie s lifecycle, inak žiadny; adapters.transition |
| `DeliversWebhooks` | `deliver(?Model $owner, string $endpoint, string $event, array $payload, string $idempotencyKey): int\|string` | Žiadny; adapters.webhooks zaregistruje krok webhook |
| `BusinessCalendar` | `timezone(), isBusinessDay($date), isOpenAt($instant), nextOpen($instant), nextClose($instant)` | weekdays, opening\_hours:\*; Workflows::calendars()->register() |
| `CountsBusinessTime` | `addBusinessDays(CarbonImmutable $from, int $days), addBusinessTime(CarbonImmutable $from, int $seconds)` | Voliteľné pre kalendár, ktorý počíta sám (kalendáre opening-hours to robia). |
| `HasWorkflowOwner` | `workflowOwner(): ?Model` | Na modeli subjektu: jeho vlastník, overuje sa ako prvý. |
| `DescribesWorkflowSubject` | `describe(): SubjectTypeBuilder` | Triedy uvedené vo workflows.subjects. |
| `WorkflowEvent` | `workflowKey(), workflowSubject(), workflowPayload(), workflowUser(), workflowIdempotencyKey()` | Udalosť hostiteľa, ktorá sa opisuje sama (listen() alebo '\*'). |

Väzba AuthorizesSteps, RestoresOwnerContext alebo ChecksOwnerMembership v kontajneri, zaregistrovaná po provideri balíka, má prednosť pred triedou z konfigurácie.

## Prejavte lásku k open source

Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.

[Ďalšie spôsoby podpory vrátane kryptomien](https://roundly-consulting.com/sk/podporte-nas.md)

Odoslaním daru súhlasíte s našimi [podmienkami prijímania darov](https://roundly-consulting.com/sk/podmienky-darov.md).

[Podporte našu open-source prácu (otvorí sa v novej karte)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Pridajte sa k nám na Patreone (otvorí sa v novej karte)](https://www.patreon.com/cw/roundly)

## Chcete to zabudovať do svojho produktu?

Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.

[Ponuka do 48 hodín](https://roundly-consulting.com/sk/kontakt.md) [Prezrieť všetky balíky](https://roundly-consulting.com/sk/open-source/navody/workflows-for-laravel.md)
