1 | <?php |
||
37 | final class MappingDescribeCommand extends Command |
||
38 | { |
||
39 | /** |
||
40 | * {@inheritdoc} |
||
41 | */ |
||
42 | 3 | protected function configure() |
|
59 | |||
60 | /** |
||
61 | * {@inheritdoc} |
||
62 | */ |
||
63 | 3 | protected function execute(InputInterface $input, OutputInterface $output) |
|
72 | |||
73 | /** |
||
74 | * Display all the mapping information for a single Entity. |
||
75 | * |
||
76 | * @param string $entityName Full or partial entity class name |
||
77 | * @param EntityManagerInterface $entityManager |
||
78 | * @param OutputInterface $output |
||
79 | */ |
||
80 | 3 | private function displayEntity($entityName, EntityManagerInterface $entityManager, OutputInterface $output) |
|
81 | { |
||
82 | 3 | $table = new Table($output); |
|
83 | |||
84 | 3 | $table->setHeaders(['Field', 'Value']); |
|
85 | |||
86 | 3 | $metadata = $this->getClassMetadata($entityName, $entityManager); |
|
87 | |||
88 | 1 | array_map( |
|
89 | 1 | [$table, 'addRow'], |
|
90 | 1 | array_merge( |
|
91 | [ |
||
92 | 1 | $this->formatField('Name', $metadata->name), |
|
93 | 1 | $this->formatField('Root entity name', $metadata->rootEntityName), |
|
94 | 1 | $this->formatField('Custom generator definition', $metadata->customGeneratorDefinition), |
|
95 | 1 | $this->formatField('Custom repository class', $metadata->customRepositoryClassName), |
|
96 | 1 | $this->formatField('Mapped super class?', $metadata->isMappedSuperclass), |
|
97 | 1 | $this->formatField('Embedded class?', $metadata->isEmbeddedClass), |
|
98 | 1 | $this->formatField('Parent classes', $metadata->parentClasses), |
|
99 | 1 | $this->formatField('Sub classes', $metadata->subClasses), |
|
100 | 1 | $this->formatField('Embedded classes', $metadata->subClasses), |
|
101 | 1 | $this->formatField('Named queries', $metadata->namedQueries), |
|
102 | 1 | $this->formatField('Named native queries', $metadata->namedNativeQueries), |
|
103 | 1 | $this->formatField('SQL result set mappings', $metadata->sqlResultSetMappings), |
|
104 | 1 | $this->formatField('Identifier', $metadata->identifier), |
|
105 | 1 | $this->formatField('Inheritance type', $metadata->inheritanceType), |
|
106 | 1 | $this->formatField('Discriminator column', $metadata->discriminatorColumn), |
|
107 | 1 | $this->formatField('Discriminator value', $metadata->discriminatorValue), |
|
108 | 1 | $this->formatField('Discriminator map', $metadata->discriminatorMap), |
|
109 | 1 | $this->formatField('Generator type', $metadata->generatorType), |
|
110 | 1 | $this->formatField('Table', $metadata->table), |
|
111 | 1 | $this->formatField('Composite identifier?', $metadata->isIdentifierComposite), |
|
112 | 1 | $this->formatField('Foreign identifier?', $metadata->containsForeignIdentifier), |
|
113 | 1 | $this->formatField('Sequence generator definition', $metadata->sequenceGeneratorDefinition), |
|
114 | 1 | $this->formatField('Table generator definition', $metadata->tableGeneratorDefinition), |
|
115 | 1 | $this->formatField('Change tracking policy', $metadata->changeTrackingPolicy), |
|
116 | 1 | $this->formatField('Versioned?', $metadata->isVersioned), |
|
117 | 1 | $this->formatField('Version field', $metadata->versionField), |
|
118 | 1 | $this->formatField('Read only?', $metadata->isReadOnly), |
|
119 | |||
120 | 1 | $this->formatEntityListeners($metadata->entityListeners), |
|
121 | ], |
||
122 | 1 | [$this->formatField('Association mappings:', '')], |
|
123 | 1 | $this->formatMappings($metadata->associationMappings), |
|
124 | 1 | [$this->formatField('Field mappings:', '')], |
|
125 | 1 | $this->formatMappings($metadata->fieldMappings) |
|
126 | ) |
||
127 | ); |
||
128 | |||
129 | 1 | $table->render(); |
|
130 | 1 | } |
|
131 | |||
132 | /** |
||
133 | * Return all mapped entity class names |
||
134 | * |
||
135 | * @param EntityManagerInterface $entityManager |
||
136 | * |
||
137 | * @return string[] |
||
138 | */ |
||
139 | 3 | private function getMappedEntities(EntityManagerInterface $entityManager) |
|
155 | |||
156 | /** |
||
157 | * Return the class metadata for the given entity |
||
158 | * name |
||
159 | * |
||
160 | * @param string $entityName Full or partial entity name |
||
161 | * @param EntityManagerInterface $entityManager |
||
162 | * |
||
163 | * @return \Doctrine\ORM\Mapping\ClassMetadata |
||
164 | */ |
||
165 | 3 | private function getClassMetadata($entityName, EntityManagerInterface $entityManager) |
|
166 | { |
||
167 | try { |
||
168 | 3 | return $entityManager->getClassMetadata($entityName); |
|
169 | 3 | } catch (MappingException $e) { |
|
170 | } |
||
171 | |||
172 | 3 | $matches = array_filter( |
|
173 | 3 | $this->getMappedEntities($entityManager), |
|
174 | 3 | function ($mappedEntity) use ($entityName) { |
|
175 | 3 | return preg_match('{' . preg_quote($entityName) . '}', $mappedEntity); |
|
176 | 3 | } |
|
177 | ); |
||
178 | |||
179 | 3 | if ( ! $matches) { |
|
180 | 1 | throw new \InvalidArgumentException(sprintf( |
|
181 | 1 | 'Could not find any mapped Entity classes matching "%s"', |
|
182 | 1 | $entityName |
|
183 | )); |
||
184 | } |
||
185 | |||
186 | 2 | if (count($matches) > 1) { |
|
187 | 1 | throw new \InvalidArgumentException(sprintf( |
|
188 | 1 | 'Entity name "%s" is ambiguous, possible matches: "%s"', |
|
189 | 1 | $entityName, implode(', ', $matches) |
|
190 | )); |
||
191 | } |
||
192 | |||
193 | 1 | return $entityManager->getClassMetadata(current($matches)); |
|
194 | } |
||
195 | |||
196 | /** |
||
197 | * Format the given value for console output |
||
198 | * |
||
199 | * @param mixed $value |
||
200 | * |
||
201 | * @return string |
||
202 | */ |
||
203 | 1 | private function formatValue($value) |
|
239 | |||
240 | /** |
||
241 | * Add the given label and value to the two column table output |
||
242 | * |
||
243 | * @param string $label Label for the value |
||
244 | * @param mixed $value A Value to show |
||
245 | * |
||
246 | * @return array |
||
247 | */ |
||
248 | 1 | private function formatField($label, $value) |
|
256 | |||
257 | /** |
||
258 | * Format the association mappings |
||
259 | * |
||
260 | * @param array $propertyMappings |
||
261 | * |
||
262 | * @return array |
||
263 | */ |
||
264 | 1 | private function formatMappings(array $propertyMappings) |
|
278 | |||
279 | /** |
||
280 | * Format the entity listeners |
||
281 | * |
||
282 | * @param array $entityListeners |
||
283 | * |
||
284 | * @return array |
||
285 | */ |
||
286 | 1 | private function formatEntityListeners(array $entityListeners) |
|
298 | } |
||
299 |
Let’s take a look at an example:
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.
Available Fixes
Change the type-hint for the parameter:
Add an additional type-check:
Add the method to the interface: