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

Workflow Bundle Laravel Package

aboutcoders/workflow-bundle

Symfony bundle to define and manage workflows with optional GUI. Provides routing and ORM configuration, Twig helpers to render workflow configuration and history, and an AJAX endpoint to fetch execution history. Integrates with KnpMenuBundle and JobBundle.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require aboutcoders/workflow-bundle:dev-master
    

    Ensure Abc\Bundle\WorkflowBundle\AbcWorkflowBundle is registered in AppKernel.php.

  2. Routing Add to app/config/routing.yml:

    abc_workflow_tasks:
        resource: "@AbcWorkflowBundle/Resources/config/routing.yml"
        prefix:   /
    

    Optionally, include the GUI routes:

    abc_workflow_workflows:
        resource: "@AbcWorkflowBundle/Resources/config/routing_optional.yml"
        prefix:   /
    
  3. Configuration Define workflows in YAML (e.g., app/config/config.yml):

    abc_workflow:
        db_driver: orm
        workflows:
            my_workflow:
                supports: App\Entity\MyEntity
                places: [draft, published, archived]
                transitions:
                    - { from: draft, to: published }
                    - { from: published, to: archived }
    
  4. First Use Case Inject the workflow service in a controller:

    use Abc\Bundle\WorkflowBundle\Workflow\WorkflowService;
    
    public function __construct(WorkflowService $workflowService) {
        $this->workflowService = $workflowService;
    }
    
    public function publishAction(MyEntity $entity) {
        $this->workflowService->apply($entity, 'publish');
        return new Response('Published!');
    }
    

Implementation Patterns

Workflow Integration in Entities

  1. Annotate Entities Use the @Workflow annotation to define workflow support:

    use Abc\Bundle\WorkflowBundle\Annotation\Workflow;
    
    /**
     * @Workflow("my_workflow")
     */
    class MyEntity {}
    
  2. Service Integration Use the WorkflowService to manage transitions:

    // Apply a transition
    $workflowService->apply($entity, 'publish');
    
    // Check current place
    $currentPlace = $workflowService->getCurrentPlace($entity);
    
    // Check allowed transitions
    $allowedTransitions = $workflowService->getAllowedTransitions($entity);
    
  3. Event Listeners Listen to workflow events (e.g., WorkflowTransitionEvent):

    use Abc\Bundle\WorkflowBundle\Event\WorkflowTransitionEvent;
    use Symfony\Component\EventDispatcher\EventSubscriberInterface;
    
    class WorkflowSubscriber implements EventSubscriberInterface {
        public static function getSubscribedEvents() {
            return [
                'workflow.transition' => 'onTransition',
            ];
        }
    
        public function onTransition(WorkflowTransitionEvent $event) {
            // Handle transition logic (e.g., send notifications)
        }
    }
    

GUI Integration

  1. Display Workflow Configuration Use the Twig extension in templates:

    {{ workflow_configuration(entity) }}
    
  2. Show Workflow History

    {{ workflow_history(entity) }}
    
  3. AJAX History Fetching Use the execution_history route to fetch history dynamically:

    {{ path('execution_history', { 'entity': entity.id }) }}
    

Command-Line Workflows

  1. Bulk Transitions Create a custom command to apply transitions to multiple entities:
    use Symfony\Component\Console\Command\Command;
    use Symfony\Component\Console\Input\InputInterface;
    use Symfony\Component\Console\Output\OutputInterface;
    
    class BulkPublishCommand extends Command {
        protected function execute(InputInterface $input, OutputInterface $output) {
            $entities = $entityManager->getRepository(MyEntity::class)->findAll();
            foreach ($entities as $entity) {
                $this->workflowService->apply($entity, 'publish');
            }
            $output->writeln('Published all entities!');
        }
    }
    

Gotchas and Tips

Common Pitfalls

  1. Missing Dependencies

    • Ensure KnpMenuBundle and AbcJobBundle are installed and configured as per their docs. The workflow GUI relies on these.
  2. Incorrect Workflow Configuration

    • Validate YAML syntax for workflows. Typos in places or transitions will cause runtime errors.
    • Example of a broken config:
      transitions:
          - { from: draft, to: publish }  # Missing 'ed' in 'published'
      
  3. Entity Not Annotated

    • If an entity isn’t annotated with @Workflow, the bundle will ignore it. Double-check annotations or service configuration.
  4. Database Driver Mismatch

    • If db_driver is set to orm but your entities aren’t Doctrine-aware, transitions won’t persist. Ensure AbcWorkflowBundle is loaded after DoctrineBundle in AppKernel.php.
  5. Circular Dependencies in Transitions

    • Avoid defining transitions that create loops (e.g., draft → published → draft). The bundle doesn’t enforce this, but it can cause infinite loops in logic.

Debugging Tips

  1. Enable Debug Mode Symfony’s debug toolbar will show workflow-related events under the "Events" tab.

  2. Log Workflow Transitions Add a subscriber to log transitions:

    public function onTransition(WorkflowTransitionEvent $event) {
        $this->logger->info(
            sprintf('Transitioned %s from %s to %s',
                get_class($event->getEntity()),
                $event->getTransition()->getFrom(),
                $event->getTransition()->to
            )
        );
    }
    
  3. Check Workflow Service Methods Use these methods to inspect state:

    $workflowService->getCurrentPlace($entity);       // Current state
    $workflowService->getAllowedTransitions($entity); // Valid next steps
    $workflowService->getHistory($entity);            // Full history
    

Extension Points

  1. Custom Transition Guards Override transition logic by implementing Abc\Bundle\WorkflowBundle\Guard\GuardInterface:

    class CustomGuard implements GuardInterface {
        public function checkTransition($entity, Transition $transition) {
            // Custom logic (e.g., check user permissions)
            return true;
        }
    }
    

    Register it in services.yml:

    abc_workflow.guard.custom:
        class: App\Guard\CustomGuard
        tags:
            - { name: abc_workflow.guard, priority: 10 }
    
  2. Custom Workflow Storage Extend the bundle’s storage layer by implementing Abc\Bundle\WorkflowBundle\Storage\WorkflowStorageInterface for non-Doctrine ORMs.

  3. Twig Extensions Override or extend the Twig functions (e.g., workflow_configuration) by creating a custom Twig extension:

    class CustomWorkflowExtension extends \Twig_Extension {
        public function getFunctions() {
            return [
                new \Twig_SimpleFunction('custom_workflow_config', [$this, 'renderCustomConfig']),
            ];
        }
    }
    
  4. Event Dispatching Extend the bundle’s event system by listening to:

    • workflow.transition (after transition)
    • workflow.place_entered (when entering a place)
    • workflow.place_exited (when leaving a place)

Performance Considerations

  1. Avoid Heavy Logic in Guards Transition guards should be lightweight. Offload complex logic to services called from guards.

  2. Batch Processing For bulk operations, use Doctrine’s EntityManager::clear() to reduce memory usage:

    $em = $this->getDoctrine()->getManager();
    foreach ($entities as $entity) {
        $workflowService->apply($entity, 'publish');
        if ($i % 20 === 0) {  // Batch every 20 entities
            $em->clear();
        }
        $i++;
    }
    
  3. Caching Workflow Metadata If workflows rarely change, cache the configuration in a service to avoid re-parsing YAML on every request.

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.
comsave/common
alecsammon/php-raml-parser
chrome-php/wrench
lendable/composer-license-checker
typhoon/reflection
mesilov/moneyphp-percentage
mike42/gfx-php
bookdown/themes
aura/view
aura/html
aura/cli
povils/phpmnd
nayjest/manipulator
omnipay/tests
psr-mock/http-message-implementation
psr-mock/http-factory-implementation
psr-mock/http-client-implementation
voku/email-check
voku/urlify
rtheunissen/guzzle-log-middleware