프로그래밍 방식으로 필드를 삭제하는 방법

Oct 19 2020

내 모듈의 설치 / 제거를 관리하는 서비스가 있습니다.

설치는 사용자에게 첨부 된 필드를 생성하지만 제거 프로세스 중에 삭제할 수 없습니다 ...

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

}

실행하는 동안 deleteStackoField()'테스트 2'메시지 만 표시됩니다. 필드 스토리지를로드 할 수 없으므로 필드가 삭제되지 않습니다.

그래서 어떻게 프로그래밍 방식으로 내 필드를 올바르게 삭제할 수 있는지 궁금합니다.

답변

1 MacSim Oct 19 2020 at 14:28

그래서 @ 4k4 조언을 따랐습니다 .

설치 / 제거 프로세스 중에 필드를 만들고 삭제하는 가장 좋은 방법은 모듈의 config / install 폴더에 필드 저장소 및 구성 yml 파일을 추가하고 모듈에 대한 종속성을 적용하는 것입니다.

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