5 * Contains \Drupal\Console\Command\Field\InfoCommand.
8 namespace Drupal\Console\Command\Field;
10 use Symfony\Component\Console\Input\InputOption;
11 use Symfony\Component\Console\Input\InputInterface;
12 use Symfony\Component\Console\Output\OutputInterface;
13 use Drupal\Console\Core\Command\Command;
14 use Drupal\Core\Entity\EntityFieldManagerInterface;
15 use Drupal\Core\Entity\EntityTypeManagerInterface;
16 use Drupal\field\FieldConfigInterface;
21 class InfoCommand extends Command
24 * @var EntityTypeManagerInterface
26 protected $entityTypeManager;
29 * @var EntityFieldManagerInterface
31 protected $entityFieldManager;
34 * InfoCommand constructor.
36 * @param EntityTypeManagerInterface $entityTypeManager
37 * @param EntityFieldManagerInterface $entityFieldManager
39 public function __construct(
40 EntityTypeManagerInterface $entityTypeManager,
41 EntityFieldManagerInterface $entityFieldManager
43 $this->entityTypeManager = $entityTypeManager;
44 $this->entityFieldManager = $entityFieldManager;
45 parent::__construct();
51 public function configure()
54 ->setName('field:info')
55 ->setDescription($this->trans('commands.field.info.description'))
56 ->setHelp($this->trans('commands.field.info.help'))
60 InputOption::VALUE_NONE,
61 $this->trans('commands.field.info.options.detailed')
66 InputOption::VALUE_OPTIONAL,
67 $this->trans('commands.field.info.options.entity')
72 InputOption::VALUE_OPTIONAL,
73 $this->trans('commands.field.info.options.bundle')
74 )->setAliases(['fii']);
80 protected function execute(InputInterface $input, OutputInterface $output)
82 // Retrieve whether detailed option has been selected.
83 $detailedOutput = $input->getOption('detailed');
85 // Retrieve whether an entity type has been specified.
86 $entityTypeOption = $input->getOption('entity');
88 // Retrieve whether a specific bundle type has been specified.
89 $bundleTypeOption = $input->getOption('bundle');
91 $entityList = $this->entityTypeManager->getDefinitions();
92 $allFields = $this->entityFieldManager->getFieldMap();
94 // Set a flag so we can error if a specific entity type selected but not found.
95 $entityTypeOptionFound = false;
97 // Set a flag so we can error if a specific bundle type selected but not found.
98 $bundleTypeOptionFound = false;
100 // Let's count the fields found so we can display a message if none found.
103 foreach ($entityList as $entityTypeId => $entityValue) {
104 // If the Entity has bundleEntityType set we grab it.
105 $bundleEntityType = $entityValue->get('bundle_entity_type');
107 // Check to see if the entity has any bundle before continuing.
108 if (!empty($bundleEntityType)) {
109 $bundleTypes = $this->entityTypeManager
110 ->getStorage($bundleEntityType)->loadMultiple();
112 // If a specific entity type has been selected and this is it then we continue else we skip.
113 if ((!empty($entityTypeOption) && ($entityTypeOption == $entityTypeId))| empty($entityTypeOption)
115 // Store the fact that we found the entity type specified so we can error if not found.
116 $entityTypeOptionFound = true;
118 // Get the entity type label.
119 $bundleParent = $entityValue->get('label');
121 // Using counter to know whether to output header.
122 $bundleTypeCounter = 0;
123 foreach ($bundleTypes as $bundleType) {
124 // If a specific bundle type has been selected and this is it then we continue else we skip.
125 if ((!empty($bundleTypeOption) && ($bundleTypeOption == $bundleType->id()))| empty($bundleTypeOption)
127 // Store the fact that we found the bundle type specified so we can error if not found.
128 $bundleTypeOptionFound = true;
130 // Increase the bundle type counter so we know whether to output header.
131 $bundleTypeCounter++;
133 if ($bundleTypeCounter == 1) {
134 // Output the Parent Entity label if we haven't already.
135 if ($detailedOutput) {
136 // If detailed output then display the id as well.
137 $this->getIo()->info(strtoupper($bundleParent) . ' (' . $entityTypeId . '):');
139 // otherwise just display the label for normal output.
140 $this->getIo()->info(strtoupper($bundleParent . ':'));
142 $this->getIo()->newLine();
145 // Load in the entityType fields.
146 $fields = $this->getBundleFields(
151 foreach ($fields as $field => $fieldArray) {
152 // We found a field so increase the field counter.
155 // Get the related / used in bundles from the field.
156 $relatedBundles = "";
157 $relatedBundlesArray = $allFields[$entityTypeId][$field]['bundles'];
159 // Turn those related / used in bundles array into a string.
160 foreach ($relatedBundlesArray as $relatedBundlesValue) {
161 if ($bundleTypes[$relatedBundlesValue]->id() != $bundleType->id()) {
162 if (!empty($relatedBundles)) {
163 $relatedBundles .= ', ' . $bundleTypes[$relatedBundlesValue]->label();
165 $relatedBundles = $bundleTypes[$relatedBundlesValue]->label();
170 // Build out our table for the fields.
171 $tableRows[] = $detailedOutput ? [
172 $fieldArray->get('label'),
173 $fieldArray->get('field_type'),
174 $fieldArray->get('description'),
177 $fieldArray->get('label'),
178 $fieldArray->get('field_type'),
182 // Clear the related bundles ready for the next field.
183 unset($relatedBundles);
186 // If detailed output then display bundle id and description.
187 if ($detailedOutput) {
188 // Output the bundle label and id.
189 $this->getIo()->info($bundleType->label() . ' (' . $bundleType->id() . ')');
190 $this->getIo()->info(strip_tags($bundleType->get('description')));
192 // Else just output the bundle label.
193 $this->getIo()->info($bundleType->label());
196 // Fill out our table header.
197 // If no rows exist for the fields then we display a no results message.
198 if (!empty($tableRows)) {
199 $tableHeader = $detailedOutput ? [
200 $this->trans('commands.field.info.table.header-name'),
201 $this->trans('commands.field.info.table.header-type'),
202 $this->trans('commands.field.info.table.header-desc'),
203 $this->trans('commands.field.info.table.header-usage')
205 $this->trans('commands.field.info.table.header-name'),
206 $this->trans('commands.field.info.table.header-type'),
207 $this->trans('commands.field.info.table.header-usage')
209 $this->getIo()->table($tableHeader, $tableRows);
211 $this->getIo()->comment(
212 $this->trans('commands.field.info.messages.fields-none')
213 . ' ' . $this->trans('commands.field.info.messages.in-bundle-type')
214 . " '" . $bundleType->label() . "'"
218 // Clear out the rows & headers arrays to start fresh.
219 unset($tableHeader, $tableRows);
221 // Create some space so the output looks nice.
222 $this->getIo()->newLine();
229 // If entity type was specified but not found then display error message.
230 if (!empty($entityTypeOption)) {
231 if (!$entityTypeOptionFound) {
232 $this->getIo()->comment(
233 $this->trans('commands.field.info.messages.entity-type') .
234 ' ' . $entityTypeOption . ' ' .
235 $this->trans('commands.field.info.messages.not-found')
237 } elseif (!empty($bundleTypeOption) && !$bundleTypeOptionFound) {
238 // If specified entity type found and bundle type specified but not found then display error message.
239 $this->getIo()->comment(
240 $this->trans('commands.field.info.messages.bundle-type') .
241 ' ' . $bundleTypeOption . ' ' .
242 $this->trans('commands.field.info.messages.not-found') .
243 ' ' . $this->trans('commands.field.info.messages.in-entity-type') .
244 ' ' . $entityTypeOption
247 } elseif (!empty($bundleTypeOption) && !$bundleTypeOptionFound) {
248 // If specified bundle type not found then display error message.
249 $this->getIo()->comment(
250 $this->trans('commands.field.info.messages.bundle-type') .
251 ' ' . $bundleTypeOption . ' ' .
252 $this->trans('commands.field.info.messages.not-found')
254 } elseif ($fieldCounter == 0) {
255 // If no fields found then display appropriate message.
256 $this->getIo()->comment($this->trans('commands.field.info.messages.fields-none'));
263 * Helper function to get the field definitions.
265 * @param string $entityTypeId
266 * The entity type we want to inspect.
267 * @param string $bundle
268 * The bundle we want to discover the fields of.
270 * An array of field storage definitions for the entity type,
271 * keyed by field name.
273 private function getBundleFields($entityTypeId, $bundle)
276 if (!empty($entityTypeId) && !empty($bundle)) {
277 $fields = array_filter(
278 $this->entityFieldManager->getFieldDefinitions($entityTypeId, $bundle),
279 function ($fieldDefinition) {
280 return $fieldDefinition instanceof FieldConfigInterface;