it-swarm.com.de

Benutzerdefinierte Validierung von Routenparametern

Ich habe so etwas wie das Folgende auf meinem .routing.yml Datei:

my.path:
  path: '/my-path/{node}'
  defaults:
    _form: 'Drupal\mymodule\Form\MyForm'
  requirements:
    _entity_access: 'node.update'
    node: \d+

Dies funktioniert einwandfrei. Es wird überprüft, ob der Benutzer die Berechtigung zum Bearbeiten des Knotens und aller hat. Jetzt möchte ich diese Route so einschränken, dass sie nur für Knoten eines bestimmten Inhaltstyps funktioniert. Im Idealfall so etwas als letzte Zeile:

    node.bundle: 'article'   # this doesn't work, of course

Wie kann ich das machen?

4
cambraca

Ich konnte drei mögliche Wege finden. Angenommen, Ihr Modulname ist Beispiel und der zu überprüfende Inhaltstyp ist Artikel.

1. Überprüfen des Arguments im Form Builder

Es ist der einfachste Weg.

Definieren Sie zunächst Ihre Route wie gewohnt:

example.routing.yml

 example.node.edit_form:
  path: /example/{node}/edit
  defaults:
    _form: 'Drupal\example\Form\ExampleNodeForm'
  options:
    _node_operation_route: TRUE
    parameters:
      node:
        type: entity:node
  requirements:
    _permission: 'edit any article content'

Dann setzen Sie diese Zeilen einfach vor dem anderen Code in Drupal\example\Form\ExampleNodeForm :: buildForm.

if ($node->getType() != 'article') {
  throw new AccessDeniedHttpException();
}

2. Überprüfen Sie das Argument mit einem benutzerdefinierten Zugriffsrückruf .

Die Routendefinition ist dieselbe wie oben, außer dass die Option custom_access Im Abschnitt "Anforderungen" angezeigt wird.

example.routing.yml

 example.node.edit_form:
  path: /example/{node}/edit
  defaults:
    _form: 'Drupal\example\Form\ExampleNodeForm'
  options:
    _node_operation_route: TRUE
    parameters:
      node:
        type: entity:node
  requirements:
    _permission: 'edit any article content'
    _custom_access:  'Drupal\example\Form\ExampleNodeForm::access'

Drupal\example\Form\ExampleNodeForm :: access () sollte die Instanz von Drupal\Core\Access\AccessResult zurückgeben. Dies kann wie folgt erfolgen.

return AccessResult::allowedIf($node->getType() == 'article');

3. Validierung des Arguments mit Zugriffsprüfung

example.routing.yml

 example.node.edit_form:
  path: /example/{node}/edit
  defaults:
    _form: 'Drupal\example\Form\ExampleNodeForm'
  options:
    _node_operation_route: TRUE
    parameters:
      node:
        type: entity:node
  requirements:
    _permission: 'edit any article content'
    _content_type:  'article'

Wie Sie sehen können, beinhaltet dies _ content_type Anforderung. Damit es funktioniert, müssen Sie einen benutzerdefinierten Zugriffsprüfungsdienst implementieren.

example.services.yml

services:
  example.content_type_access_checker:
    class: Drupal\example\Access\ContentTypeAccessCheck
    tags:
      - { name: access_check, applies_to: _content_type }

Drupal\example\src\Access\ContentTypeAccessCheck.php

namespace Drupal\example\Access;

use Drupal\Core\Access\AccessResult;
use Drupal\Core\Routing\Access\AccessInterface;
use Drupal\node\NodeInterface;
use Symfony\Component\Routing\Route;

/**
 * Checks if node type matches the one provided in the route configuration.
 */
class ContentTypeAccessCheck implements AccessInterface {

  /**
   * Access callback.
   */
  public function access(Route $route, NodeInterface $node) {
    return AccessResult::allowedIf($node->getType() == $route->getRequirement('_content_type'));
  }
}

Der letzte Ansatz kann hilfreich sein, wenn Sie den Zugriffssteuerungscode auf mehreren Routen wiederverwenden möchten.

Dokumentation: https://www.drupal.org/docs/8/api/routing-system/access-checking-on-routes .

10
ya.teck