logo

Լրացուցիչ Բլոկների Տեսակներ (EBT) - Դասավորության Կառուցողի նոր փորձառություն❗

Լրացուցիչ Բլոկների Տեսակներ (EBT) - ձևավորված, կարգավորելի բլոկների տեսակներ՝ սլայդշոուներ, ներդիրներ, քարտեր, բացվող ցանկեր և շատ ուրիշներ։ Ներառված կարգավորումներ՝ ֆոնի, DOM տուփի, JavaScript փլագինների համար։ Փորձեք դասավորությունների կառուցման ապագան արդեն այսօր։

EBT մոդուլների ցուցադրական տարբերակներ Ներբեռնել EBT մոդուլները

❗Լրացուցիչ Պարբերությունների Տեսակներ (EPT) - Պարբերությունների նոր փորձառություն

Լրացուցիչ պարբերության տեսակներ (EPT) - անալոգիական պարբերության վրա հիմնված մոդուլների հավաքակազմ։

EPT մոդուլների ցուցադրական տարբերակներ Ներբեռնել EPT մոդուլները

Scroll

Event Subscriber և Event Dispatcher։ Drupal-ում իրադարձությունների հետ աշխատելու համակարգ։

20/06/2025, by Ivan

Իրադարձությունների համակարգերի ակնարկ

Իրադարձությունների համակարգերը օգտագործվում են բազմաթիվ բարդ ծրագրերում՝ որպես միջոց ընդլայնումներին թույլ տալու համակարգի աշխատանքը փոխելու համար։ Իրադարձությունների համակարգը կարող է իրականացնել տարբեր կերպ, բայց ընդհանուր առմամբ համակարգի բաղադրիչները և հասկացությունները նույնն են։

  • Իրադարձությունների բաժանորդներ (Event Subscribers) - երբեմն կոչվում են «լսողներ», դրանք կանչվող մեթոդներ կամ ֆունկցիաներ են, որոնք արձագանքում են իրադարձությանը, որը տարածվում է ամբողջ իրադարձությունների գրանցամատյանով։
  • Իրադարձությունների գրանցամատյան (Event Registry) - այն տեղը, որտեղ հավաքվում և դասակարգվում են իրադարձությունների բաժանորդները։
  • Իրադարձությունների դիսպետչեր (Event Dispatcher) - մեխանիզմ, որով իրադարձությունը սկսվում է կամ «հաղորդվում» է համակարգի ողջ տարածքում։
  • Իրադարձության կոնտեքստ (Event Context) - շատ իրադարձությունների համար պահանջվում է տվյալների որոշակի հավաքածու, որը կարևոր է իրադարձության բաժանորդների համար։ Դա կարող է լինել պարզ արժեք, որը փոխանցվում է բաժանորդին, կամ բարդ՝ օրինակ հատուկ ստեղծված դաս, որը պարունակում է համապատասխան տվյալներ։

Drupal հուքեր (Hooks)

Drupal-ի մեծ մասի գոյության ընթացքում համակարգում եղել է հենքերի (hooks) պարզ համակարգ իրադարձությունների համար։ Եկեք դիտարկենք, թե ինչպես «հուք»-ի հասկացությունը բաժանվում է այս 4 իրադարձությունների համակարգի տարրերին։

  • Իրադարձությունների բաժանորդներ - Drupal հուքերը գրանցվում են համակարգում՝ որոշելով ֆունկցիա հատուկ անունով։ Օրինակ, եթե ցանկանում եք բաժանորդագրվել "hook_my_event_name" պատրաստված իրադարձությանը, պետք է սահմանեք նոր ֆունկցիա՝ myprefix_my_event_name(), որտեղ "myprefix"-ը ձեր մոդուլի կամ թեմայի անունն է։
  • Իրադարձությունների գրանցամատյան - Drupal հուքերը պահվում են «cache_bootstrap» կեշի մեջ՝ «module_implements» ID-ով։ Սա պարզապես զանգված է, որը պարունակում է մոդուլները, որոնք իրականացնում են տվյալ հուքը՝ նշված այդ հուքի անունով։
  • Իրադարձությունների դիսպետչեր - հուքերը տարբեր կերպ են ուղարկվում Drupal 7-ում և Drupal 8-ում․

                  1) Drupal 7-ում՝ հուքերը ուղարկվում են module_invoke_all() ֆունկցիայով։
                  2) Drupal 8-ում՝ հուքերը ուղարկվում են \Drupal::moduleHandler()->invokeAll() ծառայության մեթոդով։

  • Իրադարձության կոնտեքստ - կոնտեքստը փոխանցվում է բաժանորդին որպես պարամետրեր։ Օրինակ՝ այս դիսպետչերը կկատարի բոլոր «hook_my_event_name» իրագործումները և կփոխանցի $some_arbitrary_parameter պարամետրը․

                  1) Drupal 7-ում՝ module_invoke_all('my_event_name', $some_arbitrary_parameter);
                  2) Drupal 8-ում՝ \Drupal::moduleHandler()->invokeAll('my_event_name', [$some_arbitrary_parameter]);

