Scroll
          
        Տերմինների բառարանի մուտքի սահմանափակում Event Subscriber-ի միջոցով
Երբեմն անհրաժեշտ է կայքում ունենալ ֆիքսված, մշտական կատեգորիաներ, որոնք չպետք է պատահաբար փոփոխվեն։ Այս դեպքում կարող եք օգտագործել Event Subscriber-ով աշխատող սեփական կոդ։
Ավելացնենք նոր Event Subscriber դաս մեր custom մոդուլում։
drupalbook_custom.services.yml
services:  
  drupalbook_custom.tag_redirect_subscriber:
    class: Drupal\drupalbook_custom\EventSubscriber\TagRedirectSubscriber
    arguments:
      - '@entity_type.manager'
      - '@current_user'
    tags:
      - { name: event_subscriber }
Եվ ներառենք մեր Event Subscriber-ը հետևյալում՝ drupalbook_custom/src/EventSubscriber/TagRedirectSubscriber:
<?php
namespace Drupal\drupalbook_custom\EventSubscriber;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Routing\TrustedRedirectResponse;
use Drupal\Core\Session\AccountProxyInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
/**
 * Վերահղում է կատարում ոչ-адմինիստրատոր օգտվողներին Tag բառարանի ադմինիստրացիոն էջերից։
 *
 * Request մակարդակի subscriber-ը աշխատում է շուտ, ինչը թույլ է տալիս կարճել հարցումը
 * և վերադարձնել վերահղման պատասխան՝ մինչև ընտրած controller-ը գործարկվելը։
 */
class TagRedirectSubscriber implements EventSubscriberInterface {
  /**
   * entity-type manager ծառայությունը։
   *
   * Օգտագործվում է որպես օրինակային dependency; այս պահին պարտադիր չէ,
   * բայց ապագայում կարող է օգտակար լինել էակների բեռնավորման համար։
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected EntityTypeManagerInterface $entityTypeManager;
  /**
   * current user proxy ծառայությունը։
   *
   * Օգտագործվում է արագ դերերի ստուգման համար՝ ադմինիստրատորներին վերահղումից ազատելու նպատակով։
   *
   * @var \Drupal\Core\Session\AccountProxyInterface
   */
  protected AccountProxyInterface $currentUser;
  /**
   * Կոնստրուկտոր։
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   entity-type manager-ը։
   * @param \Drupal\Core\Session\AccountProxyInterface $current_user
   *   Ներկա հարցում իրականացնող օգտվողը։
   */
  public function __construct(
    EntityTypeManagerInterface $entity_type_manager,
    AccountProxyInterface $current_user,
  ) {
    $this->entityTypeManager = $entity_type_manager;
    $this->currentUser = $current_user;
  }
  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents(): array {
    // Priority 32 նշանակում է, որ route-ի պարամետրերը արդեն հասանելի են,
    // բայց controller-ը դեռ չի գործարկվել։
    return [
      KernelEvents::REQUEST => ['onKernelRequest', 32],
    ];
  }
  /**
   * Վերահղում է իրականացնում, երբ ոչ-ադմինիստրատորները փորձում են մուտք գործել Tag admin ուղիներ։
   *
   * @param \Symfony\Component\HttpKernel\Event\RequestEvent $event
   *   Kernel-ի event-ը, որը պարունակում է request-ը։
   */
  public function onKernelRequest(RequestEvent $event): void {
    // Կատարում է միայն հիմնական request-ների համար։
    if (!$event->isMainRequest()) {
      return;
    }
    // Թույլատրվում է ադմինիստրատորներին առանց վերահղման։
    if ($this->currentUser->hasRole('administrator')) {
      return;
    }
    $request = $event->getRequest();
    $route_name = $request->attributes->get('_route');
    // Վերահղման հասցեն բոլոր արգելված փորձերի համար։
    $redirect_to = 'https://drupalbook.org/admin/structure'
      . '/taxonomy/manage/tag/overview';
    switch ($route_name) {
      case 'entity.taxonomy_vocabulary.overview_form':
      case 'entity.taxonomy_vocabulary.overview_terms':
      case 'entity.taxonomy_term.add_form':
        // Ստուգում ենք, որ բառարանը "tag" է։
        $vocabulary = $request->attributes->get('taxonomy_vocabulary');
        if (!empty($vocabulary) && $vocabulary->id() === 'tag') {
          $event->setResponse(new TrustedRedirectResponse($redirect_to));
        }
        return;
      case 'entity.taxonomy_term.edit_form':
      case 'entity.taxonomy_term.delete_form':
        /** @var \Drupal\taxonomy\Entity\Term|null $term */
        $term = $request->attributes->get('taxonomy_term');
        // bundle() վերադարձնում է բառարանի մեքենայական անունը։
        if ($term && $term->bundle() === 'tag') {
          $event->setResponse(new TrustedRedirectResponse($redirect_to));
        }
        return;
      default:
        return;
    }
  }
}
TagRedirectSubscriber դասը Drupal-ի համար ստեղծված սեփական Event Subscriber է, որը նախատեսված է կոնկրետ տաքսոնոմիայի բառարանի (այս դեպքում՝ "tag") ադմինիստրացիոն էջերի հասանելիությունը սահմանափակելու համար ոչ-ադմինիստրատոր օգտվողների համար։ Ահա դրա կառուցվածքի և հիմնական արժեքավոր կետերի բաժանումը.
1. Նպատակն ու կիրառումը
- Նպատակ. Կանխել պատահական կամ չարտոնված փոփոխությունները "tag" բառարանում՝ վերահղելով ոչ-ադմինիստրատոր օգտվողներին admin ուղիներից։
- Օգտակարություն. UI/UX մակարդակում մուտքի լրացուցիչ հսկողություն՝ ապահովելու համար ֆիքսված կատեգորիաների կայունությունը։
2. Դասի կառուցվածքը և dependency-ները
- Դասը implement է անում EventSubscriberInterface-ը, ինչը համատեղելի է դարձնում այն Symfony-ի event համակարգի հետ, որը օգտագործում է Drupal-ը։
- Dependency-ներ՝ constructor-ի միջոցով.
	- EntityTypeManagerInterface՝ ներառված է ապագա էակների հետ աշխատանքների համար։ Այս պահին պարտադիր չէ, բայց ապահովում է հեշտ ընդլայնելիություն։
