Skip to content

Commit a3905b1

Browse files
committed
Refactor token replacement logic in Router and Admin helpers
- Introduce `resolveApiToken`, `replaceRuntimeTokens`, and `normalizeRouteModule` methods in `RouterHelper`. - Update `getTemplatePath` in `GeneratorHelper` for improved path resolution. - Add `resolveRouteLabel` method in `AdminHelper` to handle placeholders in labels. - Enhance tests to cover new token resolution logic in `AdminHelperTest` and `RouterHelperTest`.
1 parent e2997f0 commit a3905b1

5 files changed

Lines changed: 125 additions & 15 deletions

File tree

src/base/types/helpers/AdminHelper.php

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ protected static function extractAdminRoutes(array $systemRoutes): array
6161
$mode = $params['visible'] ? 'visible' : 'hidden';
6262
$routes[$module][$mode][] = [
6363
'slug' => $params['slug'],
64-
'label' => $params['label'] ?: $params['slug'],
64+
'label' => self::resolveRouteLabel($params),
6565
'icon' => $params['icon'],
6666
];
6767
}
@@ -83,4 +83,32 @@ protected static function sortRoutes(array &$routes): void
8383
}
8484
}
8585
}
86+
87+
private static function resolveRouteLabel(array $params): string
88+
{
89+
$label = (string)($params['label'] ?? $params['slug'] ?? '');
90+
if ($label === '') {
91+
return '';
92+
}
93+
94+
if (str_contains($label, '{__DOMAIN__}')) {
95+
$module = (string)($params['module'] ?? '');
96+
$label = str_replace('{__DOMAIN__}', $module, $label);
97+
}
98+
99+
if (!str_contains($label, '{__API__}')) {
100+
return $label;
101+
}
102+
103+
$defaultRoute = (string)($params['default'] ?? '');
104+
if (
105+
preg_match('/^\/admin\/[^\/]+\/([^\/]+)(?:\/.*)?$/', $defaultRoute, $matches) === 1
106+
&& isset($matches[1])
107+
&& $matches[1] !== ''
108+
) {
109+
return str_replace('{__API__}', $matches[1], $label);
110+
}
111+
112+
return $label;
113+
}
86114
}

src/base/types/helpers/GeneratorHelper.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,14 @@ public static function createDir($dir): void
7474
*/
7575
public static function getTemplatePath(): string
7676
{
77-
$path = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'templates' . DIRECTORY_SEPARATOR;
78-
return realpath($path);
77+
$path = __DIR__
78+
. DIRECTORY_SEPARATOR . '..'
79+
. DIRECTORY_SEPARATOR . '..'
80+
. DIRECTORY_SEPARATOR . '..'
81+
. DIRECTORY_SEPARATOR . 'templates';
82+
$resolvedPath = realpath($path);
83+
$finalPath = is_string($resolvedPath) && $resolvedPath !== '' ? $resolvedPath : $path;
84+
return rtrim($finalPath, '/\\') . DIRECTORY_SEPARATOR;
7985
}
8086