«Հուք»-երի մոտեցման որոշ թերություններ՝

  • Իրադարձությունները գրանցվում են միայն կեշի վերակառուցման ժամանակ։

Ընդհանուր առմամբ Drupal-ը որոնում է նոր հուքեր միայն որոշակի կեշերի կառուցման ժամանակ։ Սա նշանակում է, որ եթե ցանկանում եք ձեր կայքում իրականացնել նոր հուք, ստիպված կլինեք վերակառուցել համապատասխան կեշերը՝ կախված ձեր հուքի տեսակից։

  • Յուրաքանչյուր իրադարձության համար կարող է արձագանքել միայն մեկ անգամ յուրաքանչյուր մոդուլ։

Քանի որ այդ իրադարձությունները իրականացվում են հատուկ անուններով ֆունկցիաներ սահմանելով, յուրաքանչյուր մոդուլ կամ թեմա կարող է ունենալ միայն մեկ իրագործում այդ իրադարձության համար։ Սա պատահական սահմանափակում է՝ համեմատած մյուս իրադարձությունների համակարգերի հետ։

  • Չի կարելի հեշտությամբ որոշել իրադարձությունների հերթականությունը։

Drupal-ը իրադարձությունների բաժանորդների հերթականությունը որոշում է մոդուլների քաշերի միջոցով, որոնք որոշում են մոդուլների բեռնման կարգը և, հետևաբար, իրադարձությունների կատարումը։ Այս խնդիրը վերացնելու համար Drupal 7-ում ավելացվեց «hook_module_implements_alter» հուք, որը հնարավորություն է տալիս փոխել հուքերի կատարումը առանց մոդուլի քաշը փոխելու։

Symfony-ի հիմքով Drupal 8-ում կա նոր իրադարձությունների համակարգ։ Լավ համակարգ, որը մեծ մասամբ ավելի լավ է, քան հուքերը։ Չնայած Drupal 8-ի հիմնական համակարգում շատ իրադարձություններ չեն ուղարկվում, բայց շատ մոդուլներ սկսեցին օգտագործել այս համակարգը։

Drupal 8-ի իրադարձություններ

Drupal 8-ի իրադարձությունները շատ նման են Symfony-ի իրադարձություններին։ Եկեք տեսնենք, թե ինչպես է դա բաժանվում մեր համակարգի բաղադրիչներին։

  • Իրադարձությունների բաժանորդներ - դաս, որը իրականացնում է \Symfony\Component\EventDispatcher\EventSubscriberInterface։
  • Իրադարձությունների դիսպետչեր - դաս, որը իրականացնում է \Symfony\Component\EventDispatcher\EventDispatcherInterface։ Դիսպետչերի առնվազն մեկ օրինակ սովորաբար մատչելի է որպես ծառայություն համակարգում, սակայն կարող են ստեղծվել նաև այլ դիսպետչերներ։
  • Իրադարձությունների գրանցամատյան - բաժանորդների գրանցումն արվում է դիսպետչերի օբյեկտում որպես զանգված, որը պարունակում է իրադարձության անունը և իրադարձության առաջնահերթությունը (կատարման հերթականությունը)։ Իրադարձությունը ծառայություն գրանցելիս գրանցվում է գլոբալ դիսպետչերում։
  • Իրադարձության կոնտեքստ - դաս, որը ընդլայնում է \Symfony\Component\EventDispatcher\Event դասը։ Յուրաքանչյուր ընդլայնում, որը ուղարկում է իրադարձություն, ստեղծում է իր հատուկ Event դասը, որը պարունակում է բաժանորդների անհրաժեշտ տվյալները։

