
# Διακλάδωση υπό συνθήκη

Οι ροές εργασίας μπορούν να μεταβούν σε ένα επώνυμο βήμα με βάση την έξοδο ενός προηγούμενου βήματος. Αυτό γίνεται επιστρέφοντας ένα ειδικό κλειδί `_next_step` στην τιμή επιστροφής του βήματος.

Αν θέλετε συγκεκριμένα να επιστρέψετε σε προηγούμενο βήμα με βάση την κατάσταση της ροής εργασίας, δείτε τις [Επαναλήψεις](https://queuety.inline0.dev/el/docs/workflows/repeats). Έτσι η αναδρομική σύνδεση παραμένει ρητή στον ορισμό της ροής εργασίας, αντί να κρύβεται μέσα σε μια κλάση βήματος.

## Επώνυμα βήματα

Δώστε όνομα στα βήματα χρησιμοποιώντας το δεύτερο όρισμα του `->then()`:

```php
use Queuety\Queuety;

Queuety::workflow( 'process_order' )
    ->then( ValidateOrderHandler::class, 'validate' )
    ->then( ChargePaymentHandler::class, 'charge' )
    ->then( FulfillOrderHandler::class, 'fulfill' )
    ->then( SendConfirmationHandler::class, 'confirm' )
    ->then( HandleFailureHandler::class, 'failure' )
    ->dispatch( [ 'order_id' => 123 ] );
```

Χωρίς ρητό όνομα, τα βήματα ονομάζονται με βάση τον δείκτη τους (`'0'`, `'1'`, `'2'` κ.λπ.).

## Το κλειδί `_next_step`

Ένα βήμα μπορεί να επιστρέψει το `_next_step` για να μεταβεί σε ένα επώνυμο βήμα, παραλείποντας όλα τα ενδιάμεσα. Τα βήματα μετά τον στόχο της μετάβασης εξακολουθούν να εκτελούνται με τη σειρά: χωρίς μετάβαση, η ροή εργασίας συνεχίζει απλώς με το επόμενο βήμα της λίστας. Έτσι, στο παραπάνω παράδειγμα, ένα επιτυχημένο βήμα `confirm` συνεχίζει στο `failure`, εκτός αν επιστρέψει ένα `_next_step` που το παραλείπει ή αν το `HandleFailureHandler` ελέγξει πρώτα για κλειδί `error`:

```php
use Queuety\Step;

class ValidateOrderHandler implements Step {
    public function handle( array $state ): array {
        $order = wc_get_order( $state['order_id'] );

        if ( ! $order || $order->get_status() === 'cancelled' ) {
            return [
                'error'  => 'Order is invalid or cancelled',
                '_next_step'  => 'failure',
            ];
        }

        return [
            'order_total' => $order->get_total(),
            'customer_id' => $order->get_customer_id(),
        ];
    }

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

Όταν το `ValidateOrderHandler` επιστρέφει το `_next_step => 'failure'`, η ροή εργασίας παραλείπει τα `charge`, `fulfill` και `confirm` και μεταβαίνει απευθείας στο βήμα `failure`. Το κλειδί `_next_step` καταναλώνεται από τη μηχανή ροής εργασίας και δεν αποθηκεύεται στην κατάσταση.

## Μοτίβα διακλάδωσης

### Παράλειψη υπό συνθήκη

```php
class CheckInventoryHandler implements Step {
    public function handle( array $state ): array {
        $in_stock = check_inventory( $state['sku'] );

        if ( ! $in_stock ) {
            return [
                'reason' => 'Out of stock',
                '_next_step'  => 'notify_backorder',
            ];
        }

        return [ 'inventory_reserved' => true ];
    }

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

### Πρόωρη ολοκλήρωση

Μεταβείτε στο τελικό βήμα για να παραλείψετε περιττή επεξεργασία:

```php
class CheckCacheHandler implements Step {
    public function handle( array $state ): array {
        $cached = get_transient( "report_{$state['user_id']}" );

        if ( $cached ) {
            return [
                'report_url' => $cached,
                '_next_step'      => 'done',
            ];
        }

        return [ 'cache_miss' => true ];
    }

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

## Πλήρες παράδειγμα

```php
Queuety::workflow( 'content_pipeline' )
    ->then( CheckCacheHandler::class, 'check_cache' )
    ->then( FetchDataHandler::class, 'fetch' )
    ->then( CallLLMHandler::class, 'generate' )
    ->then( SaveResultHandler::class, 'save' )
    ->then( ReturnCachedHandler::class, 'done' )
    ->dispatch( [ 'user_id' => 42 ] );
```

Αν ο έλεγχος της cache εντοπίσει επιτυχία, η ροή εργασίας μεταβαίνει απευθείας από το `check_cache` στο `done`, παραλείποντας τα `fetch`, `generate` και `save`. Αν δεν εντοπίσει επιτυχία, τα βήματα εκτελούνται με τη σειρά και το `save` συνεχίζει και στο `done`, επομένως το `ReturnCachedHandler` πρέπει να χειρίζεται και τις δύο διαδρομές.
