Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

State Laravel Package

api-platform/state

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require api-platform/state
    

    Add the bundle to config/bundles.php (Symfony) or register the service in config/services.php (Laravel via api-platform/core if applicable).

  2. First Use Case:

    • Use the StateProcessorInterface to handle state transitions (e.g., published, draft, archived).
    • Example in a controller or event listener:
      use ApiPlatform\State\Processor\StateProcessorInterface;
      
      class PostController extends AbstractController
      {
          public function __construct(private StateProcessorInterface $stateProcessor) {}
      
          public function publish(Post $post): Post
          {
              return $this->stateProcessor->process($post, 'publish');
          }
      }
      
  3. Where to Look First:


Implementation Patterns

Workflows

  1. State Transitions:

    • Define states in a YAML/array config (e.g., config/state_machines.yaml):
      App\Entity\Post:
          initial_state: draft
          transitions:
              publish: { from: draft, to: published }
              archive: { from: published, to: archived }
      
    • Use the processor in controllers, commands, or events:
      $post = $this->stateProcessor->process($entity, 'publish');
      
  2. Event-Driven States:

    • Listen to state changes via StateChangedEvent:
      use ApiPlatform\State\Event\StateChangedEvent;
      
      public function onStateChanged(StateChangedEvent $event): void
      {
          $entity = $event->getSubject();
          $from = $event->getFromState();
          $to = $event->getToState();
      
          // Trigger side effects (e.g., notifications, logs)
      }
      
  3. Validation Guards:

    • Use guards to restrict transitions (e.g., prevent unpublishing a post with comments):
      transitions:
          unpublish:
              from: published
              to: draft
              guard: App\Guard\CanUnpublishPostGuard
      

Integration Tips

  • Laravel-Specific:

    • Bind the StateProcessorInterface in AppServiceProvider:
      $this->app->bind(StateProcessorInterface::class, function ($app) {
          return new DefaultStateProcessor(
              $app->make(StateMachineFactory::class),
              $app->make(StateMachineLoaderInterface::class)
          );
      });
      
    • Use Laravel’s event system to dispatch StateChangedEvent:
      event(new StateChangedEvent($entity, $from, $to));
      
  • API Platform Integration:

    • Extend StateProcessor in a custom StateProcessor class to add Laravel-specific logic (e.g., Eloquent model updates).

Gotchas and Tips

Pitfalls

  1. Circular Dependencies:

    • Avoid injecting StateProcessor into entity constructors. Use setters or lazy-load it in controllers/services.
  2. State Machine Misconfiguration:

    • Ensure initial_state is set in config. Missing states will throw StateMachineException.
    • Validate transitions with php bin/console debug:state-machine (Symfony) or a custom Artisan command.
  3. Race Conditions:

    • State transitions should be atomic. Use database transactions:
      DB::transaction(function () use ($post) {
          $this->stateProcessor->process($post, 'publish');
      });
      

Debugging

  • Log State Changes:
    • Subscribe to StateChangedEvent to log transitions:
      public function onStateChanged(StateChangedEvent $event): void
      {
          \Log::info("State changed: {$event->getSubject()->getId()}", [
              'from' => $event->getFromState(),
              'to' => $event->getToState(),
          ]);
      }
      
  • Check Guards:
    • If a transition fails silently, inspect guard logic or enable debug mode:
      $this->stateProcessor->process($entity, 'transition', [], true); // Force debug mode
      

Extension Points

  1. Custom State Machines:

    • Implement StateMachineInterface for non-Symfony state machines (e.g., Laravel’s StateMachine package).
  2. Dynamic Transitions:

    • Use closures in guards to enable runtime logic:
      guard: { from: draft, to: published, closure: App\Guard\DynamicPublishGuard }
      
  3. Laravel Eloquent Hooks:

    • Trigger state changes in saving() or saved() model events:
      protected static function boot()
      {
          static::saved(function ($model) {
              if ($model->isDirty('status')) {
                  $model->stateProcessor->process($model, $model->status);
              }
          });
      }
      

Config Quirks

  • YAML vs. PHP Config:
    • Prefer PHP arrays for complex logic (e.g., dynamic guards):
      return [
          'App\Entity\Post' => [
              'initial_state' => 'draft',
              'transitions' => [
                  'publish' => [
                      'from' => 'draft',
                      'to' => 'published',
                      'guard' => new DynamicPublishGuard(),
                  ],
              ],
          ],
      ];
      
  • Caching:
    • State machine configs are cached. Clear cache after changes:
      php artisan config:clear
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
calmfox/watch-sylius
damienfern/grpc-symfony-bundle
atoolo/index-bundle
atoolo/genai-bundle
coprotoai/laravel-ticket
davidjln/llm-carbon-bundle
cryonighter/valid-request-bundle
coolms/taxonomy-bundle
coolms/field-bundle
articulate-orm/symfony
aaix/laravel-tall-architect
ephoto/akeneo-connector
emmanuelballery/eb-plantumlbundle
emielburgman/symfony-visitor-beacon
emielburgman/symfony-visit-storage
emielburgman/symfony-security-headers
emielburgman/symfony-log-viewer
emarref/xdebug-bundle
emarref/pubnub-bundle
elriseio/finance-money-bundle