Drupal 8-ի իրադարձությունների օգտագործումը կօգնի ձեզ ավելի լավ հասկանալ մոդուլային զարգացման գործընթացը և կպատրաստի ձեզ ապագայի համար, որտեղ իրադարձությունները (հույս ունենք) կփոխարինեն հուքերին։ Եկեք ստեղծենք օգտագործողի մոդուլ, որը ցույց կտա, թե ինչպես օգտագործել իրադարձությունների բոլոր բաղադրիչները Drupal 8-ում։

Իմ առաջին Drupal 8-ի իրադարձությունների բաժանորդը

Սկսենք ստեղծելով մեր առաջին իրադարձությունների բաժանորդը Drupal 8-ում՝ օգտագործելով պարզ հիմնական իրադարձություններ։ Ինձ անձամբ դուր է գալիս սկսել շատ պարզ բաներով, այդ պատճառով կստեղծենք իրադարձության բաժանորդ, որը ցույց կտա օգտվողին հաղորդագրություն, երբ Config օբյեկտը պահպանվի կամ ջնջվի։

Առաջին անհրաժեշտ բանն է մոդուլ, որտեղ մենք դա կանենք։ Ես անվանել եմ այն custom_events։

name: Custom Events
type: module
description: Custom/Example event work.
core: 8.x
package: Custom

Հաջորդ քայլը՝ գրանցել նոր իրադարձությունների բաժանորդը Drupal-ում։ Այս համար պետք է ստեղծենք custom_events.services.yml։ Եթե դուք գալիս եք Drupal 7-ից և ծանոթ եք հուքերի համակարգին, կարող եք այս քայլը համեմատել «hook_my_event_name» ֆունկցիայի ստեղծման հետ ձեր մոդուլում կամ թեմայում։

services:
  # Այս ծառայության անունը։
  my_config_events_subscriber:
    # Իրադարձությունների բաժանորդ դաս, որը կլսի իրադարձությունները։
    class: '\Drupal\custom_events\EventSubscriber\ConfigEventsSubscriber'
    # Թեգավորված է որպես event_subscriber՝ բաժանորդի գրանցման համար event_dispatch ծառայությունում։
    tags:
      - { name: 'event_subscriber' }

Սա բավական պարզ է, բայց բացատրենք մի փոքր։

1) Գտնում ենք նոր ծառայություն՝ "my_config_events_subscriber" անունով։
2) Սահմանում ենք դրա "class" հատկությունը՝ նոր PHP դասի գլոբալ անունը, որը մենք կստեղծենք։
3) Սահմանում ենք «tags» հատկությունը՝ տալով «event_subscriber» նշում, որով ծառայությունը գրանցվում է որպես իրադարձությունների բաժանորդ։

Փոխարենը կարող եք օգտագործել PHP իրադարձությունների բաժանորդ դասի անունը (առանց նախակոսակի) որպես ծառայության անուն և անտեսել «class» հատկությունը, օրինակ՝

services:
  # Ծառայության անունը՝ օգտագործելով իրադարձությունների բաժանորդ դասը։
  Drupal\custom_events\EventSubscriber\ConfigEventsSubscriber:
    tags:
      - { name: 'event_subscriber' }

Հիմա մնացել է գրել իրադարձությունների բաժանորդ դասը։ Այս դասին մի քանի պահանջ կա՝

1. Պետք է իրականացնի EventSubscriberInterface։
2. Պետք է ունենա getSubscribedEvents() մեթոդ, որը վերադարձնում է զանգված, որտեղ բանալիքն իրադարձության անունն է, իսկ արժեքը՝ բաժանորդի մեթոդի անունը։

Ահա մեր բաժանորդների դասը․ այն բաժանորդագրվում է ConfigEvents դասի իրադարձություններին և կատարում տեղական մեթոդը յուրաքանչյուր իրադարձության համար։

src/EventSubscriber/ConfigEventsSubscriber.php
<?php

namespace Drupal\custom_events\EventSubscriber;

use Drupal\Core\Config\ConfigCrudEvent;
use Drupal\Core\Config\ConfigEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Class ConfigEventsSubscriber.
 *
 * @package Drupal\custom_events\EventSubscriber
 */
