cache = $cache; if ($callback !== null) { $this->callback = $callback; } if ($folderList !== null) { $this->folderList = $folderList; } if ($annotations !== null) { $this->annotations = $annotations; } else { $this->annotations = [ 'object' => [ Attribute\Object\Route::class ], 'method' => [ Attribute\Method\Route::class ], ]; } } public function addFolder($folder) : void { $this->folderList[] = $folder; } public function setFolderList(array $list) : void { $this->folderList = $list; } public function scan(? array $folders = null) : Generator { foreach($folders ?: $this->folderList as $namespace => $folder) { if ( ! file_exists($folder) ) { throw new RuntimeException(sprintf("Folder `%s` can not be found or scanned", $folder)); } foreach (new DirectoryIterator($folder) as $fileinfo) { if ( ! $fileinfo->isDot() ) { if ( $fileinfo->isDir() ) { foreach($this->scan([ "{$namespace}\\" . $fileinfo->getBasename() => $fileinfo->getPathname() ]) as $ns2 => $fi2) { yield $ns2 => $fi2; } } else { yield $namespace => $fileinfo; } } } } } public function compile(null|array $annotations = null) : array { $annotations ??= $this->annotations; return $this->handleCaching(substr(md5(serialize($annotations)), 0, 7), function() use ($annotations) : array { $list = []; foreach($this->scan() as $namespace => $file) { if ( $file->getExtension() !== "php" ) { continue; } $base = ""; $class = $this->generateClassname($file->getBasename(".php"), $namespace); $methods = $this->defaultMethods; $objectResolver = new ObjectResolver($class, true, true, false, true, $this->cache); if ( isset($annotations['object']) ) { $object = $objectResolver->getAttributeFromClassname($annotations['object'], false) ?: $objectResolver->getAnnotationFromClassname($annotations['object'], false); if ($object) { if ( $object->methods ?? false ) { $methods = $object->methods; } elseif ($object->method ?? false ) { $methods = (array) $object->method; } $base = $object->base ?? ""; } } if ( isset($annotations['method']) ) { $routeList = $objectResolver->getAttributeListFromClassname( $annotations['method'], false ); foreach($routeList as $func => $routes) { if (is_array($routes)) { foreach ($routes as $route) { $route->base = $base; $route->class = $class; $route->classMethod = $func; if (false === ($route->methods ?? false)) { $route->methods = $methods; } if (false !== ($this->callback ?? false)) { call_user_func_array($this->callback, [$route]); } $list[] = $route; } } } } } return $list; }); } protected function generateClassname($file, $namespace) { return "\\$namespace\\$file"; } }