- AccountProxyInterface՝ օգտագործվում է օգտվողի դերերի արագ ստուգման համար։
 
3. Բաժանորդագրվող իրադարձություններ
- Դասը բաժանորդագրվում է KernelEvents::REQUESTիրադարձությանը՝ 32 priorytet-ով.
 Այս priorytet-ը ապահովում է՝- Route-ի պարամետրերը արդեն հասանելի են (routing-ը լուծված է)։
- Route-ի համար controller-ը դեռ չի գործարկվել, ինչը հնարավորություն է տալիսsubscriber-ին միջամտել և կարճել հարցումը վերահղմամբ։
 
4. Վերահղման տրամաբանություն
- onKernelRequest()մեթոդը իրականացնում է բոլոր մուտքի ստուգումներն ու վերահղումը՝- Գործում է միայն հիմնական հարցումներում. Կրկնակի մշակման կանխարգելում։
- Թույլ է տալիս ադմինիստրատորներին. Եթե օգտվողն ունի administratorդեր, մուտքը միշտ թույլատրված է։
- Ստուգում է ուղու անունները. Միայն որոշ կոնկրետ տաքսոնոմիա և տերմինների ուղիներ են համարվում։
- Վերահղում է ոչ-ադմիններին.
		- Overview, add կամ list ուղիների համար (entity.taxonomy_vocabulary.overview_form,entity.taxonomy_vocabulary.overview_terms,entity.taxonomy_term.add_form) ստուգվում է, որ բառարանըtagէ։
- Խմբագրման և ջնջման ուղիների համար (entity.taxonomy_term.edit_form,entity.taxonomy_term.delete_form) ստուգվում է, որ տերմինիbundle()-ը (բառարանի մեքենայական անունը)tagէ։
 
- Overview, add կամ list ուղիների համար (
- Օգտագործում է trusted redirect. Եթե պայմանները համընկնում են, օգտվողը վերահղվում է "tag" բառարանի անվտանգ admin overview էջ։
 
- Ընդլայնելիություն. Տրամաբանությունը հեշտությամբ կարող է ընդլայնվել այլ բառարանների կամ դերերի համար՝ պայմանները փոփոխելով։
5. Անվտանգություն և լավագույն պրակտիկաներ
- Վաղ միջամտություն. Request event-ում աշխատելով՝ subscriber-ը կարող է մուտքը վերահսկել մինչև որևէ կարևոր տվյալ մշակվի կամ ցուցադրվի։
- Դերերի հիման վրա բացառություն. Արագ ստուգում է օգտվողի դերերը՝ site builder-ներին կամ ադմիններին չարգելափակելու համար։
- Հստակ բաժանում. Routing տրամաբանությունը, օգտվողի ստուգումները և վերահղումը մաքուր են առանձնացված՝ հեշտ սպասարկելիության համար։
6. Հնարավոր զարգացումներ
- Քանի որ EntityTypeManagerInterface-ը ներարկված է, կարող եք հեշտությամբ ավելացնել էակային հիմնված ստուգումներ (օրինակ՝ թերմի հատուկ հատկությունների կամ կապված բովանդակության հիման վրա թույլտվություններ)։
- Կարող եք ընդհանրացնել դասը՝ մի քանի բառարանների համար, կամ թույլատրել կոնֆիգուրացիայով վերահղման հասցեները։
7. Հիմնական եզրակացություններ
- Այս Event Subscriber-ը ցույց է տալիս մուտքի վերահսկման գործնական մոտեցում Drupal-ում՝ օգտագործելով Symfony-ի իրադարձություններով կառավարվող ճարտարապետությունը՝ վաղ և արդյունավետ հարցման մշակման համար։
- Այս մեթոդը հարմար է այն տաքսոնոմիա բառարանների պաշտպանության համար, որոնք պետք է կառավարվեն միայն վստահելի օգտվողների կողմից՝ նվազեցնելով պատահական փոփոխությունների ռիսկը։