Version 1
[yaffs-website] / web / core / modules / field / src / FieldUninstallValidator.php
1 <?php
2
3 namespace Drupal\field;
4
5 use Drupal\Core\Entity\EntityTypeManagerInterface;
6 use Drupal\Core\Extension\ModuleUninstallValidatorInterface;
7 use Drupal\Core\Field\FieldTypePluginManagerInterface;
8 use Drupal\Core\StringTranslation\StringTranslationTrait;
9 use Drupal\Core\StringTranslation\TranslationInterface;
10
11 /**
12  * Prevents uninstallation of modules providing active field storage.
13  */
14 class FieldUninstallValidator implements ModuleUninstallValidatorInterface {
15
16   use StringTranslationTrait;
17
18   /**
19    * The field storage config storage.
20    *
21    * @var \Drupal\Core\Config\Entity\ConfigEntityStorageInterface
22    */
23   protected $fieldStorageConfigStorage;
24
25   /**
26    * The field type plugin manager.
27    *
28    * @var \Drupal\Core\Field\FieldTypePluginManagerInterface
29    */
30   protected $fieldTypeManager;
31
32   /**
33    * Constructs a new FieldUninstallValidator.
34    *
35    * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
36    *   The entity manager.
37    * @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation
38    *   The string translation service.
39    * @param \Drupal\Core\Field\FieldTypePluginManagerInterface $field_type_manager
40    *   The field type plugin manager.
41    */
42   public function __construct(EntityTypeManagerInterface $entity_type_manager, TranslationInterface $string_translation, FieldTypePluginManagerInterface $field_type_manager) {
43     $this->fieldStorageConfigStorage = $entity_type_manager->getStorage('field_storage_config');
44     $this->stringTranslation = $string_translation;
45     $this->fieldTypeManager = $field_type_manager;
46   }
47
48   /**
49    * {@inheritdoc}
50    */
51   public function validate($module) {
52     $reasons = [];
53     if ($field_storages = $this->getFieldStoragesByModule($module)) {
54       // Provide an explanation message (only mention pending deletions if there
55       // remain no actual, non-deleted fields.)
56       $fields_in_use = [];
57       foreach ($field_storages as $field_storage) {
58         if (!$field_storage->isDeleted()) {
59           $fields_in_use[$field_storage->getType()][] = $field_storage->getLabel();
60         }
61       }
62       if (!empty($fields_in_use)) {
63         foreach ($fields_in_use as $field_type => $field_storages) {
64           $field_type_label = $this->getFieldTypeLabel($field_type);
65           $reasons[] = $this->formatPlural(count($fields_in_use[$field_type]), 'The %field_type_label field type is used in the following field: @fields', 'The %field_type_label field type is used in the following fields: @fields', ['%field_type_label' => $field_type_label, '@fields' => implode(', ', $field_storages)]);
66         }
67       }
68       else {
69         $reasons[] = $this->t('Fields pending deletion');
70       }
71     }
72     return $reasons;
73   }
74
75   /**
76    * Returns all field storages for a specified module.
77    *
78    * @param string $module
79    *   The module to filter field storages by.
80    *
81    * @return \Drupal\field\FieldStorageConfigInterface[]
82    *   An array of field storages for a specified module.
83    */
84   protected function getFieldStoragesByModule($module) {
85     return $this->fieldStorageConfigStorage->loadByProperties(['module' => $module, 'include_deleted' => TRUE]);
86   }
87
88
89   /**
90    * Returns the label for a specified field type.
91    *
92    * @param string $field_type
93    *   The field type.
94    *
95    * @return string
96    *   The field type label.
97    */
98   protected function getFieldTypeLabel($field_type) {
99     return $this->fieldTypeManager->getDefinitions()[$field_type]['label'];
100   }
101
102 }