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

Business-Workflows in Symfony-Anwendungen model...

Business-Workflows in Symfony-Anwendungen modellieren

SymfonyLive Cologone 2017

Avatar for Christian Flothmann

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; } }