Drupal 10 : Injection Automatique de l’ID de l’Entreprise dans les Contenus Créés

Introduction

Dans un environnement de gestion de contenu dynamique, il est souvent nécessaire de structurer les données pour garantir une organisation cohérente et automatisée. Cet article détaille la mise en œuvre d’un module personnalisé sous Drupal, conçu pour associer automatiquement chaque contenu créé par un utilisateur à son entreprise via un champ d’identifiant unique. Cette approche assure une attribution précise et transparente de la relation entre les utilisateurs et leurs contenus, facilitant ainsi l’accès et le suivi des données. Ce guide vous conduira, étape par étape, à travers les configurations et les implémentations nécessaires pour établir cette fonctionnalité de manière optimale.

Prérequis

Avant de procéder à la configuration, veuillez vous assurer de satisfaire aux conditions suivantes :

Use Case

Dans ce cas d’utilisation, nous allons créer un module personnalisé appelé custom_entity_associate qui permet d’associer automatiquement chaque contenu d’un type spécifique, tel que Document, à l’entreprise de l’utilisateur authentifié. L’objectif est de garantir que, lorsqu’un utilisateur, ici “John” de la société “Alpha”, crée un contenu de type Document (par exemple, “document0”), l’identifiant de son entreprise soit automatiquement renseigné dans le champ field_accountid du contenu. Cela assure une liaison cohérente et automatisée entre chaque contenu et l’entreprise de l’utilisateur, simplifiant ainsi la gestion des données et leur suivi par entreprise.

Création d’un Content Type

Nous allons créer un type de contenu dédié, nommé Document, auquel nous ajouterons un champ de référence pour associer chaque contenu à l’entreprise de l’utilisateur qui le crée.

  • Créer le type de contenu : Dans l’interface d’administration de Drupal, rendez-vous à l’adresse /admin/structure/types et cliquez sur Add content type. Donnez au type de contenu le nom Document et, si nécessaire, ajoutez une description. Par défaut, un champ Title est inclus et défini comme requis.
  • Ajouter un champ de référence d’entité : Une fois le type de contenu enregistré, ajoutez un champ de référence d’entité nommé field_accountid, qui pointera vers le type de contenu Account. Ce champ est essentiel pour stocker l’ID de l’entreprise de l’utilisateur. Sélectionnez Content comme type de référence, puis spécifiez le type de contenu Account pour établir le lien entre le document et l’entreprise.
  • Configurer JSON (facultatif) : Pour adapter l’endpoint JSON de ce type de contenu, accédez à /admin/config/services/jsonapi/resource_types. Modifiez le chemin par défaut de l’endpoint /api/node/document vers /api/document si vous souhaitez simplifier l’accès aux données.
  • Configurer les permissions d’accès : Afin que chaque utilisateur authentifié puisse créer un contenu de type Document, accédez à /admin/people/permissions dans l’administration de Drupal. Dans la section Document, activez la permission Create new content pour le rôle Authenticated user. Cette étape garantit que les utilisateurs pourront créer des contenus de type Document et que le champ field_accountid contiendra l’identifiant de leur entreprise.

Mise en Place du Service

Nous allons implémenter un service qui associe automatiquement chaque contenu créé par un utilisateur à son entreprise via un champ d’identifiant unique. Ce service s’appuie sur le module personnalisé custom_entity_associate et assure une liaison transparente entre l’utilisateur et son contenu à travers le champ field_accountid. Tout d’abord, nous allons créer le fichier de configuration du service pour le module. Ce fichier définit un service qui gère l’association des entités avec l’entreprise de l’utilisateur.

services:
  custom_entity_associate.entity_associator:
    class: Drupal\custom_entity_associate\Service\EntityAssociator
    arguments: ['@logger.factory', '@entity_type.manager']
    tags:
      - { name: event_subscriber }
      

Ce fichier déclare un service nommé custom_entity_associate.entity_associator, qui fait appel à la classe EntityAssociator (à créer dans la suite). Le service injecte deux dépendances : entity_type.manager pour gérer les entités et logger.factory pour enregistrer des logs.

Le cœur de notre fonctionnalité réside dans le service EntityAssociator, qui associe automatiquement chaque contenu créé par un utilisateur à son entreprise. Voici le code de ce service :