class ConfigEventsSubscriber implements EventSubscriberInterface {

  /**
   * {@inheritdoc}
   *
   * @return array
   *   Իրադարձությունների անունները և դրանց հետ կապված մեթոդները։
   */
  public static function getSubscribedEvents() {
    return [
      ConfigEvents::SAVE => 'configSave',
      ConfigEvents::DELETE => 'configDelete',
    ];
  }

  /**
   * Արտադրվում է, երբ config օբյեկտը պահպանվում է։
   *
   * @param \Drupal\Core\Config\ConfigCrudEvent $event
   *   Config CRUD իրադարձություն։
   */
  public function configSave(ConfigCrudEvent $event) {
    $config = $event->getConfig();
    \Drupal::messenger()->addStatus('Պահպանված կոնֆիգը՝ ' . $config->getName());
  }

  /**
   * Արտադրվում է, երբ config օբյեկտը ջնջվում է։
   *
   * @param \Drupal\Core\Config\ConfigCrudEvent $event
   *   Config CRUD իրադարձություն։
   */
  public function configDelete(ConfigCrudEvent $event) {
    $config = $event->getConfig();
    \Drupal::messenger()->addStatus('Ջնջված կոնֆիգը՝ ' . $config->getName());
  }

}

Սա ամեն ինչ է։ Սա բավական պարզ է թվում, բայց եկեք նկատենք կարևոր բաներ․

  • Մենք իրականացնում ենք EventSubscriberInterface դասը։
  • Մենք իրականացնում ենք getSubscribedEvents() մեթոդը, որը վերադարձնում է իրադարձությունների անուններ՝ մեթոդների անուններով։
  • Երկու մեթոդները՝ configSave() և configDelete(), ստանում են ConfigCrudEvent օբյեկտ, որը ունի getConfig() մեթոդ՝ կոնֆիգ օբյեկտը վերադարձնելու համար։

Որոշ հարցեր, որոնք կարող են առաջանալ.

  • Ինչ է ConfigEvents::SAVE և որտեղից է դա վերցված։

Սովորաբար նոր իրադարձություններ սահմանելիս ստեղծում են գլոբալ կոնստանտ, որի արժեքը իրադարձության անունն է։ Այս դեպքում \Drupal\Core\Config\ConfigEvents ունի SAVE կոնստանտ՝ արժեքով «config.save»։

  • Ինչու սպասում էինք ConfigCrudEvent օբյեկտ, և ինչպես գիտենք դա։

Նոր իրադարձություններ սահմանելիս սովորաբար ստեղծվում է հատուկ իրադարձության օբյեկտի տեսակ, որը պարունակում է անհրաժեշտ տվյալները և պարզ API տրամադրում դրանց համար։ Այս պահին մենք լավագույնս կարող ենք որոշել սպասվող իրադարձության օբյեկտը՝ ուսումնասիրելով կոդը և API-ի հրապարակված փաստաթղթերը։

Կարծում եմ՝ մենք պատրաստ ենք միացնել մոդուլն ու փորձարկել իրադարձությունը։ Մենք սպասում ենք, որ երբեք որ config օբյեկտ պահպանվի կամ ջնջվի Drupal-ում, կտեսնենք հաղորդագրություն, որը պարունակում է կոնֆիգ օբյեկտի անունը։

Քանի որ config օբյեկտները շատ տարածված են Drupal 8-ում, սա բավական հեշտ է փորձարկելու համար։ Մոտավոր բոլոր մոդուլները կառավարվում են կոնֆիգ օբյեկտներով, ուստի կարող ենք պարզապես տեղադրել և հեռացնել մոդուլ և դիտել, թե ինչ կոնֆիգ օբյեկտներ են պահպանվում և ջնջվում։

1. Տեղադրեք "custom_events" մոդուլը։
2. Տեղադրեք "statistics" մոդուլը։

events-1-installed

Հաղորդագրություն՝ "statistics" մոդուլը տեղադրելուց հետո։

Պատկանում է, որ երկու կոնֆիգ օբյեկտներ պահպանվել են։ Առաջինը՝ core.extension, որը կառավարում է տեղադրված մոդուլներն ու թեմաները։ Երկրորդը՝ statistics.settings կոնֆիգ օբյեկտը։

3. Հեռացրեք "statistics" մոդուլը։

events-2-uninstalled

