logo

Dodatni tipovi blokova (EBT) - Novo iskustvo rada sa Layout Builder-om❗

Dodatni tipovi blokova (EBT) – stilizovani, prilagodljivi tipovi blokova: slajdšouvi, kartice sa tabovima, kartice, akordeoni i mnogi drugi. Ugrađena podešavanja za pozadinu, DOM Box, javascript dodatke. Iskusite budućnost kreiranja rasporeda već danas.

Demo EBT moduli Preuzmite EBT module

❗Dodatni tipovi pasusa (EPT) – Novo iskustvo rada sa pasusima

Dodatni tipovi pasusa (EPT) – analogni skup modula zasnovan na pasusima.

Demo EPT moduli Preuzmite EPT module

Scroll

Ograničite pristup vokabularu taksonomskih termina pomoću Event Subscriber-a

11/06/2025, by Ivan

Menu

Ponekad su vam potrebne fiksne, trajne kategorije na sajtu, koje ne bi trebalo slučajno ažurirati. U ovom slučaju možete koristiti sopstveni kod sa Event Subscriber-om.

Dodajmo novu klasu Event Subscriber-a u prilagođeni modul.

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 }

I uključujemo naš Event Subscriber u 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;

/**
 * Preusmerava ne-administratore sa administratorskih stranica Tag vokabulara.
 *
 * Subscriber na nivou Request-a se pokreće rano, što omogućava da se zahtev prekine
 * i vrati redirect odgovor pre nego što se izvrši odgovarajući kontroler.
 */
class TagRedirectSubscriber implements EventSubscriberInterface {

  /**
   * Servis za upravljanje tipovima entiteta.
   *
   * Ova zavisnost je ovde kao primer; nije striktno potrebna za trenutnu
   * logiku ali može biti korisna za buduća proširenja gde je potrebno učitavanje entiteta.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected EntityTypeManagerInterface $entityTypeManager;

  /**
   * Proxy servis za trenutnog korisnika.
   *
   * Koristi se za brzu proveru uloga korisnika kako bi se omogućio prolazak
   * administratorima.
   *
   * @var \Drupal\Core\Session\AccountProxyInterface
   */
  protected AccountProxyInterface $currentUser;

  /**
   * Konstruktor subscriber-a.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   Servis za tipove entiteta.
   * @param \Drupal\Core\Session\AccountProxyInterface $current_user
   *   Korisnik koji šalje zahtev.
   */
  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 {
    // Prioritet 32 osigurava da su parametri rute dostupni, ali se kontroler još nije izvršio.
    return [
      KernelEvents::REQUEST => ['onKernelRequest', 32],
    ];
  }

  /**
   * Preusmerava ne-administratore sa administratorskih ruta Tag vokabulara.
   *
   * @param \Symfony\Component\HttpKernel\Event\RequestEvent $event
   *   Kernel događaj sa zahtevom.
   */
  public function onKernelRequest(RequestEvent $event): void {
    // Radi samo na glavnim (master) zahtevima.
    if (!$event->isMainRequest()) {
      return;
    }

    // Administratori nisu preusmereni.
    if ($this->currentUser->hasRole('administrator')) {
      return;
    }

    $request = $event->getRequest();
    $route_name = $request->attributes->get('_route');

    // Destinacija za sve pokušaje koji su blokirani.
    $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':
        // Proveravamo da li se radi o "tag" vokabularu.
        $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() vraća mašinsko ime vokabulara.
        if ($term && $term->bundle() === 'tag') {
          $event->setResponse(new TrustedRedirectResponse($redirect_to));
        }
        return;

      default:
        return;
    }
  }

}

Klasa TagRedirectSubscriber je prilagođeni Event Subscriber za Drupal, namenjen ograničavanju pristupa administrativnim stranicama određenog taxonomy vokabulara (u ovom slučaju, „tag“) za ne-administratore. Evo pregleda njene strukture i ključnih aspekata u kodu:

