官术网_书友最值得收藏!

Dispatching events

Since we have discussed how to subscribe to events in Drupal 8, we should also take a look at how we can dispatch our own events. After all, the Symfony Event Dispatcher component is one of the principal vectors of extensibility in Drupal 8.

To demonstrate this, we will create an event to be dispatched whenever our HelloWorldSalutation::getSalutation() method is called. The purpose is to inform other modules that this has happened and potentially allow them to alter the message that comes out of the configuration object—not really a solid use case, but good enough to demonstrate how we can dispatch events.

The first thing that we will need to do is to create an event class that will be dispatched. It can go into the root of our module's namespace:

namespace Drupal\hello_world; 
 
use Symfony\Component\EventDispatcher\Event; 
 
/** 
 * Event class to be dispatched from the HelloWorldSalutation service. 
 */ 
class SalutationEvent extends Event { 
 
  const EVENT = 'hello_world.salutation_event'; 
 
  /** 
   * The salutation message. 
   * 
   * @var string 
   */ 
  protected $message; 
 
  /** 
   * @return mixed 
   */ 
  public function getValue() { 
    return $this->message; 
  } 
 
  /** 
   * @param mixed $message 
   */ 
  public function setValue($message) { 
    $this->message = $message; 
  } 
}  

The main purpose of this event class is that an instance of it will be used to transport the value of our salutation message. This is why we created the $message property on the class and added the getter and setter methods. Moreover, we use it to define a constant for the actual name of the event that will be dispatched. Finally, the class extends from the base Event class that comes with the Event Dispatcher component as a standard practice. We could also use that class directly, but we would not have our data stored in it as we do now.

Next, it's time to inject the Event Dispatcher service into our HelloWorldSalutation service. We have already injected config.factory, so we just need to add a new argument to the service definition:

arguments: ['@config.factory', '@event_dispatcher'] 

Of course, we will also receive it in the constructor and store it as a class property:

/** 
 * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface 
 */ 
protected $eventDispatcher; 
 
/** 
 * HelloWorldSalutation constructor. 
 * 
 * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory 
 * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $eventDispatcher 
 */ 
public function __construct(ConfigFactoryInterface $config_factory, EventDispatcherInterface $eventDispatcher) { 
  $this->configFactory = $config_factory; 
  $this->eventDispatcher = $eventDispatcher; 
} 

We will also have the obligatory use statement for the EventDispatcherInterface at the top of the file:

use Symfony\Component\EventDispatcher\EventDispatcherInterface;  

Now, we can make use of the dispatcher. So instead of the following code inside the getSalutation() method:

if ($salutation != "") { 
  return $salutation; 
}  

We can have the following:

if ($salutation != "") { 
  $event = new SalutationEvent(); 
  $event->setValue($salutation); 
  $event = $this->eventDispatcher->dispatch(SalutationEvent::EVENT, $event); 
  return $event->getValue(); 
}

So with the above, we decided that if we are to return a salutation message from the configuration object, we want to inform other modules and allow them to change it. We first create an instance of our Event class and feed it the relevant data (the message). Then, we dispatch the named event and pass the event object along with it. The Event Dispatcher returns the event that has been dispatched with any changes that might have been applied to it by subscribers. Finally, we get the data from that instance and return it.

Pretty simple, isn't it? What can subscribers do? It's very similar to what we saw regarding the example on redirects in the preceding section. All a subscriber needs to do is listen for the SalutationEvent::EVENT event and do something based on that. The main thing that it can do is use the setValue() method on the received event object to change the salutation message. It can also use the stopPropagation() method from the base Event class to inform the Event Dispatcher to no longer trigger other listeners that have subscribed to this event.

主站蜘蛛池模板: 伊宁县| 宜都市| 连州市| 桐梓县| 马边| 南陵县| 苏尼特左旗| 合作市| 牙克石市| 沈丘县| 中山市| 辽阳县| 十堰市| 蓬莱市| 津市市| 尼木县| 泰来县| 黎城县| 黄石市| 盐山县| 霍城县| 乐至县| 独山县| 资源县| 四川省| 修武县| 隆昌县| 汨罗市| 通化市| 沙雅县| 崇左市| 江山市| 禄劝| 库车县| 保亭| 大渡口区| 弋阳县| 微博| 越西县| 石景山区| 全椒县|