Հաղորդագրություն՝ "statistics" մոդուլը հեռացնելուց հետո։

Այս անգամ տեսնում ենք և SAVE, և DELETE իրադարձությունները։ Տեսնում ենք, որ statistics.settings կոնֆիգը ջնջվել է, իսկ core.extension կոնֆիգը պահպանվել։

Սա հաջողություն է։ Մենք հաջողությամբ բաժանորդագրվել ենք Drupal-ի երկու հիմնական իրադարձություններին։

Հիմա եկեք տեսնենք, ինչպես ստեղծել սեփական իրադարձություններ և ուղարկել դրանք մյուս մոդուլների համար։

Իմ առաջին Drupal 8-ի իրադարձությունը և իրադարձությունների ուղարկումը

Առաջին հարցը՝ ինչ տեսակի իրադարձություն ենք ուղարկելու և երբ։ Մենք պատրաստվում ենք ստեղծել իրադարձություն Drupal-ի այն հուքի համար, որն ունի "hook_user_login" անունը, բայց ядքում իրադարձություն չունի։

Սկսենք նոր դաս ստեղծելով, որը ընդլայնում է Event դասը՝ անվանենք այն UserLoginEvent։ Կամենայնդեպս սահմանենք գլոբալ անուն իրադարձության համար բաժանորդների համար։

src/Event/UserLoginEvent.php
<?php

namespace Drupal\custom_events\Event;

use Drupal\user\UserInterface;
use Symfony\Component\EventDispatcher\Event;

/**
 * Իրադարձություն, որը ակտիվանում է օգտվողի մուտքի ժամանակ։
 */
class UserLoginEvent extends Event {

  const EVENT_NAME = 'custom_events_user_login';

  /**
   * Օգտագործողի հաշիվը։
   *
   * @var \Drupal\user\UserInterface
   */
  public $account;

  /**
   * Կառուցում։
   *
   * @param \Drupal\user\UserInterface $account
   *   Մուտք գործած օգտվողի հաշիվը։
   */
  public function __construct(UserInterface $account) {
    $this->account = $account;
  }

}
  • UserLoginEvent::EVENT_NAME-ը կոնստանտ է՝ արժեքով «custom_events_user_login», որը մեր նոր իրադարձության անունն է։
  • Կոնստրուկտորը սպասում է UserInterface օբյեկտ, որը պահում է իրադարձության $account հատկությունը։ Սա կթույլ տա բաժանորդներին օգտագործել $account օբյեկտը։

Դա էլ ավարտը։

Հիմա պարզապես պետք է ուղարկենք մեր նոր իրադարձությունը։ Մենք կվերագրանցենք այն "hook_user_login" ժամանակ։ Սկսենք ստեղծելով custom_events.module ֆայլը։

<?php

/**
 * @file
 * Կատառում է custom_events.module։
 */

use Drupal\custom_events\Event\UserLoginEvent;

/**
 * Կատարվում է hook_user_login().
 */
function custom_events_user_login($account) {
  // Իրադարձության օբյեկտը ստեղծում ենք։
  $event = new UserLoginEvent($account);

  // Ստանում ենք event_dispatcher ծառայությունը և ուղարկում իրադարձությունը։
  $event_dispatcher = \Drupal::service('event_dispatcher');
  $event_dispatcher->dispatch(UserLoginEvent::EVENT_NAME, $event);
}

Մեր "hook_user_login" իրականացման մեջ պետք է կատարել հետևյալը՝

1. Ստեղծել UserLoginEvent նոր իրադարձության օբյեկտ և փոխանցել կոնստրուկտորին $account օբյեկտը։
2. Ստանալ event_dispatcher ծառայությունը։
3. Կատարել dispatch() մեթոդը՝ փոխանցելով իրադարձության անունը և իրադարձության օբյեկտը։

Սա էլ վերջն է։ Հիմա մեր նոր իրադարձությունը ուղարկվում է, երբ օգտվողը մուտք է գործում Drupal։

Հաջորդը՝ լրացնելու ենք մեր օրինակն, ստեղծելով բաժանորդ նոր իրադարձության համար։ Նախ պետք է թարմացնենք services.yml ֆայլը՝ ընդգրկելով նոր բաժանորդին։

