Найти тему
Topsite Web

Как использовать апкастинг параметров в Drupal

Оглавление

В Drupal система маршрутизации позволяет разработчикам определять маршруты для различных страниц в своих приложениях. Эти маршруты могут включать элементы-заполнители в путь, которые по сути являются переменными или динамическими значениями в URL-адресе. Эти заполнители заключены в фигурные фигурные скобки, такие как {node}.

Как работают параметры апкастинга

Элементы-заполнитель

Это части URL-адреса, которые являются переменными или динамическими. В примере /node/{node}, {node} является заполнителем, указывающим на то, что эта часть URL-адреса может варьироваться. Заполнители названы так, чтобы сделать их идентифицируемыми. В примере {node} называется, чтобы указать, что он представляет идентификатор узла.

Апкастинг

Апкастинг относится к процессу преобразования значения заполнителя из URL-адреса в фактический экземпляр объекта. Например система может преобразовать значение заполнителя {node} в фактический объект узла.

Система ParamConverter

Система Drupal ParamConverter отвечает за автоматическое выполнение этого преобразования.
Система ParamConverter принимает значение заполнителя (например, идентификатор узла) и преобразует его в экземпляр соответствующего объекта (например, объект узла).

Пример:

Предположим, у вас есть маршрут с путем /user/{user}/{profile_type}/add.

Когда пользователь посещает URL-адрес, такой как /user/12/editor, система ParamConverter автоматически преобразует значение 12 в фактический пользовательский объект с идентификатором 12.

Вот пример, чтобы проиллюстрировать, как работает обновление параметров в Drupal:

profile.routing.yml

FILENAME: profile.routing.yml
 profile.user_page.add_form:
  path: '/user/{user}/{profile_type}/add'
  defaults:
    _controller: '\Drupal\profile\Controller\UserController::addForm'
    _title: 'Add profile'
  requirements:
    _profile_type_multiple: 'TRUE'
    _custom_access: '\Drupal\profile\Controller\UserController::checkCreateAccess'

UserController.php

Filename: UserController.php
 <?php
 namespace Drupal\profile\Controller;

use Drupal\Core\Access\AccessResult;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Session\AccountInterface;
use Drupal\profile\Entity\ProfileInterface;
use Drupal\profile\Entity\ProfileTypeInterface;
use Drupal\user\UserInterface;

/**
 * Предоставляет пользовательский интерфейс профиля для пользователей.
 */
class UserController extends ControllerBase {

  /**
   * Проверяет доступ к одной или нескольким страницам.
   *
   * @param \Drupal\user\UserInterface $user
   *   Учетная запись пользователя.
   * @param \Drupal\profile\Entity\ProfileTypeInterface $profile_type
   *   Тип профиля.
   * @param \Drupal\Core\Session\AccountInterface $account
   *   Текущая учетная запись, вошедшего в систему.
   *
   * @return \Drupal\Core\Access\AccessResultInterface
   *   Результат доступа.
   */
  public function checkAccess(UserInterface $user, ProfileTypeInterface $profile_type, AccountInterface $account) {
    $user_access = $user->access('view', $account, TRUE);
    if (!$user_access->isAllowed()) {
//Учетная запись не имеет доступа к канонической странице пользователя //("/пользователь/{user}"), также не разрешайте доступ ни к каким
//подстраницам.
      return $user_access;
    }

    $access_control_handler = $this->entityTypeManager()->getAccessControlHandler('profile');
    $profile_storage = $this->entityTypeManager()->getStorage('profile');
    $profile_stub = $profile_storage->create([
      'type' => $profile_type->id(),
      'uid' => $user->id(),
    ]);
    $operation = $profile_type->allowsMultiple() ? 'view' : 'update';
    $result = $access_control_handler->access($profile_stub, $operation, $account, TRUE);

    return $result;
  }

}

Drupal получает множество встроенных конвертеров параметров:


Drupal\Core\ParamConver\EntityConverter — конвертер параметров для преобразования идентификаторов сущностей в полные объекты.

Drupal\Core\ParamConver\EntityRevisionParamConverter — конвертер параметров для преобразования идентификаторов ревизии сущностей в полные объекты.

Drupal\Core\ParamConver\MenuLinkPluginConverter — конвертер параметров для преобразования идентификаторов сущностей меню в полные объекты.

Drupal\ctools\ParamConverter\TempstoreConverter — конвертер параметров для извлечения сущностей из временного хранилища. Это особенно полезно при создании форм, не относящихся к мастеру (например, диалогов), которые работают с данными в мастере и получают правильный доступ к маршруту.

