Listening to when a modifier is matched in the request

When purl detects that a modifier is present in the request, an event of type Drupal\purl\PurlEvents::MODIFIER_MATCHED passing in an instance of Drupal\purl\Event\ModifierMatchedEvent is dispatched for subscribers and listeners to do their thing.

Scenario:

Provider Method Modifier Value
microsites subdomain foo 1
microsites subdomain bar "baz"
department path_prefix dev 2

Current request: http://foo.drupalsite.io/dev/node/4737

As you can deduce, there are two modifiers that are matched in the current request:

Provider Method Modifier Value
microsites subdomain foo 1
department path_prefix dev 2

This results in two PurlEvents::MODIFIER_MATCHED events getting dispatched by @event_dispatcher.

Example listener:


<?php

namespace Drupal\microsites\ContextProvider;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Drupal\purl\Event\PurlEvents;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Plugin\Context\Context;
use Drupal\Core\Plugin\Context\ContextDefinition;
use Drupal\Core\Plugin\Context\ContextProviderInterface;

/**
 * Creates a microsite context whenever a `microsite` modifier is matched.
 */
class MicrositeContext implements ContextProviderInterface, EventSubscriberInterface
{
    protected $modifierMatched;

    protected $storage;

    public function __construct(EntityStorageInterface $storage)
    {
        $this->storage = $storage;
    }

    public static function getSubscribedEvents()
    {
        array(
            PurlEvents::MODIFIER_MATCHED => array('onModifierMatched'),
        );
    }

    public function onModifierMatched(ModifierMatchedEvent $event)
    {
        if ($event->getProvider() !== 'microsites') {
          // We are not interested in modifiers not provided by `microsites`.
          return;
        }

        $this->modifierMatched = $event;
    }

    public function getRuntimeContexts(array $unqualifiedContextIds)
    {
        if (!$this->modifierMatched === null) {
            return false;
        }

        $microsite = $this->storage->load($this->modifierMatched->getValue());

        $context = new Context(
            new ContextDefintion('microsite', $this->t('Microsite')),
            $microsite
        );

        return array(
            'microsite' => $context,
        );
    }
}

Register the context provider as an event_subscriber:

# microsites.services.yml

services:
    microsites.context_provider:
        class: Drupal\microsites\ContextProvider\MicrositeContext
        arguments: [ @microsites.entity_storage ]
        tags:
          - { name: context_provider }
          - { name: event_subscriber }

    microsites.entity_storage
        class: Drupal\Core\Entity\EntityStorageInterface
        factory: [ @entity.manager, getStorage ]
        arguments: [ "microsite" ]