8187
/**

src/base/types/helpers/RouterHelper.php

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -201,26 +201,23 @@ public static function extractRouteInfo(ReflectionMethod $method, string $api =
201201
{
202202
$route = $info = null;
203203
$docComments = $method->getDocComment();
204+
$resolvedApi = self::resolveApiToken($method, $api);
204205
$regexpRoute = AnnotationHelper::extractRoute($docComments ?: '', $method);
205206
if (null !== $regexpRoute) {
206207
list($regex, $default, $params, $requirements) = RouterHelper::extractReflectionParams(
207208
$regexpRoute,
208209
$method
209210
);
210211
$originalRegex = $regex;
211-
if ('' !== $api && str_contains($regex, '__API__')) {
212-
$regex = str_replace('{__API__}', $api, $regex);
213-
$default = str_replace('{__API__}', $api, $default);
214-
}
215-
$regex = str_replace('{__DOMAIN__}', $module, $regex);
216-
$default = str_replace('{__DOMAIN__}', $module, $default);
212+
$regex = self::replaceRuntimeTokens($regex, $resolvedApi, $module);
213+
$default = self::replaceRuntimeTokens($default, $resolvedApi, $module);
217214
$httpMethod = AnnotationHelper::extractReflectionHttpMethod($docComments ?: '', $method);
218215
$icon = AnnotationHelper::extractDocIcon($docComments ?: '', $method);
219-
$label = (string)AnnotationHelper::extractReflectionLabel($docComments ?: '', $method);
220-
if ($label !== '') {
221-
$label = str_replace('{__API__}', $api, $label);
222-
$label = str_replace('{__DOMAIN__}', $module, $label);
223-
}
216+
$label = self::replaceRuntimeTokens(
217+
(string)AnnotationHelper::extractReflectionLabel($docComments ?: '', $method),
218+
$resolvedApi,
219+
$module
220+
);
224221
$route = $httpMethod . "#|#" . $regex;
225222
$route = preg_replace('/(\\r|\\f|\\t|\\n)/', '', $route);
226223
$info = [
@@ -230,7 +227,7 @@ public static function extractRouteInfo(ReflectionMethod $method, string $api =
230227
'pattern' => $originalRegex,
231228
'label' => $label,
232229
'icon' => strlen($icon) > 0 ? $icon : '',
233-
'module' => preg_replace('/(\\\|\\/)/', '', $module),
230+
'module' => self::normalizeRouteModule($module),
234231
'visible' => AnnotationHelper::extractReflectionVisibility($docComments ?: '', $method),
235232
'http' => $httpMethod,
236233
'cache' => AnnotationHelper::extractReflectionCacheability($docComments ?: '', $method),
@@ -240,6 +237,31 @@ public static function extractRouteInfo(ReflectionMethod $method, string $api =
240237
return [$route, $info];
241238
}
242239

240+
private static function resolveApiToken(ReflectionMethod $method, string $api): string
241+
{
242+
$candidate = trim($api);
243+
if ($candidate !== '') {
244+
return $candidate;
245+
}
246+
247+
return $method->getDeclaringClass()->getShortName();
248+
}
249+
250+
private static function replaceRuntimeTokens(string $value, string $api, string $module): string
251+
{
252+
if ($value === '') {
253+
return $value;
254+
}
255+
256+
$value = str_replace('{__API__}', $api, $value);
257+
return str_replace('{__DOMAIN__}', $module, $value);
258+
}
259+
260+
private static function normalizeRouteModule(string $module): string
261+
{
262+
return preg_replace('/(\\\|\\/)/', '', $module);
263+
}
264+
243265
/**
244266
*
245267
* @param string $text

tests/base/type/helper/AdminHelperTest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,21 @@ public function testGetAdminRoutesSkipsCanonicalManagerItemRoutesButKeepsOtherHi
5151
$this->assertSame('admin-switch-user', $routes['PSFS']['hidden'][0]['slug']);
5252
$this->assertArrayNotHasKey('hidden', $routes['DEMO']);
5353
}
54+
55+
public function testGetAdminRoutesResolvesApiPlaceholderFromDefaultRoute(): void
56+
{
57+
$routes = AdminHelper::getAdminRoutes([
58+
[
59+
'http' => 'GET',
60+
'default' => '/admin/core/books',
61+
'slug' => 'admin-core-books',
62+
'label' => '{__API__} Manager',
63+
'icon' => 'fa-database',
64+
'module' => 'CORE',
65+
'visible' => true,
66+
],
67+
]);
68+
69+
$this->assertSame('books Manager', $routes['CORE']['visible'][0]['label']);
70+
}
5471
}

tests/base/type/helper/RouterHelperTest.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,33 @@ public function testExtractRouteInfoReplacesApiPlaceholderInAttributeLabel(): vo
2626
$this->assertSame('Books Manager', $info['label']);
2727
$this->assertSame('/admin/PSFS/Books', $info['default']);
2828
}
29+
30+
public function testExtractRouteInfoUsesClassNameAsApiFallbackWhenApiMetadataMissing(): void
31+
{
32+
$method = new \ReflectionMethod(RouterHelperAttributeFixture::class, 'admin');
33+
[$route, $info] = RouterHelper::extractRouteInfo($method, '', 'PSFS');
34+
35+
$this->assertSame('GET#|#/admin/PSFS/RouterHelperAttributeFixture', $route);
36+
$this->assertSame('RouterHelperAttributeFixture Manager', $info['label']);
37+
$this->assertSame('/admin/PSFS/RouterHelperAttributeFixture', $info['default']);
38+
}
39+
40+
public function testExtractRouteInfoKeepsLabelWithoutTokensUntouched(): void
41+
{
42+
$method = new \ReflectionMethod(RouterHelperStaticLabelFixture::class, 'admin');
43+
[, $info] = RouterHelper::extractRouteInfo($method, '', 'PSFS');
44+
45+
$this->assertSame('Static Manager Label', $info['label']);
46+
}
47+
48+
public function testExtractRouteInfoTrimsApiInputBeforeReplacingTokens(): void
49+
{
50+
$method = new \ReflectionMethod(RouterHelperAttributeFixture::class, 'admin');
51+
[$route, $info] = RouterHelper::extractRouteInfo($method, ' Books ', 'PSFS');
52+
53+
$this->assertSame('GET#|#/admin/PSFS/Books', $route);
54+
$this->assertSame('Books Manager', $info['label']);
55+
}
2956
}
3057

3158
final class RouterHelperAttributeFixture
@@ -37,3 +64,13 @@ public function admin(): void
3764
{
3865
}
3966
}
67+
68+
final class RouterHelperStaticLabelFixture
69+
{
70+
#[HttpMethod('GET')]
71+
#[Label('Static Manager Label')]
72+
#[Route('/admin/{__DOMAIN__}/status')]
73+
public function admin(): void
74+
{
75+
}
76+
}

0 commit comments

Comments
 (0)