So löschen Sie ein Feld programmgesteuert

Oct 19 2020

Ich habe einen Dienst, der die Installation / Deinstallation meines Moduls verwaltet.

Installieren Erstellen Sie ein Feld, das an den Benutzer angehängt ist, aber ich kann es während des Deinstallationsvorgangs nicht löschen ...

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');
  }

}

Während des Laufens habe deleteStackoField()ich nur die Meldung 'Test 2'. Da der Feldspeicher nicht geladen werden kann, wird das Feld nicht gelöscht.

Ich frage mich also, wie ich mein Feld programmgesteuert richtig löschen kann.

Antworten

1 MacSim Oct 19 2020 at 14:28

Also folgte ich den Ratschlägen von @ 4k4 .

Der beste Weg, ein Feld während des Installations- / Deinstallationsprozesses zu erstellen und zu löschen, besteht darin, die Feldspeicher- und Konfigurations-XML-Dateien zum Konfigurations- / Installationsordner des Moduls hinzuzufügen und eine Abhängigkeit vom Modul zu erzwingen.

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