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-ի իրադարձություններով կառավարվող ճարտարապետությունը՝ վաղ և արդյունավետ հարցման մշակման համար։
- Այս մեթոդը հարմար է այն տաքսոնոմիա բառարանների պաշտպանության համար, որոնք պետք է կառավարվեն միայն վստահելի օգտվողների կողմից՝ նվազեցնելով պատահական փոփոխությունների ռիսկը։