services:
  # Ծառայության անունը։
  my_config_events_subscriber:
    class: '\Drupal\custom_events\EventSubscriber\ConfigEventsSubscriber'
    tags:
      - { name: 'event_subscriber' }

  # Բաժանորդ, որը կլսի hook_user_login-ում ուղարկվող իրադարձությունը։
  custom_events_user_login:
    class: '\Drupal\custom_events\EventSubscriber\UserLoginSubscriber'
    tags:
      - { name: 'event_subscriber' }

Ինչպես նախկինում, սահմանում ենք նոր ծառայություն և նշում՝ որպես event_subscriber։ Հիմա պետք է գրենք այս EventSubscriber դասը։

src/EventSubscriber/UserLoginSubscriber.php
<?php

namespace Drupal\custom_events\EventSubscriber;

use Drupal\custom_events\Event\UserLoginEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Class UserLoginSubscriber.
 *
 * @package Drupal\custom_events\EventSubscriber
 */
class UserLoginSubscriber implements EventSubscriberInterface {

  /**
   * Տվյալների բազայի կապը։
   *
   * @var \Drupal\Core\Database\Connection
   */
  protected $database;

  /**
   * Ամսաթվի ձևաչափիչ։
   *
   * @var \Drupal\Core\Datetime\DateFormatterInterface
   */
  protected $dateFormatter;

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    return [
      // Կլասսի σταատիկ կոնստանտը => այս կլասսի մեթոդը։
      UserLoginEvent::EVENT_NAME => 'onUserLogin',
    ];
  }

  /**
   * Բաժանորդագրվում է օգտվողի մուտքի իրադարձությանը։
   *
   * @param \Drupal\custom_events\Event\UserLoginEvent $event
   *   Իրադարձության օբյեկտ։
   */
  public function onUserLogin(UserLoginEvent $event) {
    $database = \Drupal::database();
    $dateFormatter = \Drupal::service('date.formatter');

    $account_created = $database->select('users_field_data', 'ud')
      ->fields('ud', ['created'])
      ->condition('ud.uid', $event->account->id())
      ->execute()
      ->fetchField();

    \Drupal::messenger()->addStatus(t('Բարի գալուստ, ձեր հաշիվը ստեղծվել է %created_date։', [
      '%created_date' => $dateFormatter->format($account_created, 'short'),
    ]));
  }

}

Բացատրություն՝

1. Մենք բաժանորդագրվում ենք UserLoginEvent::EVENT_NAME իրադարձությանը՝ օգտագործելով onUserLogin() մեթոդը։
2. onUserLogin() ընթացքում օգտվում ենք $event->account հատկությունից՝ օգտվողին ներկայացնելու համար։
3. Օգտվողը մուտք գործելիս կտեսնի հաղորդագրություն՝ նշելով հաշվի ստեղծման ամսաթիվը։

events-3-login

Մուտքի ժամանակ հաղորդագրությունը։

Voila! Մենք ուղարկել և բաժանորդագրվել ենք նոր իրադարձությանը։ Մենք հիանալի ենք դրանում։

Իրադարձությունների բաժանորդների առաջնահերթություններ

Իրադարձությունների համակարգի մեկ այլ հիանալի հատկությունն է, որ բաժանորդները կարող են սահմանել իրենց առաջնահերթությունը բաժանորդի ներսում՝ փոխարեն մոդուլի քաշը փոխելու կամ հուք օգտագործելու առաջնահերթությունը փոխելու համար (ինչպես հուքերի դեպքում)։

Սա շատ պարզ է իրականացնել, բայց դրա լավագույն ցուցադրությունը կլինի նոր բաժանորդ գրելը, երբ արդեն ունենք բաժանորդ։ Եկեք գրենք «AnotherConfigEventSubscriber» և սահմանենք նրա լսողների առաջնահերթությունները։

Նախ գրանցենք մեր նոր բաժանորդը services.yml-ում՝

services:
  # Ծառայության անունը։
  my_config_events_subscriber:
    class: '\Drupal\custom_events\EventSubscriber\ConfigEventsSubscriber'
    tags:
      - { name: 'event_subscriber' }

  # Բաժանորդ hook_user_login-ում ուղարկվող իրադարձությանը։
  custom_events_user_login:
    class: '\Drupal\custom_events\EventSubscriber\UserLoginSubscriber'
    tags:
      - { name: 'event_subscriber' }

  another_config_events_subscriber:
    class: '\Drupal\custom_events\EventSubscriber\AnotherConfigEventsSubscriber'
    tags:
      - { name: 'event_subscriber' }

