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. Christian Flothmann Symfony Core Team & Documentation Team Entwickler bei

    SensioLabs Deutschland github.com/xabbuh @xabbuh
  2. • 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
  3. • Subject: Objekt, auf das ein Workflow angewandt wird •

    Place: Zustände, die ein Workflow annehmen kann • Transition: (benannter) Übergang zwischen zwei Places Terminologie
  4. • Marking: Zustand/Zustände, in denen sich ein Workflow befindet •

    Marking Store: Mapping des Workflow Markings auf Properties des Subjects Terminologie
  5. AppBundle\Entity\Order class Order { /** * @var string */ private

    $state; /** * @var Customer */ private $customer; /** * @var Product[] */ private $products; }
  6. Konfiguration framework: workflows: order_payment: places: - placed - paid -

    payment_failed - delivered - returned - refunded initial_place: placed
  7. 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'); // ... }
  8. Twig-Integration {# Transition auf Anwendbarkeit testen #} {% if workflow_can(order,

    'deliver', 'order_payment') %} <a href="{{ path('deliver_order') }}">Deliver</a> {% endif %} {# alle anwendbaren Transitionen #} {% for t in workflow_transitions(order, 'order_payment') %} <a href="{{ path(t.name ~ '_order') }}"> {{ ('transition.' ~ t.name)|trans }} </a> {% endfor %}
  9. • workflow.leave vor dem Verlassen eines Places • workflow.transition vor

    dem Anwenden einer Transition • workflow.enter vor dem Entern eines Places • workflow.<workflow>.announce.<transition> Announcement aktivierter Transitions Event-Kategorien
  10. 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; } }
  11. 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
  12. • Möglichkeit durch Event Listener Ausführung von Transitionen zu blocken

    • Events: o workflow.guard o workflow.<workflow>.guard o workflow.<workflow>.guard.<transition> Guard Events
  13. 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); } } }
  14. 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(', ') }}
  15. • neues Event: workflow.entered • nachdem ein Place aktiviert wurde

    • Abstufungen: o workflow.entered o workflow.<workflow>.entered o workflow. <workflow>.entered.<place> • neue Methode: getWorkflowName() Änderungen am Event-System
  16. Guard Expression Support framework: workflows: order_payment: # ... transitions: deliver:

    guard: 'has_role("ROLE_DELIVERER")' from: paid to: delivered # ...
  17. 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
  18. 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; } }