<?php
namespace Drupal\custom_entity_associate\Service;

use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Drupal\node\NodeInterface;

class EntityAssociator implements EventSubscriberInterface {

  protected $loggerFactory;
  protected $entityTypeManager;

  public function __construct(LoggerChannelFactoryInterface $loggerFactory, EntityTypeManagerInterface $entityTypeManager) {
    $this->loggerFactory = $loggerFactory;
    $this->entityTypeManager = $entityTypeManager;
  }

  public static function getSubscribedEvents() {
    return [
      'entity.insert' => 'onEntityInsert',
    ];
  }

  public function onEntityInsert(EntityInterface $entity) {
    // Check if the entity has a 'field_accountid' field.
    if ($entity instanceof NodeInterface && $entity->hasField('field_accountid')) {
      $this->loggerFactory->get('custom_entity_associate')->notice('Entity insert hook called for entity type @entity_type.', [
        '@entity_type' => $entity->getEntityTypeId(),
      ]);
      $this->associateEntityWithAccount($entity);
    }
  }

  private function associateEntityWithAccount(EntityInterface $entity) {
    // Retrieve the company account information.
    $account_id = $this->getAccountForCurrentUser(); // Implement logic to fetch the appropriate account ID.

    if ($account_id) {
      $entity->set('field_accountid', $account_id); // Assuming 'field_accountid' is the reference field.
      $entity->save();

      $this->loggerFactory->get('custom_entity_associate')->notice('Entity @entity_id associated with account @account_id', [
        '@entity_id' => $entity->id(),
        '@account_id' => $account_id,
      ]);
    } else {
      $this->loggerFactory->get('custom_entity_associate')->error('Failed to find or associate an account with entity @entity_id', [
        '@entity_id' => $entity->id(),
      ]);
    }
  }

  // Example logic to retrieve account ID, adjust as per your requirement.
  private function getAccountForCurrentUser() {
    // Retrieve the current user.
    $user = \Drupal::currentUser();

    // Retrieve the account associated with the user.
    $account_id = NULL;
    if ($user->isAuthenticated()) {
      $account = $this->entityTypeManager->getStorage('user')->load($user->id());
      $account_id = $account->get('field_accountid')->target_id;
    }

    return $account_id;
  }
}

Le code utilise plusieurs éléments pour garantir une gestion efficace des entités. D’abord, EntityTypeManagerInterface est injecté afin de permettre la manipulation des entités, tandis que LoggerChannelFactoryInterface est utilisé pour enregistrer les événements dans les logs. La méthode onEntityInsert() est déclenchée chaque fois qu’une entité est insérée. Elle vérifie si l’entité est un Node et si elle contient le champ field_accountid. Si ces conditions sont remplies, elle appelle la méthode associateEntityWithAccount(), qui assigne l’ID de l’entreprise de l’utilisateur au champ field_accountid du contenu et enregistre l’action dans les logs à l’aide de la méthode notice(). La méthode getAccountForCurrentUser() récupère l’ID de l’entreprise de l’utilisateur authentifié, en supposant que l’utilisateur possède un champ field_accountid. Enfin, la méthode getSubscribedEvents() permet à la classe de s’abonner à l’événement EntityInsertEvent, ce qui signifie que chaque fois qu’une entité est insérée, la méthode onEntityInsert() est appelée.

Utilisation du hook

Nous utilisons le hook hook_entity_insert() pour déclencher le service d’association. Ce hook permet d’intervenir immédiatement après la création d’une entité en appelant notre service EntityAssociator pour gérer l’association.

/**
 * Implements hook_entity_insert().
 */
function custom_entity_associate_entity_insert(Drupal\Core\Entity\EntityInterface $entity) {
  // Use the service to handle company account association.
  if ($entity instanceof Node) {
    \Drupal::service('custom_entity_associate.entity_associator')->onEntityInsert($entity);
  }
}

Le code commence par vérifier si l’entité est un nœud (Node) afin de s’assurer que l’opération s’applique uniquement aux entités de type contenu. Ensuite, il appelle le service custom_entity_associate.entity_associator et utilise sa méthode onEntityInsert() pour effectuer l’association avec l’entreprise de l’utilisateur.

Configuration du fichier .info

