@@ -46,6 +46,7 @@ public function __construct(KernelInterface $kernel)
46
46
*/
47
47
public function parse ($ controller )
48
48
{
49
+ $ originalController = $ controller ;
49
50
if (3 != count ($ parts = explode (': ' , $ controller ))) {
50
51
throw new \InvalidArgumentException (sprintf ('The "%s" controller is not a valid "a:b:c" controller string. ' , $ controller ));
51
52
}
@@ -54,8 +55,24 @@ public function parse($controller)
54
55
$ controller = str_replace ('/ ' , '\\' , $ controller );
55
56
$ bundles = array ();
56
57
57
- // this throws an exception if there is no such bundle
58
- foreach ($ this ->kernel ->getBundle ($ bundle , false ) as $ b ) {
58
+ try {
59
+ // this throws an exception if there is no such bundle
60
+ $ allBundles = $ this ->kernel ->getBundle ($ bundle , false );
61
+ } catch (\InvalidArgumentException $ e ) {
62
+ $ message = sprintf (
63
+ 'The "%s" (from the _controller value "%s") does not exist! ' ,
64
+ $ bundle ,
65
+ $ originalController
66
+ );
67
+
68
+ if ($ alternative = $ this ->findAlternative ($ bundle )) {
69
+ $ message .= sprintf (' Did you mean "%s:%s:%s"? ' , $ alternative , $ controller , $ action );
70
+ }
71
+
72
+ throw new \InvalidArgumentException ($ message );
73
+ }
74
+
75
+ foreach ($ allBundles as $ b ) {
59
76
$ try = $ b ->getNamespace ().'\\Controller \\' .$ controller .'Controller ' ;
60
77
if (class_exists ($ try )) {
61
78
return $ try .':: ' .$ action .'Action ' ;
@@ -100,4 +117,27 @@ public function build($controller)
100
117
101
118
throw new \InvalidArgumentException (sprintf ('Unable to find a bundle that defines controller "%s". ' , $ controller ));
102
119
}
120
+
121
+ private function findAlternative ($ nonExistentBundleName )
122
+ {
123
+ $ bundleNames = array_map (function ($ b ) {
124
+ return $ b ->getName ();
125
+ }, $ this ->kernel ->getBundles ());
126
+
127
+ $ alternative = null ;
128
+ $ shortest = null ;
129
+ foreach ($ bundleNames as $ bundleName ) {
130
+ // if there's a partial match, return it immediately
131
+ if (false !== strpos ($ bundleName , $ nonExistentBundleName )) {
132
+ return $ bundleName ;
133
+ }
134
+
135
+ $ lev = levenshtein ($ nonExistentBundleName , $ bundleName );
136
+ if ($ lev <= strlen ($ nonExistentBundleName ) / 3 && ($ alternative === null || $ lev < $ shortest )) {
137
+ $ alternative = $ bundleName ;
138
+ }
139
+ }
140
+
141
+ return $ alternative ;
142
+ }
103
143
}
0 commit comments