芝麻web文件管理V1.00
编辑当前文件:/home/qrafawbu/minscoop.com/system/Commands/Utilities/Routes/ControllerMethodReader.php
* * 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
* @phpstan-return list
*/ 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; } }