Հետո կգրենք AnotherConfigEventSubscriber.php-ը՝

<?php

namespace Drupal\custom_events\EventSubscriber;

use Drupal\Core\Config\ConfigCrudEvent;
use Drupal\Core\Config\ConfigEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Class AnotherConfigEventsSubscriber.
 *
 * @package Drupal\custom_events\EventSubscriber
 */
class AnotherConfigEventsSubscriber implements EventSubscriberInterface {

  /**
   * {@inheritdoc}
   *
   * @return array
   *   Իրադարձությունների անունները և դրանց հետ կապված մեթոդները՝ առաջնահերթություններով։
   */
  public static function getSubscribedEvents() {
    return [
      ConfigEvents::SAVE => ['configSave', 100],
      ConfigEvents::DELETE => ['configDelete', -100],
    ];
  }

  /**
   * Արտադրվում է, երբ config օբյեկտը պահպանվում է։
   *
   * @param \Drupal\Core\Config\ConfigCrudEvent $event
   *   Config CRUD իրադարձություն։
   */
  public function configSave(ConfigCrudEvent $event) {
    $config = $event->getConfig();
    \Drupal::messenger()->addStatus('(Մյուս) Պահպանված կոնֆիգը՝ ' . $config->getName());
  }

  /**
   * Արտադրվում է, երբ config օբյեկտը ջնջվում է։
   *
   * @param \Drupal\Core\Config\ConfigCrudEvent $event
   *   Config CRUD իրադարձություն։
   */
  public function configDelete(ConfigCrudEvent $event) {
    $config = $event->getConfig();
    \Drupal::messenger()->addStatus('(Մյուս) Ջնջված կոնֆիգը՝ ' . $config->getName());
  }

}

Գլխավոր տարբերությունը, որ մենք փոխեցինք getSubscribedEvents() մեթոդի վերադարձվող զանգվածը։ Այժմ ի տեղը պարզապես մեթոդի անուն ունենալու, զանգվածն ունի առաջին էլեմենտը մեթոդի անունը, իսկ երկրորդը՝ այդ լսողի առաջնահերթությունը։

Այնպես, փոխեցինք.

public static function getSubscribedEvents() {
  return [
    ConfigEvents::SAVE => 'configSave',
    ConfigEvents::DELETE => 'configDelete',
  ];
}

Այսպիսով՝ այն դարձավ՝

public static function getSubscribedEvents() {
  return [
    ConfigEvents::SAVE => ['configSave', 100],
    ConfigEvents::DELETE => ['configDelete', -100],
  ];
}

Որին մենք սպասում ենք՝

  • AnotherConfigEventSubscriber::configSave() ունի բարձր առաջնահերթություն, ուստի կկատարվի ConfigEventsSubscriber::configSave()-ից առաջ։
  • AnotherConfigEventSubscriber::configDelete() ունի ցածր առաջնահերթություն, ուստի կկատարվի ConfigEventsSubscriber::configDelete()-ից հետո։

Դիտարկենք SAVE իրադարձությունը, կրկին ակտիվացնելով statistics մոդուլը։

events-4-installed-priorities

Statistics մոդուլի տեղադրում և հաղորդագրությունների դիտում։

Հիանալի է։ Մեր նոր իրադարձությունների լսողը ConfigEvents::SAVE-ի համար կատարվել է մեր նախորդից առաջ։ Հիմա հեռացնենք statistics մոդուլը և նայենք DELETE իրադարձությանը։

events-5-uninstalled-priorities

Statistics մոդուլի հեռացում և հաղորդագրությունների դիտում։

Լավ է։ Մեր նոր լսողը ConfigEvents::DELETE-ի համար կատարվել է մեր նախորդից հետո, քանի որ ունի ցածր առաջնահերթություն։

Նշում. Եթե բաժանորդը գրանցվում է առանց առաջնահերթության, լռելյայն նշանակվում է 0։

Հղումներ՝

Drupal’s online documentation is © 2000-2020 by the individual contributors and can be used in accordance with the Creative Commons License, Attribution-ShareAlike 2.0. PHP code is distributed under the GNU General Public License.