diff --git a/CHANGELOG.md b/CHANGELOG.md index 267dee1..e00645b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - Chg #115: Only a full path can now be used as a layout (@vjik) - Chg #116, #117, #118: Rename package to `yiisoft/yii-view-renderer` (@vjik) - Chg #119: Change package configuration parameters `viewPath` and `layout` to null (@vjik) +- Chg #64: Refactor controller name extractor, use greedy search of namespace items with "controller(s)" postfix (@vjik) ## 6.1.1 June 06, 2024 diff --git a/README.md b/README.md index 8ba06ba..33cdb5d 100644 --- a/README.md +++ b/README.md @@ -122,6 +122,8 @@ In this case the name is determined as follows: ```text App\Controller\FooBar\BazController -> foo-bar/baz App\Controllers\FooBar\BazController -> foo-bar/baz +App\AllControllers\MyController\FooBar\BazController -> foo-bar/baz +App\AllControllers\MyController\BazController -> baz Path\To\File\BlogController -> blog ``` diff --git a/UPGRADE.md b/UPGRADE.md index d79ddf1..5bbe78f 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -22,3 +22,7 @@ application when you upgrade the package from one version to another. 'layout' => '@layout/main.php', ], ``` + +- Controller name extractor now uses greedy search of namespace items with "controller(s)" postfix. For example, for controller namespace `App\AllControllers\MyController\FooBar\BazController` previously, + result was "controller/foo-bar/baz", now it is "foo-bar/baz". You can use `ViewRenderer::withControllerName()` + instead of `ViewRenderer::withController()` to explicitly define controller name. diff --git a/src/ViewRenderer.php b/src/ViewRenderer.php index 37ea21c..f6205a3 100644 --- a/src/ViewRenderer.php +++ b/src/ViewRenderer.php @@ -525,6 +525,8 @@ private function injectLinkTags(array $tags, WebView $view): void * * @example App\Controller\FooBar\BazController -> foo-bar/baz * @example App\Controllers\FooBar\BazController -> foo-bar/baz + * @example App\AllControllers\MyController\FooBar\BazController -> foo-bar/baz + * @example App\AllControllers\MyController\BazController -> baz * @example Path\To\File\BlogController -> blog * * @see Inflector::pascalCaseToId() @@ -539,14 +541,16 @@ private function extractControllerName(object $controller): string return $cache[$class]; } - $regexp = '/((?<=controller\\\|controllers\\\)(?:[\w\\\]+)|(?:[a-z\d]+))controller$/iU'; - if (!preg_match($regexp, $class, $m) || empty($m[1])) { + if (preg_match('/(?:.*controller\\\|.*controllers\\\)([\w\\\]+)controller$/iU', $class, $m) && !empty($m[1])) { + $name = $m[1]; + } elseif (preg_match('/(\w+)controller$/iU', $class, $m) && !empty($m[1])) { + $name = $m[1]; + } else { throw new RuntimeException('Cannot detect controller name.'); } - $inflector = new Inflector(); - $name = str_replace('\\', '/', $m[1]); - return $cache[$class] = $inflector->pascalCaseToId($name); + $name = str_replace('\\', '/', $name); + return $cache[$class] = (new Inflector())->pascalCaseToId($name); } /** diff --git a/tests/Support/AllControllers/MoreController/MyController.php b/tests/Support/AllControllers/MoreController/MyController.php new file mode 100644 index 0000000..9f11089 --- /dev/null +++ b/tests/Support/AllControllers/MoreController/MyController.php @@ -0,0 +1,9 @@ + [ + new Support\AllControllers\MoreController\MyController(), + '/my', + ], + 'several controller in namespace, nested' => [ + new Support\AllControllers\MoreController\Nested\MyController(), + '/nested/my', + ], ]; }