Pour que le module custom_entity_associate soit reconnu par Drupal et puisse fonctionner correctement, vous devez configurer le fichier .info.yml de votre module, qui contient des informations essentielles sur le module, comme son nom, sa version, sa description et ses dépendances. Créez un fichier nommé custom_entity_associate.info.yml dans le répertoire de votre module, puis ajoutez-y le contenu suivant :

name: 'Custom Entity Account Association'
type: module
description: 'Automatically associates a company account when a new entity with field_accountid is created.'
core_version_requirement: ^8 || ^9 || ^10
package: Custom
dependencies:
  - drupal:node
  - drupal:field
  - drupal:user
  - drupal:system

Ce fichier .info.yml configure le module Custom Entity Account Association, qui associe automatiquement un compte d’entreprise lors de la création d’une entité avec le champ field_accountid. Il précise les versions de Drupal compatibles (8, 9, et 10), le classe sous “Custom” et déclare les dépendances nécessaires (node, field, user, et system) pour son bon fonctionnement.

Test

Pour tester le module, voici un exemple de requête curl à exécuter après avoir activé le module et vérifié que l’utilisateur “John” possède un champ field_accountid lié à son entreprise (par exemple, “Alpha”).

Avant de créer un contenu via l’API, récupérez le jeton CSRF pour autoriser la requête.

curl -X GET "https://your-drupal-site.com/session/token" -H "Content-Type: application/json"

Une fois le jeton CSRF obtenu, utilisez-le dans la requête suivante pour créer un contenu Document avec les informations ci-dessous. Assurez-vous de remplacer <X-CSRF-Token> par le jeton CSRF obtenu, et <OAuth2-Access-Token> par le jeton d’accès de John.

curl -X POST "https://your-drupal-site.com/api/document" \
  -H "Content-Type: application/vnd.api+json" \
  -H "X-CSRF-Token: <X-CSRF-Token>" \
  -H "Authorization: Bearer <OAuth2-Access-Token>" \
  -d '{
    "data": {
      "type": "node--document",
      "attributes": {
        "title": "document0"
      }
    }
  }'

Dans la réponse de l’API, assurez-vous que le champ field_accountid est automatiquement rempli. La réponse JSON devrait inclure un objet relationshipsfield_accountid est lié à l’entreprise de l’utilisateur “John”, c’est-à-dire “Alpha”.

{
  "data": {
    "type": "node--document",
    "id": "generated-document-id",
    "attributes": {
      "title": "document0"
    },
    "relationships": {
      "field_accountid": {
        "data": {
          "type": "node--account",
          "id": "bb027692-c144-41f4-807b-fcdef4915391",
          "meta": {
            "drupal_internal__target_id": 1
          }
        }
      }
    }
  }
}

Dans cet exemple, l’ID bb027692-c144-41f4-807b-fcdef4915391 et le drupal_internal__target_id (1) représentent l’ID de l’entreprise “Alpha”, confirmant que le champ field_accountid est correctement lié à l’entreprise et de John.

Conclusion

Ce module personnalisé pour Drupal automatise l’association des contenus avec les entreprises des utilisateurs, améliorant ainsi la gestion des données en liant chaque contenu à l’entreprise de son créateur. En suivant les étapes de configuration et d’implémentation, vous pourrez assurer une organisation et une traçabilité optimales pour chaque entité créée, contribuant à un système plus cohérent et efficace pour les utilisateurs et administrateurs du site.

Développeuse fullstack * Plus de publications

Développeuse fullstack spécialisée en Systèmes d'Information Répartis , diplômée de la section informatique de la Faculté des Sciences et Techniques (FST) de l'UCAD. Je relève avec passion des défis complexes, avec une forte capacité d'adaptation et un engagement pour la collaboration en équipe. Toujours avide d'apprendre, je vise à créer un impact positif et à promouvoir l'excellence organisationnelle dans chaque projet.

Contributeurs

0 0 votes
Évaluation de l'article
guest
0 Commentaires
Le plus ancien
Le plus récent Le plus populaire
Commentaires en ligne
Afficher tous les commentaires

Ingénierie informatique (SSII)

Applize crée des logiciels métiers pour accompagner les entreprises dans la transition vers le zéro papier.


Avez-vous un projet en tête ? Discutons-en.