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

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.

主站蜘蛛池模板: 涟水县| 屏东市| 鸡西市| 通辽市| 宜章县| 甘谷县| 方山县| 如皋市| 福安市| 岑巩县| 乌苏市| 东乌珠穆沁旗| 北流市| 武强县| 宁武县| 凉城县| 历史| 清水河县| 福鼎市| 海盐县| 汝城县| 铅山县| 色达县| 仁布县| 西乡县| 麻栗坡县| 马关县| 莲花县| 阿巴嘎旗| 承德市| 苗栗市| 普安县| 济南市| 汽车| 石门县| 彰武县| 蒙自县| 吉林市| 合江县| 赤峰市| 双峰县|