Viewing file: ControllerMethodReader.php (4.97 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php
/** * This file is part of CodeIgniter 4 framework. * * (c) CodeIgniter Foundation <admin@codeigniter.com> * * For the full copyright and license information, please view * the LICENSE file that was distributed with this source code. */
namespace CodeIgniter\Commands\Utilities\Routes;
use ReflectionClass; use ReflectionMethod;
/** * Reads a controller and returns a list of auto route listing. */ final class ControllerMethodReader { /** * @var string the default namespace */ private string $namespace;
/** * @param string $namespace the default namespace */ public function __construct(string $namespace) { $this->namespace = $namespace; }
/** * @phpstan-param class-string $class * * @return array<int, array{route: string, handler: string}> * @phpstan-return list<array{route: string, handler: string}> */ public function read(string $class, string $defaultController = 'Home', string $defaultMethod = 'index'): array { $reflection = new ReflectionClass($class);
if ($reflection->isAbstract()) { return []; }
$classname = $reflection->getName(); $classShortname = $reflection->getShortName();
$output = []; $uriByClass = $this->getUriByClass($classname);
if ($this->hasRemap($reflection)) { $methodName = '_remap';
$routeWithoutController = $this->getRouteWithoutController( $classShortname, $defaultController, $uriByClass, $classname, $methodName ); $output = [...$output, ...$routeWithoutController];
$output[] = [ 'route' => $uriByClass . '[/...]', 'handler' => '\\' . $classname . '::' . $methodName, ];
return $output; }
foreach ($reflection->getMethods(ReflectionMethod::IS_PUBLIC) as $method) { $methodName = $method->getName();
$route = $uriByClass . '/' . $methodName;
// Exclude BaseController and initController // See system/Config/Routes.php if (preg_match('#\AbaseController.*#', $route) === 1) { continue; } if (preg_match('#.*/initController\z#', $route) === 1) { continue; }
if ($methodName === $defaultMethod) { $routeWithoutController = $this->getRouteWithoutController( $classShortname, $defaultController, $uriByClass, $classname, $methodName ); $output = [...$output, ...$routeWithoutController];
$output[] = [ 'route' => $uriByClass, 'handler' => '\\' . $classname . '::' . $methodName, ]; }
$output[] = [ 'route' => $route . '[/...]', 'handler' => '\\' . $classname . '::' . $methodName, ]; }
return $output; }
/** * Whether the class has a _remap() method. */ private function hasRemap(ReflectionClass $class): bool { if ($class->hasMethod('_remap')) { $remap = $class->getMethod('_remap');
return $remap->isPublic(); }
return false; }
/** * @phpstan-param class-string $classname * * @return string URI path part from the folder(s) and controller */ private function getUriByClass(string $classname): string { // remove the namespace $pattern = '/' . preg_quote($this->namespace, '/') . '/'; $class = ltrim(preg_replace($pattern, '', $classname), '\\');
$classParts = explode('\\', $class); $classPath = '';
foreach ($classParts as $part) { // make the first letter lowercase, because auto routing makes // the URI path's first letter uppercase and search the controller $classPath .= lcfirst($part) . '/'; }
return rtrim($classPath, '/'); }
/** * Gets a route without default controller. */ private function getRouteWithoutController( string $classShortname, string $defaultController, string $uriByClass, string $classname, string $methodName ): array { $output = [];
if ($classShortname === $defaultController) { $pattern = '#' . preg_quote(lcfirst($defaultController), '#') . '\z#'; $routeWithoutController = rtrim(preg_replace($pattern, '', $uriByClass), '/'); $routeWithoutController = $routeWithoutController ?: '/';
$output[] = [ 'route' => $routeWithoutController, 'handler' => '\\' . $classname . '::' . $methodName, ]; }
return $output; } }
|