@@ -31,13 +31,15 @@ class DebugCommand extends Command
3131
3232private $ twig ;
3333private $ projectDir ;
34+ private $ bundlesMetadata ;
3435
35- public function __construct (Environment $ twig ,string $ projectDir =null )
36+ public function __construct (Environment $ twig ,string $ projectDir =null , array $ bundlesMetadata = array () )
3637 {
3738parent ::__construct ();
3839
3940$ this ->twig =$ twig ;
4041$ this ->projectDir =$ projectDir ;
42+ $ this ->bundlesMetadata =$ bundlesMetadata ;
4143 }
4244
4345protected function configure ()
@@ -83,6 +85,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
8385$ data ['tests ' ] =array_keys ($ data ['tests ' ]);
8486$ data ['loader_paths ' ] =$ this ->getLoaderPaths ();
8587$ io ->writeln (json_encode ($ data ));
88+ $ this ->displayAlternatives ($ this ->findWrongBundleOverrides ($ data ['loader_paths ' ]),$ io );
8689
8790return 0 ;
8891 }
@@ -108,7 +111,8 @@ protected function execute(InputInterface $input, OutputInterface $output)
108111 }
109112
110113$ rows =array ();
111- foreach ($ this ->getLoaderPaths ()as $ namespace =>$ paths ) {
114+ $ loaderPaths =$ this ->getLoaderPaths ();
115+ foreach ($ loaderPathsas $ namespace =>$ paths ) {
112116if (count ($ paths ) >1 ) {
113117$ rows [] =array ('' ,'' );
114118 }
@@ -123,6 +127,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
123127array_pop ($ rows );
124128$ io ->section ('Loader Paths ' );
125129$ io ->table (array ('Namespace ' ,'Paths ' ),$ rows );
130+ $ this ->displayAlternatives ($ this ->findWrongBundleOverrides ($ loaderPaths ),$ io );
126131
127132return 0 ;
128133 }
@@ -242,4 +247,63 @@ private function getPrettyMetadata($type, $entity)
242247return $ meta ?'( ' .implode (', ' ,$ meta ).') ' :'' ;
243248 }
244249 }
250+
251+ private function findWrongBundleOverrides ($ loaderPaths )
252+ {
253+ $ alternatives =array ();
254+ $ paths =array_unique ($ loaderPaths ['(None) ' ]);
255+ $ bundleNames =array ();
256+ foreach ($ pathsas $ path ) {
257+ $ relativePath =$ path .'/bundles/ ' ;
258+ if (file_exists ($ dir =$ this ->projectDir .'/ ' .$ relativePath )) {
259+ $ folders =glob ($ dir .'* ' ,GLOB_ONLYDIR );
260+ $ bundleNames =array_reduce ($ folders ,function ($ carry ,$ absolutePath )use ($ relativePath ) {
261+ if (null !==$ this ->projectDir &&0 ===strpos ($ absolutePath ,$ this ->projectDir )) {
262+ $ path =ltrim (substr ($ absolutePath ,\strlen ($ this ->projectDir )),DIRECTORY_SEPARATOR );
263+ $ name =ltrim (substr ($ path ,\strlen ($ relativePath )),DIRECTORY_SEPARATOR );
264+ $ carry [$ name ] =$ path ;
265+ }
266+
267+ return $ carry ;
268+ },$ bundleNames );
269+ }
270+ }
271+
272+ if (\count ($ bundleNames )) {
273+ $ loadedBundles =$ this ->bundlesMetadata ;
274+ $ notFoundBundles =array_diff_key ($ bundleNames ,$ loadedBundles );
275+ if (\count ($ notFoundBundles )) {
276+ $ alternatives =array ();
277+ foreach ($ notFoundBundlesas $ notFoundBundle =>$ path ) {
278+ $ alternatives [$ path ] =array ();
279+ foreach ($ loadedBundlesas $ name =>$ bundle ) {
280+ $ lev =levenshtein ($ notFoundBundle ,$ name );
281+ if ($ lev <=\strlen ($ notFoundBundle ) /3 ||false !==strpos ($ name ,$ notFoundBundle )) {
282+ $ alternatives [$ path ][] =$ name ;
283+ }
284+ }
285+ }
286+ }
287+ }
288+
289+ return $ alternatives ;
290+ }
291+
292+ private function displayAlternatives (array $ wrongBundles ,SymfonyStyle $ io )
293+ {
294+ foreach ($ wrongBundlesas $ path =>$ alternatives ) {
295+ $ message =sprintf ('Path "%s" not matching any bundle found ' ,$ path );
296+ if ($ alternatives ) {
297+ if (1 ===\count ($ alternatives )) {
298+ $ message .=sprintf (", did you mean \"%s \"? \n" ,$ alternatives [0 ]);
299+ }else {
300+ $ message .=", did you mean one of these: \n" ;
301+ foreach ($ alternativesas $ bundle ) {
302+ $ message .=sprintf (" - %s \n" ,$ bundle );
303+ }
304+ }
305+ }
306+ $ io ->warning (trim ($ message ));
307+ }
308+ }
245309}