10
10
use Doctrine \ORM \Mapping \FieldMapping ;
11
11
use Doctrine \Persistence \Mapping \MappingException ;
12
12
use InvalidArgumentException ;
13
+ use JsonException ;
13
14
use Symfony \Component \Console \Completion \CompletionInput ;
14
15
use Symfony \Component \Console \Completion \CompletionSuggestions ;
15
16
use Symfony \Component \Console \Input \InputArgument ;
@@ -55,6 +56,7 @@ protected function configure(): void
55
56
->addArgument ('entityName ' , InputArgument::REQUIRED , 'Full or partial name of entity ' )
56
57
->setDescription ('Display information about mapped objects ' )
57
58
->addOption ('em ' , null , InputOption::VALUE_REQUIRED , 'Name of the entity manager to operate on ' )
59
+ ->addOption ('format ' , null , InputOption::VALUE_REQUIRED , 'Output format (json, text) ' , 'text ' )
58
60
->setHelp (<<<'EOT'
59
61
The %command.full_name% command describes the metadata for the given full or partial entity class name.
60
62
@@ -63,6 +65,15 @@ protected function configure(): void
63
65
Or:
64
66
65
67
<info>%command.full_name%</info> MyEntity
68
+
69
+ To output the metadata in JSON format, use the <info>--format</info> option:
70
+
71
+ <info>%command.full_name% My\Namespace\Entity\MyEntity --format=json</info>
72
+
73
+ To use a specific entity manager (e.g., for multi-DB projects), use the <info>--em</info> option:
74
+
75
+ <info>%command.full_name% My\Namespace\Entity\MyEntity --em=my_custom_entity_manager</info>
76
+
66
77
EOT);
67
78
}
68
79
@@ -72,7 +83,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
72
83
73
84
$ entityManager = $ this ->getEntityManager ($ input );
74
85
75
- $ this ->displayEntity ($ input ->getArgument ('entityName ' ), $ entityManager , $ ui );
86
+ $ this ->displayEntity ($ input ->getArgument ('entityName ' ), $ entityManager , $ ui, $ input -> getOption ( ' format ' ) );
76
87
77
88
return 0 ;
78
89
}
@@ -89,6 +100,10 @@ public function complete(CompletionInput $input, CompletionSuggestions $suggesti
89
100
90
101
$ suggestions ->suggestValues (array_values ($ entities ));
91
102
}
103
+
104
+ if ($ input ->mustSuggestOptionValuesFor ('format ' )) {
105
+ $ suggestions ->suggestValues (array_values ($ this ->getAvailableFormatOptions ()));
106
+ }
92
107
}
93
108
94
109
/**
@@ -100,9 +115,47 @@ private function displayEntity(
100
115
string $ entityName ,
101
116
EntityManagerInterface $ entityManager ,
102
117
SymfonyStyle $ ui ,
118
+ string |null $ format ,
103
119
): void {
104
120
$ metadata = $ this ->getClassMetadata ($ entityName , $ entityManager );
105
121
122
+ if ($ format === 'json ' ) {
123
+ $ ui ->text (json_encode (
124
+ [
125
+ 'name ' => $ metadata ->name ,
126
+ 'rootEntityName ' => $ metadata ->rootEntityName ,
127
+ 'customGeneratorDefinition ' => $ this ->formatValueToJson ($ metadata ->customGeneratorDefinition ),
128
+ 'customRepositoryClassName ' => $ metadata ->customRepositoryClassName ,
129
+ 'isMappedSuperclass ' => $ metadata ->isMappedSuperclass ,
130
+ 'isEmbeddedClass ' => $ metadata ->isEmbeddedClass ,
131
+ 'parentClasses ' => $ metadata ->parentClasses ,
132
+ 'subClasses ' => $ metadata ->subClasses ,
133
+ 'embeddedClasses ' => $ metadata ->embeddedClasses ,
134
+ 'identifier ' => $ metadata ->identifier ,
135
+ 'inheritanceType ' => $ metadata ->inheritanceType ,
136
+ 'discriminatorColumn ' => $ this ->formatValueToJson ($ metadata ->discriminatorColumn ),
137
+ 'discriminatorValue ' => $ metadata ->discriminatorValue ,
138
+ 'discriminatorMap ' => $ metadata ->discriminatorMap ,
139
+ 'generatorType ' => $ metadata ->generatorType ,
140
+ 'table ' => $ this ->formatValueToJson ($ metadata ->table ),
141
+ 'isIdentifierComposite ' => $ metadata ->isIdentifierComposite ,
142
+ 'containsForeignIdentifier ' => $ metadata ->containsForeignIdentifier ,
143
+ 'containsEnumIdentifier ' => $ metadata ->containsEnumIdentifier ,
144
+ 'sequenceGeneratorDefinition ' => $ this ->formatValueToJson ($ metadata ->sequenceGeneratorDefinition ),
145
+ 'changeTrackingPolicy ' => $ metadata ->changeTrackingPolicy ,
146
+ 'isVersioned ' => $ metadata ->isVersioned ,
147
+ 'versionField ' => $ metadata ->versionField ,
148
+ 'isReadOnly ' => $ metadata ->isReadOnly ,
149
+ 'entityListeners ' => $ metadata ->entityListeners ,
150
+ 'associationMappings ' => $ this ->formatMappingsToJson ($ metadata ->associationMappings ),
151
+ 'fieldMappings ' => $ this ->formatMappingsToJson ($ metadata ->fieldMappings ),
152
+ ],
153
+ JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR ,
154
+ ));
155
+
156
+ return ;
157
+ }
158
+
106
159
$ ui ->table (
107
160
['Field ' , 'Value ' ],
108
161
array_merge (
@@ -115,7 +168,7 @@ private function displayEntity(
115
168
$ this ->formatField ('Embedded class? ' , $ metadata ->isEmbeddedClass ),
116
169
$ this ->formatField ('Parent classes ' , $ metadata ->parentClasses ),
117
170
$ this ->formatField ('Sub classes ' , $ metadata ->subClasses ),
118
- $ this ->formatField ('Embedded classes ' , $ metadata ->subClasses ),
171
+ $ this ->formatField ('Embedded classes ' , $ metadata ->embeddedClasses ),
119
172
$ this ->formatField ('Identifier ' , $ metadata ->identifier ),
120
173
$ this ->formatField ('Inheritance type ' , $ metadata ->inheritanceType ),
121
174
$ this ->formatField ('Discriminator column ' , $ metadata ->discriminatorColumn ),
@@ -240,6 +293,22 @@ private function formatValue(mixed $value): string
240
293
throw new InvalidArgumentException (sprintf ('Do not know how to format value "%s" ' , print_r ($ value , true )));
241
294
}
242
295
296
+ /** @throws JsonException */
297
+ private function formatValueToJson (mixed $ value ): mixed
298
+ {
299
+ if (is_object ($ value )) {
300
+ $ value = (array ) $ value ;
301
+ }
302
+
303
+ if (is_array ($ value )) {
304
+ foreach ($ value as $ k => $ v ) {
305
+ $ value [$ k ] = $ this ->formatValueToJson ($ v );
306
+ }
307
+ }
308
+
309
+ return $ value ;
310
+ }
311
+
243
312
/**
244
313
* Add the given label and value to the two column table output
245
314
*
@@ -281,6 +350,22 @@ private function formatMappings(array $propertyMappings): array
281
350
return $ output ;
282
351
}
283
352
353
+ /**
354
+ * @param array<string, FieldMapping|AssociationMapping> $propertyMappings
355
+ *
356
+ * @return array<string, mixed>
357
+ */
358
+ private function formatMappingsToJson (array $ propertyMappings ): array
359
+ {
360
+ $ output = [];
361
+
362
+ foreach ($ propertyMappings as $ propertyName => $ mapping ) {
363
+ $ output [$ propertyName ] = $ this ->formatValueToJson ((array ) $ mapping );
364
+ }
365
+
366
+ return $ output ;
367
+ }
368
+
284
369
/**
285
370
* Format the entity listeners
286
371
*
@@ -293,4 +378,10 @@ private function formatEntityListeners(array $entityListeners): array
293
378
{
294
379
return $ this ->formatField ('Entity listeners ' , array_map ('get_class ' , $ entityListeners ));
295
380
}
381
+
382
+ /** @return string[] */
383
+ private function getAvailableFormatOptions (): array
384
+ {
385
+ return ['text ' , 'json ' ];
386
+ }
296
387
}
0 commit comments