29
29
*/
30
30
class FormDebugCommand extends Command
31
31
{
32
- /** @var OptionsResolver */
32
+ private $ formRegistry ;
33
33
private $ optionsResolver ;
34
34
private $ parents = array ();
35
35
private $ extensions = array ();
36
- private $ formRegistry ;
36
+ private $ typesFound = array () ;
37
37
38
38
public function __construct (FormRegistryInterface $ formRegistry )
39
39
{
@@ -62,8 +62,8 @@ protected function configure()
62
62
protected function execute (InputInterface $ input , OutputInterface $ output )
63
63
{
64
64
$ class = $ input ->getArgument ('class ' );
65
- if (!class_exists ($ class )) {
66
- $ class = $ this ->getBuiltinFormTypeClass ($ class );
65
+ if (!class_exists ($ class ) && false === mb_strpos ( $ class , '\\' ) ) {
66
+ $ class = $ this ->findFormTypeClass ($ class );
67
67
}
68
68
69
69
$ type = $ this ->formRegistry ->getType ($ class );
@@ -83,6 +83,13 @@ protected function execute(InputInterface $input, OutputInterface $output)
83
83
$ io ->section ('Type extensions ' );
84
84
$ io ->listing (array_keys ($ this ->extensions ));
85
85
}
86
+
87
+ if (count ($ this ->typesFound ) > 1 ) {
88
+ $ io ->block ('Similar form types found: ' , null , 'info ' );
89
+ $ io ->listing (array_slice ($ this ->typesFound , 1 ));
90
+ $ io ->comment ('To search for a specific class, re-run this command with the fully-qualified class name. ' );
91
+ $ io ->comment (sprintf ('e.g. <comment>debug:form \'%s \'</comment> ' , $ this ->typesFound [1 ]));
92
+ }
86
93
}
87
94
88
95
private function getOptionsGroup (ResolvedFormTypeInterface $ type )
@@ -145,20 +152,48 @@ private function getParentOptionResolver(ResolvedFormTypeInterface $type)
145
152
return $ optionsResolver ;
146
153
}
147
154
148
- private function getBuiltinFormTypeClass ( $ class )
155
+ private function findFormTypeClass ( $ shortClassName )
149
156
{
150
- $ namespaces = array (
151
- 'Symfony \\Component \\Form \\Extension \\Core \\Type ' ,
152
- 'Symfony \\Bridge \\Doctrine \\Form \\Type ' ,
153
- );
157
+ $ namespaces = $ this ->getRegisteredFormNamespaces ();
154
158
155
159
foreach ($ namespaces as $ namespace ) {
156
- if (class_exists ($ fqcn = $ namespace .'\\' .$ class )) {
157
- return $ fqcn ;
160
+ if (class_exists ($ fqcn = $ namespace .'\\' .$ shortClassName )) {
161
+ $ this -> typesFound [] = $ fqcn ;
158
162
}
159
163
}
160
164
161
- throw new \InvalidArgumentException (sprintf ('Could not find built-in type "%s" into the following namespaces: %s. ' , $ class , implode (', ' , $ namespaces )));
165
+ if (0 === count ($ this ->typesFound )) {
166
+ throw new \InvalidArgumentException (sprintf ('Could not find type "%s" into the following namespaces: %s. ' , $ shortClassName , implode (', ' , $ namespaces )));
167
+ }
168
+
169
+ return $ this ->typesFound [0 ];
170
+ }
171
+
172
+ private function getRegisteredFormNamespaces ()
173
+ {
174
+ // Registered form namespaces
175
+ $ types = array ();
176
+ foreach ($ this ->formRegistry ->getExtensions () as $ extension ) {
177
+ $ refTypeContainer = (new \ReflectionObject ($ extension ))->getProperty ('typeContainer ' );
178
+ $ refTypeContainer ->setAccessible (true );
179
+ $ typeContainer = $ refTypeContainer ->getValue ($ extension );
180
+
181
+ $ refFactories = (new \ReflectionObject ($ typeContainer ))->getProperty ('factories ' );
182
+ $ refFactories ->setAccessible (true );
183
+
184
+ $ types = array_merge ($ types , array_keys ($ refFactories ->getValue ($ typeContainer )));
185
+ }
186
+ $ registeredNamespaces = array_map (function ($ class ) {
187
+ return substr ($ class , 0 , strrpos ($ class , '\\' ));
188
+ }, $ types );
189
+
190
+ // Core namespaces
191
+ $ coreNamespaces = array (
192
+ 'Symfony \\Bridge \\Doctrine \\Form \\Type ' ,
193
+ 'Symfony \\Component \\Form \\Extension \\Core \\Type ' ,
194
+ );
195
+
196
+ return array_unique (array_merge ($ registeredNamespaces , $ coreNamespaces ));
162
197
}
163
198
164
199
private function buildTableContent ($ options )
0 commit comments