Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Business-Workflows in Symfony-Anwendungen modellieren

Business-Workflows in Symfony-Anwendungen modellieren

SymfonyLive Cologone 2017

Christian Flothmann

April 07, 2017
Tweet

More Decks by Christian Flothmann

Other Decks in Programming

Transcript

  1. SensioLabs
    Business-Workflows
    in Symfony-
    Anwendungen
    modellieren

    View Slide

  2. Christian Flothmann
    Symfony Core Team &
    Documentation Team
    Entwickler bei SensioLabs
    Deutschland
    github.com/xabbuh
    @xabbuh

    View Slide

  3. Die Workflow
    Komponente

    View Slide

  4. • eingeführt in Symfony 3.2
    • unterstützt Workflow Nets und State
    Machines
    • in Twig und das Full-Stack Framework
    integriert
    • Audit Logging
    Die Workflow Komponente

    View Slide

  5. • Subject:
    Objekt, auf das ein Workflow angewandt
    wird
    • Place:
    Zustände, die ein Workflow annehmen kann
    • Transition:
    (benannter) Übergang zwischen zwei Places
    Terminologie

    View Slide

  6. • Marking:
    Zustand/Zustände, in denen sich ein
    Workflow befindet
    • Marking Store:
    Mapping des Workflow Markings auf
    Properties des Subjects
    Terminologie

    View Slide

  7. Beispiel:
    Bestellungen in
    einem Onlineshop

    View Slide

  8. AppBundle\Entity\Order
    class Order
    {
    /**
    * @var string
    */
    private $state;
    /**
    * @var Customer
    */
    private $customer;
    /**
    * @var Product[]
    */
    private $products;
    }

    View Slide

  9. Konfiguration
    framework:
    # ...
    workflows:
    order_payment:
    marking_store:
    type: single_state
    arguments: [state]
    supports:
    - AppBundle\Entity\Order
    # ...

    View Slide

  10. Konfiguration
    framework:
    workflows:
    order_payment:
    places:
    - placed
    - paid
    - payment_failed
    - delivered
    - returned
    - refunded
    initial_place: placed

    View Slide

  11. Konfiguration
    framework:
    workflows:
    order_payment:
    transitions:
    pay:
    from: [placed, payment_failed]
    to: paid
    deliver:
    from: paid
    to: delivered
    # ...

    View Slide

  12. Verwendung des Workflows
    public function startDeliveryAction(Order $order)
    {
    $workflow = $this->get('workflow.order_payment');
    if (!$workflow->can($order, 'deliver')) {
    // Error Handling
    }
    $workflow->apply($order, 'deliver');
    // ...
    }

    View Slide

  13. Twig-Integration
    {# Transition auf Anwendbarkeit testen #}
    {% if workflow_can(order, 'deliver', 'order_payment') %}
    Deliver
    {% endif %}
    {# alle anwendbaren Transitionen #}
    {% for t in workflow_transitions(order, 'order_payment') %}

    {{ ('transition.' ~ t.name)|trans }}

    {% endfor %}

    View Slide

  14. Das Event-System

    View Slide

  15. • workflow.leave
    vor dem Verlassen eines Places
    • workflow.transition
    vor dem Anwenden einer Transition
    • workflow.enter
    vor dem Entern eines Places
    • workflow..announce.
    Announcement aktivierter Transitions
    Event-Kategorien

    View Slide

  16. Die Event Klasse
    use Symfony\Component\EventDispatcher\Event as BaseEvent;
    class Event extends BaseEvent
    {
    // ...
    public function getMarking()
    {
    return $this->marking;
    }
    public function getSubject()
    {
    return $this->subject;
    }
    public function getTransition()
    {
    return $this->transition;
    }
    }

    View Slide

  17. Beispiel: Audit Logging
    services:
    audit_trail_logger:
    class: Symfony\Component\Workflow\EventListener\AuditTrailListener
    arguments: ['@logger']
    tags:
    - name: kernel.event_subscriber
    event: workflow.order_payment.leave
    method: onLeave
    - name: kernel.event_listener
    event: workflow.order_payment.transition
    method: onTransition
    - name: kernel.event_listener
    event: workflow.order_payment.enter
    method: onEnter

    View Slide

  18. • Möglichkeit durch Event Listener
    Ausführung von Transitionen zu blocken
    • Events:
    o workflow.guard
    o workflow..guard
    o workflow..guard.
    Guard Events

    View Slide

  19. Beispiel: rollenbasierter Access Check
    class RoleGuardListener
    {
    private $authorizationChecker;
    public function __construct(
    AuthorizationCheckerInterface $authorizationChecker
    ) {
    $this->authorizationChecker = $authorizationChecker;
    }
    public function canDeliver(GuardEvent $event)
    {
    if (!$this->authorizationChecker->isGranted('ROLE_DELIVERER')) {
    $event->setBlocked(true);
    }
    }
    }

    View Slide

  20. Beispiel: rollenbasierter Access Check
    services:
    role_guard_listener:
    class: AppBundle\Workflow\RoleGuardListener
    arguments: ['@security.authorization_checker']
    tags:
    - name: kernel.event_listener
    event: workflow.order_payment.guard.deliver
    method: canDeliver

    View Slide

  21. SensioLabs
    Neu in Symfony
    3.3

    View Slide

  22. Neue Twig-Funktionen
    {# prüfen, ob ein Workflow in einem
    gewünschten Place ist #}
    {% if workflow_has_marked_place(order, 'paid', 'order_payment') %}
    bezahlt
    {% endif %}
    {# aktive Places ermitteln #}
    {{ workflow_marked_places(order, true, 'order_payment')|join(', ') }}

    View Slide

  23. • neues Event: workflow.entered
    • nachdem ein Place aktiviert wurde
    • Abstufungen:
    o workflow.entered
    o workflow..entered
    o workflow. .entered.
    • neue Methode: getWorkflowName()
    Änderungen am Event-System

    View Slide

  24. Guard Expression
    Support

    View Slide

  25. Guard Expression Support
    framework:
    workflows:
    order_payment:
    # ...
    transitions:
    deliver:
    guard: 'has_role("ROLE_DELIVERER")'
    from: paid
    to: delivered
    # ...

    View Slide

  26. • subject
    • token
    • user
    • roles
    Guard Expression Support, Variablen

    View Slide

  27. • is_granted()
    • is_anonymous()
    • is_authenticated()
    • is_fully_authenticated()
    • is_rememberme()
    • has_role()
    Guard Expression Support, Funktionen

    View Slide

  28. Verbesserte
    Integration des
    AuditTrailLogger

    View Slide

  29. Symfony 3.2
    services:
    audit_trail_logger:
    class: Symfony\Component\Workflow\EventListener\AuditTrailListener
    arguments: ['@logger']
    tags:
    - name: kernel.event_subscriber
    event: workflow.order_payment.leave
    method: onLeave
    - name: kernel.event_listener
    event: workflow.order_payment.transition
    method: onTransition
    - name: kernel.event_listener
    event: workflow.order_payment.enter
    method: onEnter

    View Slide

  30. Symfony 3.3
    framework:
    workflows:
    order_payment:
    supports: AppBundle\Entity\Order
    audit_trail: true
    # ...

    View Slide

  31. Benutzerdefinierte
    Support Strategien

    View Slide

  32. Benutzerdefinierte Support Strategien
    use Symfony\Component\Workflow\SupportStrategy\SupportStrategyInterface;
    class EconomySupportStrategy implements SupportStrategyInterface
    {
    public function supports(Workflow $workflow, $subject)
    {
    if (!$subject instanceof Article) {
    return false;
    }
    return $subject->getCategory() === Article::CATEGORY_ECONOMY;
    }
    }

    View Slide

  33. Benutzerdefinierte Support Strategien
    services:
    economy_article_strategy:
    class: AppBundle\EconomySupportStrategy

    View Slide

  34. Benutzerdefinierte Support Strategien
    framework:
    workflows:
    economy_article_publication:
    support_strategy: economy_article_strategy
    # ...

    View Slide

  35. SensioLabs
    Vielen Dank!

    View Slide

  36. SensioLabs
    https://joind.in/talk/10c9f

    View Slide