drupal菜鸟笔记之订阅和调度事件(路由监听、url监听)
需求: 某个按钮点击之后需要跳转至一个中转地址,但是中转地址没有页面,所有跳转到中转地址的请求直接定向跳转到指定页面。
参考:
官方文档:
https://www.drupal.org/docs/creating-custom-modules/subscribe-to-and-dispatch-events
实际案例:
1、 services.yml 添加如下代码
ixtend_user.user_registration:
class: Drupal\ixtend_user\EventSubscriber\RequestAccessSubscriber
tags:
- { name: event_subscriber }
第一行: 服务名,我这里是使用改事件的页面服务名,和routing.yml 一致。
第二行:使用事件订阅者的 PHP 类;该类在src/EventSubscriber下面。
第三行:“ tags ”属性,并提供了一个名为“event_subscriber”的标签。这就是服务在系统内注册为事件订阅者的方式。
这里遇到的坑:服务名称使用了一个不存在的服务;因此在使用drush. sh cr命令时报错:
[] operator not supported for strings
2、使用订阅事件的类:
该类必须继承EventSubscriberInterface;并实现 getSubscribedEvents 方法;该方法返回事件名称 => 方法名称键/值对的数组。
checkForRedirection 就是该类中实现自定义逻辑的方法。
第二个值100表示优先级;此值越高,链中的事件侦听器将越早触发
/**
* {@inheritdoc}
*
* @return array
* The event names to listen for, and the methods that should be executed.
*/
public static function getSubscribedEvents() {
$events[KernelEvents::REQUEST][] = ['checkForRedirection', 100];
return $events;
}
实现自定义逻辑的方法:
/**
* Request access check.
*
* @param \Symfony\Component\HttpKernel\Event\RequestEvent $event
* RequestEvent event.
*/
public function checkForRedirection(RequestEvent $event) {
$current_path = \Drupal::service('path.current')->getPath();
if ($current_path == '/ixtend') {
$url = Url::fromRoute('ixtend_user.user_login')->toString();
$response = new RedirectResponse($url, 301);
$event->setResponse($response);
}
}
使用订阅事件的类:
<?php
namespace Drupal\ixtend_user\EventSubscriber;
use Drupal\Core\Url;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
/**
* Event subscriber subscribing to request.
*/
class RequestAccessSubscriber implements EventSubscriberInterface {
/**
* Request access check.
*
* @param \Symfony\Component\HttpKernel\Event\RequestEvent $event
* RequestEvent event.
*/
public function checkForRedirection(RequestEvent $event) {
$current_path = \Drupal::service('path.current')->getPath();
if ($current_path == '/ixtend') {
$url = Url::fromRoute('ixtend_user.user_login')->toString();
$response = new RedirectResponse($url, 301);
$event->setResponse($response);
}
}
/**
* {@inheritdoc}
*
* @return array
* The event names to listen for, and the methods that should be executed.
*/
public static function getSubscribedEvents() {
$events[KernelEvents::REQUEST][] = ['checkForRedirection', 100];
return $events;
}
}