Comment supprimer un champ par programmation

Oct 19 2020

J'ai un service gérant l'installation / la désinstallation de mon module.

Installer créer un champ attaché à l'utilisateur mais je ne suis pas en mesure de le supprimer pendant le processus de désinstallation ...

stacko.services.yml

services:
  stacko.module_installer:
    class: Drupal\stacko\ModuleInstaller
    arguments:
      - '@entity_type.manager'
    tags:
      - { name: service_collector, tag: 'module_install.uninstall_validator', call: addUninstallValidator }

stacko.install

/**
 * Implements hook_install().
 */
function stacko_install() {
  $module_installer = Drupal::service('stacko.module_installer'); $module_installer->install([]);
}

/**
 * Implements hook_uninstall().
 */
function stacko_uninstall() {
  $module_installer = Drupal::service('stacko.module_installer'); $module_installer->uninstall([]);
}

src / ModuleInstaller.php

namespace Drupal\stacko;

use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleInstallerInterface;
use Drupal\Core\Extension\ModuleUninstallValidatorInterface;
use Drupal\field\Entity\FieldStorageConfig;

/**
 * Module installer.
 */
class ModuleInstaller implements ModuleInstallerInterface {

  /**
   * Field storage config manager.
   *
   * @var \Drupal\field\FieldStorageConfigStorage
   */
  protected $fieldStorageConfigManager; /** * Field config manager. * * @var \Drupal\field\FieldConfigInterface */ protected $fieldConfigManager;

  /**
   * Constructor.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager * The entityt type manager. */ public function __construct(EntityTypeManagerInterface $entity_type_manager) {
    $this->fieldStorageConfigManager = $entity_type_manager->getStorage('field_storage_config');
    $this->fieldConfigManager = $entity_type_manager->getStorage('field_config');
  }

  /**
   * {@inheritdoc}
   */
  public function install(array $module_list, $enable_dependencies = TRUE) {
    $this->createFields(); } /** * {@inheritdoc} */ public function uninstall(array $module_list, $uninstall_dependents = TRUE) { $this->deleteFields();
  }

  /**
   * {@inheritdoc}
   */
  public function addUninstallValidator(ModuleUninstallValidatorInterface $uninstall_validator) { } /** * {@inheritdoc} */ public function validateUninstall(array $module_list) {
  }

  /**
   * Create all fields.
   */
  protected function createFields() {
    $this->createStackoField(); } /** * Create Stacko field. */ protected function createStackoField() { $this->createStackoFieldStorage();
    $this->createStackoFieldInstance(); } /** * Delete all fields. */ protected function deleteFields() { $this->deleteStackoField();
  }

  /**
   * Create Stacko field storage.
   */
  protected function createStackoFieldStorage() {
    try {
      $this->fieldStorageConfigManager->create([ 'field_name' => 'field_stacko', 'entity_type' => 'user', 'type' => 'text', 'cardinality' => 1, 'locked' => FALSE, 'indexes' => [], 'settings' => [ 'max_length' => 14, 'is_ascii' => false, 'case_sensitive' => false, ], ])->save(); } catch (\Exception $e) {
      if (PHP_SAPI === 'cli') {
        drush_print_r('Either the field_stacko storage already exists or an error occured and it has not been created.');
      }
    }
  }

  /**
   * Create Stacko field instance.
   */
  protected function createStackoFieldInstance() {
    try {
      $this->fieldConfigManager->create([ 'field_name' => 'field_stacko', 'entity_type' => 'user', 'bundle' => 'user', 'label' => 'The stacko', 'required' => FALSE, 'settings' => [], ])->save(); } catch (\Exception $e) {
      if (PHP_SAPI === 'cli') {
        drush_print_r('Either the field_stacko instance already exists or an error occured and it has not been created.');
      }
    }
  }

  /**
   * Delete Stacko field storage.
   */
  protected function deleteStackoField() {
    // Leads to Error: Call to undefined method Drupal\field\FieldStorageConfigStorage::loadByName()
    /* if ($this->fieldStorageConfigManager->loadByName('user', 'field_stacko')) { $field_storage->delete();
    } */
    // Doesn't load the field storage | doesn't delete the field.
    /* if ($field_storage = $this->fieldStorageConfigManager->loadByProperties([
      'entity_type' => 'user',
      'field_name' => 'field_stacko',
    ])) {
      kint('test 1');
      $field_storage->delete(); } kint('test 2'); */ // Doesn't load the field storage | doesn't delete the field. if ($field_storage = FieldStorageConfig::loadByName('user', 'field_stacko')) {
      kint('test 1');
      $field_storage->delete();
    }
    kint('test 2');
  }

}

Lors de l'exécution, deleteStackoField()je n'ai que le message «test 2». Comme il ne peut pas charger le stockage de champ, le champ n'est pas supprimé.

Je me demande donc comment puis-je supprimer correctement mon champ par programme?

Réponses

1 MacSim Oct 19 2020 at 14:28

J'ai donc suivi les conseils de @ 4k4 .

La meilleure façon de créer et de supprimer un champ pendant le processus d'installation / désinstallation est d'ajouter les fichiers de stockage de champ et de configuration yml au dossier config / install du module et d'imposer une dépendance au module.

config / install / field.field.user.user.field_stacko.yml

langcode: fr
status: true
dependencies:
  config:
    - field.storage.user.field_stacko
  module:
    - text
    - user
  enforced:
    module:
      - stacko
id: user.user.field_stacko
field_name: field_stacko
entity_type: user
bundle: user
label: 'The stacko'
description: ''
required: false
translatable: true
default_value: {  }
default_value_callback: ''
settings: {  }
field_type: text

config / install / field.storage.user.field_stacko.yml

langcode: fr
status: true
dependencies:
  module:
    - text
    - user
  enforced:
    module:
      - stacko
id: user.field_stacko
field_name: field_stacko
entity_type: user
type: text
settings:
  max_length: 14
module: text
locked: false
cardinality: 1
translatable: true
indexes: {  }
persist_with_no_fields: false
custom_storage: false