
# Spouštění workflow

Workflow může v rámci jednoho ze svých kroků spustit podřízené workflow. Nadřazené workflow se pozastaví, dokud se spuštěné workflow nedokončí, a pak sloučí jeho konečný stav do svého stavu.

## Metoda `->run_workflow()`

```php
use Queuety\Queuety;

$enrichment = Queuety::workflow( 'enrich_user' )
    ->then( FetchSocialHandler::class )
    ->then( FetchCreditScoreHandler::class );

Queuety::workflow( 'onboarding' )
    ->then( CreateAccountHandler::class )
    ->run_workflow( 'enrich_user', $enrichment )
    ->then( SendWelcomeEmailHandler::class )
    ->dispatch( [ 'email' => 'user@example.com' ] );
```

Metoda `run_workflow()` přijímá dva argumenty:
1. Název spuštěného workflow
2. Instanci `WorkflowBuilder`, která definuje jeho kroky

## Jak to funguje

Když nadřazené workflow dosáhne kroku `run_workflow`:

1. Spuštěné workflow se zařadí jako nezávislé workflow s vlastním ID
2. Nadřazené workflow se pozastaví
3. Spuštěné workflow běžně provede své kroky
4. Po dokončení se jeho konečný stav sloučí se stavem nadřazeného workflow
5. Nadřazené workflow pokračuje dalším krokem

## Stav nadřazeného a podřízeného workflow

Spuštěné workflow obdrží aktuální nashromážděný stav nadřazeného workflow jako počáteční data. Podřízené kroky tak mají přístup ke všem datům vytvořeným předchozími kroky nadřazeného workflow:

```php
class CreateAccountHandler implements Step {
    public function handle( array $state ): array {
        $user_id = wp_create_user( $state['email'], wp_generate_password() );
        return [ 'user_id' => $user_id ];
    }

    public function config(): array {
        return [];
    }
}

// This run-workflow step can access 'user_id' from the parent
class FetchSocialHandler implements Step {
    public function handle( array $state ): array {
        $profile = fetch_social_profile( $state['user_id'] );
        return [ 'social_data' => $profile ];
    }

    public function config(): array {
        return [];
    }
}
```

## Sloučení stavu

Po dokončení spuštěného workflow se jeho konečný stav (bez interních klíčů, jako jsou `_steps`, `_queue`, `_priority`, `_max_attempts`) sloučí se stavem nadřazeného workflow. Další nadřazený krok uvidí všechna data z dřívějších nadřazených kroků i ze spuštěného workflow:

```php
class SendWelcomeEmailHandler implements Step {
    public function handle( array $state ): array {
        // Has access to:
        // - $state['email'] (from initial dispatch)
        // - $state['user_id'] (from CreateAccountHandler)
        // - $state['social_data'] (from run-workflow's FetchSocialHandler)
        // - $state['credit_score'] (from run-workflow's FetchCreditScoreHandler)

        send_welcome_email( $state['email'], $state['social_data'] );
        return [ 'welcome_sent' => true ];
    }

    public function config(): array {
        return [];
    }
}
```

## Možnosti spuštěného workflow

Možnosti `on_queue()`, `with_priority()` a `max_attempts()` nástroje pro sestavení spuštěného workflow se vztahují na podřízené workflow. Ostatní možnosti na úrovni workflow v nástroji pro sestavení podřízeného workflow, například `on_cancel()`, `prune_state_after()`, `must_complete_within()`, `version()`, `idempotency_key()`, rozpočty `max_*()` a `compensate_on_failure()`, se nepřenášejí:

```php
$sub = Queuety::workflow( 'heavy_processing' )
    ->on_queue( 'background' )
    ->with_priority( Priority::Normal )
    ->max_attempts( 5 )
    ->then( StepA::class )
    ->then( StepB::class );

Queuety::workflow( 'parent' )
    ->run_workflow( 'heavy', $sub )
    ->then( FinalStep::class )
    ->dispatch( $payload );
```

## Vnořená spuštěná workflow

Spuštěná workflow mohou sama obsahovat další spuštěná workflow, což umožňuje libovolné vnořování:

```php
$inner = Queuety::workflow( 'inner' )
    ->then( InnerStepA::class )
    ->then( InnerStepB::class );

$middle = Queuety::workflow( 'middle' )
    ->then( MiddleStepA::class )
    ->run_workflow( 'inner', $inner )
    ->then( MiddleStepB::class );

Queuety::workflow( 'outer' )
    ->then( OuterStepA::class )
    ->run_workflow( 'middle', $middle )
    ->then( OuterStepB::class )
    ->dispatch( $payload );
```