1. Svrha i upotreba

  • Cilj: Sprečiti slučajne ili neautorizovane izmene „tag“ vokabulara preusmeravanjem ne-admin korisnika sa administratorskih ruta.
  • Prednost: Obezbeđuje dodatni sloj UI/UX kontrole pristupa za kritične taxonomy vokabulare, obezbeđujući stabilnost fiksnih kategorija.

2. Struktura klase i zavisnosti

  • Klasa implementira EventSubscriberInterface, što je čini kompatibilnom sa Symfony event sistemom koji koristi Drupal.
  • Zavisnosti se ubrizgavaju kroz konstruktor:
    • EntityTypeManagerInterface: Uključeno radi potencijalnih budućih operacija nad entitetima. Nije neophodno za trenutnu logiku, ali omogućava lako proširenje.
    • AccountProxyInterface: Koristi se za efikasno dobijanje i proveru uloga trenutnog korisnika.
    Dependency injection obezbeđuje da je subscriber testabilan, višekratno upotrebljiv i u skladu sa Drupal servis kontejner praksama.

3. Subscribovani događaji

  • Klasa se pretplaćuje na KernelEvents::REQUEST događaj sa prioritetom 32.
    Ovaj prioritet obezbeđuje:
    • Parametri rute su dostupni (routing je rešen).
    • Kontroler za rutu još NIJE izvršen, što omogućava subscriber-u da presretne i prekine zahtev redirect-om po potrebi.

4. Logika preusmeravanja

  • Metod onKernelRequest() sprovodi sve provere pristupa i logiku preusmeravanja:
    • Radi samo na glavnim zahtevima: Izbegava višestruko procesiranje kod pod-zahteva.
    • Dozvoljava administratore: Ako korisnik ima ulogu administrator, pristup je uvek dozvoljen.
    • Proverava imena ruta: Samo određene rute vezane za taxonomy vokabular ili njegove termine se obrađuju.
    • Preusmerava ne-admine:
      • Za overview, add ili list rute (entity.taxonomy_vocabulary.overview_form, entity.taxonomy_vocabulary.overview_terms, entity.taxonomy_term.add_form) proverava da li je vokabular tag.
      • Za edit i delete rute (entity.taxonomy_term.edit_form, entity.taxonomy_term.delete_form) proverava da li je bundle() termina tag.
    • Koristi trusted redirect: Ako su uslovi zadovoljeni, korisnik se preusmerava na sigurnu administratorsku stranicu pregleda za "tag" vokabular.
  • Mogućnost proširenja: Logika se lako može proširiti na dodatne vokabulare ili uloge jednostavnom izmenom uslova.

5. Bezbednost i najbolje prakse

  • Rano presretanje: Pokretanjem na request događaj, subscriber može da sprovede proveru pristupa pre nego što bilo koji osetljivi podaci budu procesirani ili prikazani.
  • Role-based bypass: Efikasno proverava uloge korisnika kako ne bi blokirao rad site buildera ili administratora.
  • Jasna separacija odgovornosti: Logika rutiranja, korisničke provere i preusmeravanja su jasno razdvojene radi održavanja.

6. Moguća poboljšanja

  • Pošto je EntityTypeManagerInterface ubrizgan, lako možete dodati provere bazirane na entitetima u budućnosti (npr. dozvole bazirane na specifičnim osobinama termina ili povezanim sadržajima).
  • Klasa se može generalizovati da podržava više vokabulara ili da omogućava podešavanje preusmeravanja putem konfiguracije.

7. Ključne napomene

  • Ovaj Event Subscriber predstavlja praktičan način za kontrolu pristupa u Drupalu, koristeći Symfony event-driven arhitekturu za ranu i efikasnu obradu zahteva.
  • Pristup je idealan za zaštitu taxonomy vokabulara kojima bi trebalo da upravljaju samo pouzdani korisnici, čime se smanjuje rizik od slučajnih promena.