-
-
Notifications
You must be signed in to change notification settings - Fork 0
Configuration Guide
Master advanced configuration options to customize Laravel Statecraft for your specific needs.
Laravel Statecraft offers extensive configuration options to adapt to different project structures, performance requirements, and business needs. This guide covers all configuration options from basic setup to advanced customization.
Publish the default configuration file:
php artisan vendor:publish --tag=statecraft-config
This creates config/statecraft.php
with all available options:
<?php
return [
/*
|--------------------------------------------------------------------------
| State Machines Path
|--------------------------------------------------------------------------
| Path where your YAML state machine definitions are stored
*/
'state_machines_path' => base_path('state-machines'),
/*
|--------------------------------------------------------------------------
| Default State Field
|--------------------------------------------------------------------------
| Default database field name to store current state
*/
'default_state_field' => 'status',
/*
|--------------------------------------------------------------------------
| History Tracking
|--------------------------------------------------------------------------
| Configuration for state transition history
*/
'history' => [
'enabled' => false,
'table' => 'state_machine_histories',
'model' => \Grazulex\LaravelStatecraft\Models\StateMachineHistory::class,
'queue_recording' => false,
'cleanup_enabled' => false,
'retention_days' => 365,
],
/*
|--------------------------------------------------------------------------
| Events Configuration
|--------------------------------------------------------------------------
| Configuration for state machine events
*/
'events' => [
'enabled' => true,
'queue_listeners' => false,
'queue_connection' => 'default',
],
/*
|--------------------------------------------------------------------------
| Performance Settings
|--------------------------------------------------------------------------
| Caching and performance optimizations
*/
'cache' => [
'enabled' => true,
'ttl' => 3600, // 1 hour
'store' => 'default',
'prefix' => 'statecraft',
],
/*
|--------------------------------------------------------------------------
| Class Resolution
|--------------------------------------------------------------------------
| Default namespaces for guards and actions
*/
'namespaces' => [
'guards' => 'App\\Guards',
'actions' => 'App\\Actions',
],
/*
|--------------------------------------------------------------------------
| Validation
|--------------------------------------------------------------------------
| Validation settings for YAML files
*/
'validation' => [
'strict_mode' => false,
'validate_on_load' => true,
'validate_guards' => true,
'validate_actions' => true,
],
];
Configure where YAML files are stored:
// Default: base_path('state-machines')
'state_machines_path' => base_path('state-machines'),
// Alternative locations
'state_machines_path' => resource_path('workflows'),
'state_machines_path' => storage_path('state-machines'),
'state_machines_path' => app_path('StateMachines/Definitions'),
Flat structure (recommended for small projects):
state-machines/
βββ OrderStateMachine.yaml
βββ UserRegistrationStateMachine.yaml
βββ ArticleWorkflow.yaml
Hierarchical structure (recommended for large projects):
state-machines/
βββ e-commerce/
β βββ OrderStateMachine.yaml
β βββ PaymentStateMachine.yaml
β βββ RefundStateMachine.yaml
βββ content/
β βββ ArticleStateMachine.yaml
β βββ CommentModerationStateMachine.yaml
βββ user/
βββ RegistrationStateMachine.yaml
βββ SubscriptionStateMachine.yaml
Create a custom file loader for special requirements:
// In a service provider
$this->app->singleton(StateDefinitionLoader::class, function ($app) {
return new CustomStateDefinitionLoader([
'primary_path' => config('statecraft.state_machines_path'),
'fallback_paths' => [
resource_path('legacy-workflows'),
storage_path('external-workflows'),
],
'file_extensions' => ['yaml', 'yml', 'json'],
]);
});
'history' => [
'enabled' => true,
'table' => 'state_machine_histories',
'model' => \App\Models\CustomStateMachineHistory::class,
]
'history' => [
'enabled' => true,
'table' => 'state_machine_histories',
'model' => \App\Models\StateMachineHistory::class,
// Performance options
'queue_recording' => true,
'queue_connection' => 'database',
'queue' => 'state-transitions',
'batch_size' => 100,
// Cleanup configuration
'cleanup_enabled' => true,
'retention_days' => 365,
'cleanup_schedule' => '0 2 * * *', // Daily at 2 AM
// Storage optimization
'compress_metadata' => true,
'partition_by_month' => true,
// Per-model settings
'model_settings' => [
'App\Models\Order' => [
'retention_days' => 2555, // 7 years for orders
'detailed_logging' => true,
],
'App\Models\TempWorkflow' => [
'retention_days' => 30,
'detailed_logging' => false,
],
],
]
Create a custom history model for specific requirements:
<?php
namespace App\Models;
use Grazulex\LaravelStatecraft\Models\StateMachineHistory as BaseHistory;
class CustomStateMachineHistory extends BaseHistory
{
protected $table = 'custom_state_histories';
protected $fillable = [
'model_type',
'model_id',
'state_machine',
'transition',
'from_state',
'to_state',
'context',
'user_id',
'ip_address',
'user_agent',
'session_id',
];
protected $casts = [
'context' => 'encrypted:array', // Encrypt sensitive data
'created_at' => 'datetime',
'updated_at' => 'datetime',
];
// Custom relationships
public function user()
{
return $this->belongsTo(User::class);
}
// Custom scopes
public function scopeByUser($query, $userId)
{
return $query->where('user_id', $userId);
}
public function scopeRecent($query, $days = 30)
{
return $query->where('created_at', '>=', now()->subDays($days));
}
}
'events' => [
'enabled' => true,
'queue_listeners' => false,
]
'events' => [
'enabled' => true,
// Performance settings
'queue_listeners' => true,
'queue_connection' => 'redis',
'queue' => 'state-events',
// Event filtering
'dispatch_events' => [
'state_transitioning' => true,
'state_transitioned' => true,
'transition_failed' => true,
'guard_failed' => false, // Disable noisy events
],
// Custom event classes
'event_classes' => [
'state_transitioning' => \App\Events\CustomStateTransitioning::class,
'state_transitioned' => \App\Events\CustomStateTransitioned::class,
],
// Model-specific settings
'model_settings' => [
'App\Models\Order' => [
'enable_broadcasting' => true,
'broadcast_channel' => 'orders.{id}',
],
'App\Models\InternalWorkflow' => [
'enabled' => false, // Disable events for internal workflows
],
],
]
Create custom event classes for specific business logic:
<?php
namespace App\Events;
use Grazulex\LaravelStatecraft\Events\StateTransitioned as BaseEvent;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class OrderStateTransitioned extends BaseEvent implements ShouldBroadcast
{
use InteractsWithSockets;
public function broadcastOn()
{
return [
new Channel('orders'),
new PrivateChannel('user.' . $this->model->customer_id),
];
}
public function broadcastWith()
{
return [
'order_id' => $this->model->id,
'previous_state' => $this->from,
'new_state' => $this->to,
'transition' => $this->transition,
'timestamp' => now()->toISOString(),
];
}
}
'cache' => [
'enabled' => true,
'ttl' => 3600, // Cache for 1 hour
'store' => 'redis', // Use Redis for better performance
'prefix' => 'statecraft',
// What to cache
'cache_definitions' => true,
'cache_resolved_guards' => true,
'cache_resolved_actions' => true,
'cache_available_transitions' => true,
// Cache invalidation
'auto_invalidate' => true,
'invalidate_on_file_change' => true,
]
'database' => [
// Use database connections optimized for reads
'read_connection' => 'mysql_read',
'write_connection' => 'mysql_write',
// Query optimization
'eager_load_relationships' => true,
'use_query_cache' => true,
// Bulk operations
'batch_size' => 1000,
'chunk_size' => 500,
]
'memory' => [
'max_definitions_in_memory' => 100,
'clear_resolved_instances' => true,
'use_weak_references' => true,
]
'security' => [
// Restrict who can execute transitions
'require_authentication' => true,
'check_permissions' => true,
// Audit settings
'log_all_transitions' => true,
'log_failed_attempts' => true,
'log_guard_failures' => false,
// Validation
'validate_guard_classes' => true,
'validate_action_classes' => true,
'allow_dynamic_loading' => false, // Prevent code injection
]
'encryption' => [
'encrypt_context' => true,
'encrypt_metadata' => true,
'encryption_key' => env('STATECRAFT_ENCRYPTION_KEY'),
]
'namespaces' => [
'guards' => 'App\\Guards',
'actions' => 'App\\Actions',
// Model-specific namespaces
'model_namespaces' => [
'App\\Models\\Order' => [
'guards' => 'App\\OrderWorkflow\\Guards',
'actions' => 'App\\OrderWorkflow\\Actions',
],
'App\\Models\\Article' => [
'guards' => 'App\\Content\\Guards',
'actions' => 'App\\Content\\Actions',
],
],
]
Implement a custom class resolver:
<?php
namespace App\Services;
use Grazulex\LaravelStatecraft\Contracts\ClassResolver;
class CustomClassResolver implements ClassResolver
{
public function resolveGuard(string $className, string $modelClass = null): string
{
// Custom logic for resolving guard classes
if (str_starts_with($className, 'Legacy.')) {
return $this->resolveLegacyClass($className);
}
return $this->resolveModernClass($className, 'Guards');
}
public function resolveAction(string $className, string $modelClass = null): string
{
// Custom logic for resolving action classes
return $this->resolveModernClass($className, 'Actions');
}
private function resolveModernClass(string $className, string $type): string
{
// Implementation details...
}
}
Register the custom resolver:
// In a service provider
$this->app->singleton(ClassResolver::class, CustomClassResolver::class);
'validation' => [
'strict_mode' => false,
'validate_on_load' => true,
'validate_guards' => true,
'validate_actions' => true,
// YAML validation
'yaml_schema_validation' => true,
'custom_schema_path' => resource_path('schemas/statecraft.json'),
// Runtime validation
'validate_state_existence' => true,
'validate_transition_paths' => true,
'check_circular_dependencies' => true,
// Error handling
'fail_on_validation_errors' => false,
'log_validation_warnings' => true,
]
'custom_validators' => [
'guards' => \App\Validators\GuardValidator::class,
'actions' => \App\Validators\ActionValidator::class,
'yaml' => \App\Validators\YamlValidator::class,
]
// config/statecraft.php for development
'debug' => [
'enabled' => env('APP_DEBUG', false),
'log_all_operations' => true,
'validate_strictly' => true,
'show_debug_info' => true,
],
'cache' => [
'enabled' => false, // Disable caching in development
],
'validation' => [
'strict_mode' => true,
'fail_on_validation_errors' => true,
],
// config/statecraft.php for production
'cache' => [
'enabled' => true,
'ttl' => 86400, // Cache for 24 hours
'store' => 'redis',
],
'history' => [
'enabled' => true,
'queue_recording' => true,
'cleanup_enabled' => true,
],
'events' => [
'queue_listeners' => true,
'queue_connection' => 'redis',
],
'validation' => [
'strict_mode' => false,
'validate_on_load' => false, // Skip validation in production
],
// config/statecraft.php for testing
'history' => [
'enabled' => false, // Disable history in tests
],
'events' => [
'enabled' => false, // Disable events in tests unless specifically testing them
],
'cache' => [
'enabled' => false,
],
Create a custom state machine manager:
<?php
namespace App\Services;
use Grazulex\LaravelStatecraft\StateMachineManager as BaseManager;
class CustomStateMachineManager extends BaseManager
{
protected function beforeTransition($model, $from, $to, $transition, $context)
{
// Custom logic before any transition
$this->auditService->logTransitionAttempt($model, $from, $to);
return parent::beforeTransition($model, $from, $to, $transition, $context);
}
protected function afterTransition($model, $from, $to, $transition, $context)
{
// Custom logic after any transition
parent::afterTransition($model, $from, $to, $transition, $context);
$this->notificationService->handleStateChange($model, $from, $to);
}
}
Register the custom manager:
// In a service provider
$this->app->singleton('statecraft.manager', CustomStateMachineManager::class);
Create a command to validate your configuration:
php artisan statecraft:validate-config
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class StatecraftHealthCheck extends Command
{
protected $signature = 'statecraft:health-check';
public function handle()
{
$this->info('Checking Laravel Statecraft configuration...');
// Check file paths
$this->checkPaths();
// Check database configuration
$this->checkDatabase();
// Check cache configuration
$this->checkCache();
// Check class resolution
$this->checkClassResolution();
$this->info('Health check completed!');
}
private function checkPaths()
{
$path = config('statecraft.state_machines_path');
if (!is_dir($path)) {
$this->error("State machines path does not exist: {$path}");
} else {
$this->info("β State machines path exists: {$path}");
}
}
// Additional check methods...
}
- Environment-specific configs - Use different settings per environment
- Namespace organization - Group related guards and actions
- Performance tuning - Enable caching and queuing in production
- Security hardening - Enable validation and auditing
- Monitoring setup - Configure logging and health checks
// Optimize for production deployment
'deployment' => [
'precompile_definitions' => true,
'validate_on_deploy' => true,
'warm_cache' => true,
'check_dependencies' => true,
]
Now that you understand configuration, explore:
- π§ͺ Testing Guide - Test your state machines
- π οΈ Console Commands - Master CLI tools
- π State History - Configure history tracking
- π― Events System - Configure events
- π‘ Examples Collection - See configuration examples
- π User Workflow - Advanced patterns
- π Performance tuning - Main repository
- π API Documentation - Complete API reference
Ready to test your configuration? Check out π§ͺ Testing Guide!
π― Laravel Statecraft - Advanced State Machine Implementation for Laravel
Navigate: π Home | π¦ Installation | π Basic Guide | π YAML Config | π‘ Examples
Resources: π‘οΈ Guards & Actions | π― Events | π State History | π§ͺ Testing | π¨ Commands
π Community Resources:
Made with β€οΈ for the Laravel community β’ Contribute β’ License