Drupal\jsonapi\ParamConverter\EntityUuidConverter — Конвертер параметров для преобразования UUID сущностей в полные объекты. Имейте в виду, что JSON:API не поддерживает PHP API, так как его API является HTTP API. Этот класс может измениться в любое время, и это разрушит любые зависимости от него.

Как создать пользовательский ParamConvertor

Создайте my_module.routing.yml

my_module.custom_entity_page:
  path: '/node/{dynamic_title}/page'
  defaults:
    _title: 'Заголовок'
    _form: '\Drupal\mymodule\Form\MyModuleformControllerForm'
  options:
    parameters:
      dynamic_title:
        type: custom_entity
        parameter_conversion: true

options — это корневой ключ для дополнительных опций в определении маршрута.

parameters — этот раздел используется для определения параметров маршрута.

dynamic_title — это имя параметра. В этом случае это относится к параметру с именем dynamic_title.

type: custom_entity — это указывает тип параметра. Он сообщает Drupal, что параметр dynamic_title должен быть объектом типа custom_entity. Это полезно для Drupal, чтобы понять ожидаемый тип параметра и применить соответствующую проверку и преобразование.

parameter_conversion: true — эта опция указывает на то, что преобразование параметров должно быть применено для параметра dynamic_title. Преобразование параметров — это процесс, с помощью которого Drupal автоматически преобразует значения заполнителей в URL-адресе в фактические объекты на основе указанного типа.

Создайте my_module.services.yml

Описание метаданных для вашего пользовательского paramconverter, реализующего интерфейс paramconverter.

my_module.services.yml
services:
  my_module.custom_param_converter:
    class: Drupal\my_module\ParamConverter\CustomEntityConverter
    arguments: ['@entity_type.manager']
    tags:
      - { name: 'paramconverter' }
 { name: 'paramconverter' } :  Это тег, применяемый к службе. Он указывает, что служба должна быть распознана как paramconverter. Атрибуту name присвоено значение 'paramconverter'.

Реализуйте пользовательский конвертер параметров в пространстве имен классов PHP в my_module.services.yml

Создайте файл внутри папки /src.

<?php

namespace Drupal\custom_entity;

use Drupal\Core\ParamConverter\ParamConverterInterface;
use Symfony\Component\Routing\Route;

/**
 * Преобразует параметры для типов разделов с расширенной передачей.
 */
class CustomConverter implements ParamConverterInterface {

  /**
   * {@inheritdoc}
   */
  public function convert($value, $definition, $name, array $defaults) {

    $title = $value . 'CustomTitle';
    return $title;
  }

  /**
   * {@inheritdoc}
   */
  public function applies($definition, $name, Route $route) {
    return (!empty($definition['type']) && $definition['type'] === 'custom_entity');
  }

}

После всего этого очистите кэш.

В функции преобразования вы можете манипулировать фактическим значением заполнителя. Вы также можете добавить в него некоторую логику, если условие не выполнено, то вы можете вернуть ноль, что может привести к ошибке 404.

Возврат null из метода преобразования пользовательского ParamConverter в Drupal может привести к ошибке "Страница не найдена". Когда ParamConverter возвращает null, он сигнализирует Drupal о том, что процесс преобразования не был успешным.

Как работают параметры апкастинга

Существует несколько помеченных сервисов (тег "route_enhancer"), которые меняют значения в атрибутах запроса. Одним из примеров является конвертер параметров. (Drupal\Core\ParamConverter\ParamConverterManager).

Менеджер конвертера параметров запускает все необработанные значения через список зарегистрированных преобразователей параметров, важным является сущность (Drupal\Core\ParamConverter\EntityConverter).

ParamConverterManager->convert() вызывает метод EntityConverter->convert() с NID в качестве параметра и устанавливает результат в атрибуты запроса. Этот конвертер сущностей содержит логику преобразования {entity_type} в соответствующий объект сущности, хотя вы можете настроить его так, как показано выше.

Вывод

В Drupal параметр Upcasting позволяет преобразовывать динамические значения URL в экземпляры объектов через систему ParamConverter. Приведенная выше информация иллюстрирует создание пользовательского ParamConverter для пользовательского типа сущности.

Этот процесс включает в себя определение параметров в файле маршрутизации YAML, настройку служб и реализацию класса конвертера. Понимание этого механизма жизненно важно для разработчиков, эффективно управляющих динамическими URL-адресами, предлагая гибкость в обработке различных сценариев.