Création d’un type d’objet de configuration dans Drupal 8
Cette page présente un exemple de création d’un type d’objet de configuration avec des pages de gestion dans l’administration pour Drupal 8. Pour comprendre les notions de configuration simple et d’objets de configuration, voir https://drupal.org/node/2120523.
Après activation du module d’exemple contenant le code ci-dessous, un formulaire de configuration sera accessible à l’adresse « admin/config/system/example », comme montré sur la capture d’écran :
Configuration du module et entrée dans le menu d’administration
example/example.info.yml
name: Example description: 'Manages example configuration.' package: Example type: module core: 8.x
Routage
(Voir certains classes d’aide ajoutées pour simplifier la gestion des routes d’entités.)
example/example.routing.yml
Ce fichier routing.yml définit les routes pour les pages de gestion : liste, ajout, édition, suppression.
entity.example.collection: path: '/admin/config/system/example' defaults: _entity_list: 'example' _title: 'Example configuration' requirements: _permission: 'administer site configuration' entity.example.add_form: path: '/admin/config/system/example/add' defaults: _entity_form: 'example.add' _title: 'Add example' requirements: _permission: 'administer site configuration' entity.example.edit_form: path: '/admin/config/system/example/{example}' defaults: _entity_form: 'example.edit' _title: 'Edit example' requirements: _permission: 'administer site configuration' entity.example.delete_form: path: '/admin/config/system/example/{example}/delete' defaults: _entity_form: 'example.delete' _title: 'Delete example' requirements: _permission: 'administer site configuration'
example/example.links.menu.yml
Ajoute un lien vers la page de configuration sous Système :
entity.example.collection: title: 'Example' parent: system.admin_config_system description: 'Configure example' route_name: entity.example.collection
example/example.links.action.yml
Ce fichier fait apparaître un lien « Ajouter » sur la page de liste :
entity.example.add_form: route_name: 'entity.example.add_form' title: 'Add example' appears_on: - entity.example.collection
Classes du type d’objet
example/src/ExampleInterface.php
Si votre entité de configuration a des propriétés, vous devez définir les méthodes set/get dans l’interface.
namespace Drupal\example; use Drupal\Core\Config\Entity\ConfigEntityInterface; /** * Fournit une interface définissant une entité Example. */ interface ExampleInterface extends ConfigEntityInterface { // Ajoutez ici les méthodes get/set pour vos propriétés de configuration. }
example/src/Entity/Example.php
Ce fichier définit la classe de l’entité de configuration.
namespace Drupal\example\Entity; use Drupal\Core\Config\Entity\ConfigEntityBase; use Drupal\example\ExampleInterface; /** * Définit l’entité Example. * * @ConfigEntityType( * id = "example", * label = @Translation("Example"), * handlers = { * "list_builder" = "Drupal\example\Controller\ExampleListBuilder", * "form" = { * "add" = "Drupal\example\Form\ExampleForm", * "edit" = "Drupal\example\Form\ExampleForm", * "delete" = "Drupal\example\Form\ExampleDeleteForm", * } * }, * config_prefix = "example", * admin_permission = "administer site configuration", * entity_keys = { * "id" = "id", * "label" = "label", * }, * config_export = { * "id", * "label" * }, * links = { * "edit-form" = "/admin/config/system/example/{example}", * "delete-form" = "/admin/config/system/example/{example}/delete", * } * ) */ class Example extends ConfigEntityBase implements ExampleInterface { /** * ID de l’Example. * * @var string */ public $id; /** * Libellé de l’Example. * * @var string */ public $label; // Vos méthodes get/set pour vos propriétés personnalisées ici, // implémentant l’interface. }
La clé admin_permission autorise automatiquement l’accès aux utilisateurs disposant de cette permission. Pour une logique plus complexe, un contrôleur d’accès personnalisé peut être défini.
Depuis Drupal 8.6.x, il est recommandé que tous les types d’objets de configuration aient la propriété config_export dans leurs annotations (voir : https://www.drupal.org/node/2949023).
Fichier de schéma de configuration
example/config/schema/example.schema.yml
example.example.*: type: config_entity label: 'Example config' mapping: id: type: string label: 'ID' label: type: label label: 'Label'
Dans example.schema.yml, ajoutez les propriétés/attributs définis dans \Drupal\example\Entity\Example.
example.example.* est la variable de configuration faisant référence aux propriétés/attributs de notre classe. Vous pouvez utiliser un autre nom de variable en modifiant « config_prefix », par exemple :
@ConfigEntityType( .. ... config_prefix = "variable_name" ...
vous pouvez alors y faire référence ainsi :
example.variable_name.*: ....
Pour plus d’informations sur le schéma de configuration, voir Schéma de configuration/métadonnées.
Classes d’entités
example/src/Form/ExampleForm.php
namespace Drupal\example\Form; use Drupal\Core\Entity\EntityForm; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Messenger\MessengerInterface; use Symfony\Component\DependencyInjection\ContainerInterface; /** * Gestionnaire du formulaire d’ajout et d’édition d’Example. */ class ExampleForm extends EntityForm { /** * Constructeur de l’ExampleForm. * * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager * Le gestionnaire de types d’entités. */ public function __construct(EntityTypeManagerInterface $entityTypeManager) { $this->entityTypeManager = $entityTypeManager; } /** * {@inheritdoc} */ public static function create(ContainerInterface $container) { return new static( $container->get('entity_type.manager') ); } /** * {@inheritdoc} */ public function form(array $form, FormStateInterface $form_state) { $form = parent::form($form, $form_state); $example = $this->entity; $form['label'] = [ '#type' => 'textfield', '#title' => $this->t('Label'), '#maxlength' => 255, '#default_value' => $example->label(), '#description' => $this->t("Label for the Example."), '#required' => TRUE, ]; $form['id'] = [ '#type' => 'machine_name', '#default_value' => $example->id(), '#machine_name' => [ 'exists' => [$this, 'exist'], ], '#disabled' => !$example->isNew(), ]; // Vous devrez ajouter d’autres éléments de formulaire pour vos propriétés personnalisées. return $form; } /** * {@inheritdoc} */ public function save(array $form, FormStateInterface $form_state) { $example = $this->entity; $status = $example->save(); if ($status === SAVED_NEW) { $this->messenger()->addMessage($this->t('The %label Example created.', [ '%label' => $example->label(), ])); } else { $this->messenger()->addMessage($this->t('The %label Example updated.', [ '%label' => $example->label(), ])); } $form_state->setRedirect('entity.example.collection'); } /** * Fonction utilitaire pour vérifier si une entité Example existe déjà. */ public function exist($id) { $entity = $this->entityTypeManager->getStorage('example')->getQuery() ->condition('id', $id) ->execute(); return (bool) $entity; } }
example/src/Controller/ExampleListBuilder.php
namespace Drupal\example\Controller; use Drupal\Core\Config\Entity\ConfigEntityListBuilder; use Drupal\Core\Entity\EntityInterface; /** * Fournit la liste des Example. */ class ExampleListBuilder extends ConfigEntityListBuilder { /** * {@inheritdoc} */ public function buildHeader() { $header['label'] = $this->t('Example'); $header['id'] = $this->t('Machine name'); return $header + parent::buildHeader(); } /** * {@inheritdoc} */ public function buildRow(EntityInterface $entity) { $row['label'] = $entity->label(); $row['id'] = $entity->id(); // Vous pouvez ajouter ici d’autres propriétés... return $row + parent::buildRow($entity); } }
example/src/Form/ExampleDeleteForm.php
namespace Drupal\example\Form; use Drupal\Core\Entity\EntityConfirmFormBase; use Drupal\Core\Url; use Drupal\Core\Form\FormStateInterface; /** * Construction du formulaire de suppression d’un Example. */ class ExampleDeleteForm extends EntityConfirmFormBase { /** * {@inheritdoc} */ public function getQuestion() { return $this->t('Are you sure you want to delete %name?', ['%name' => $this->entity->label()]); } /** * {@inheritdoc} */ public function getCancelUrl() { return new Url('entity.example.collection'); } /** * {@inheritdoc} */ public function getConfirmText() { return $this->t('Delete'); } /** * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { $this->entity->delete(); $this->messenger()->addMessage($this->t('Entity %label has been deleted.', ['%label' => $this->entity->label()])); $form_state->setRedirectUrl($this->getCancelUrl()); } }