Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
/*
4
 * This file is part of the Symfony package.
5
 *
6
 * (c) Fabien Potencier <fabien@symfony.com>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
 
12
namespace Symfony\Component\Routing\Loader;
13
 
14
use Symfony\Component\Config\FileLocatorInterface;
15
use Symfony\Component\Config\Loader\DirectoryAwareLoaderInterface;
16
use Symfony\Component\Config\Loader\Loader;
17
use Symfony\Component\Config\Resource\DirectoryResource;
18
use Symfony\Component\Routing\RouteCollection;
19
 
20
/**
21
 * A loader that discovers controller classes in a directory that follows PSR-4.
22
 *
23
 * @author Alexander M. Turek <me@derrabus.de>
24
 */
25
final class Psr4DirectoryLoader extends Loader implements DirectoryAwareLoaderInterface
26
{
27
    private ?string $currentDirectory = null;
28
 
29
    public function __construct(
30
        private readonly FileLocatorInterface $locator,
31
    ) {
32
        // PSR-4 directory loader has no env-aware logic, so we drop the $env constructor parameter.
33
        parent::__construct();
34
    }
35
 
36
    /**
37
     * @param array{path: string, namespace: string} $resource
38
     */
39
    public function load(mixed $resource, string $type = null): ?RouteCollection
40
    {
41
        $path = $this->locator->locate($resource['path'], $this->currentDirectory);
42
        if (!is_dir($path)) {
43
            return new RouteCollection();
44
        }
45
 
46
        return $this->loadFromDirectory($path, trim($resource['namespace'], '\\'));
47
    }
48
 
49
    public function supports(mixed $resource, string $type = null): bool
50
    {
51
        return ('attribute' === $type || 'annotation' === $type) && \is_array($resource) && isset($resource['path'], $resource['namespace']);
52
    }
53
 
54
    public function forDirectory(string $currentDirectory): static
55
    {
56
        $loader = clone $this;
57
        $loader->currentDirectory = $currentDirectory;
58
 
59
        return $loader;
60
    }
61
 
62
    private function loadFromDirectory(string $directory, string $psr4Prefix): RouteCollection
63
    {
64
        $collection = new RouteCollection();
65
        $collection->addResource(new DirectoryResource($directory, '/\.php$/'));
66
        $files = iterator_to_array(new \RecursiveIteratorIterator(
67
            new \RecursiveCallbackFilterIterator(
68
                new \RecursiveDirectoryIterator($directory, \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS),
69
                function (\SplFileInfo $current) {
70
                    return !str_starts_with($current->getBasename(), '.');
71
                }
72
            ),
73
            \RecursiveIteratorIterator::SELF_FIRST
74
        ));
75
        usort($files, function (\SplFileInfo $a, \SplFileInfo $b) {
76
            return (string) $a > (string) $b ? 1 : -1;
77
        });
78
 
79
        /** @var \SplFileInfo $file */
80
        foreach ($files as $file) {
81
            if ($file->isDir()) {
82
                $collection->addCollection($this->loadFromDirectory($file->getPathname(), $psr4Prefix.'\\'.$file->getFilename()));
83
 
84
                continue;
85
            }
86
            if ('php' !== $file->getExtension() || !class_exists($className = $psr4Prefix.'\\'.$file->getBasename('.php')) || (new \ReflectionClass($className))->isAbstract()) {
87
                continue;
88
            }
89
 
90
            $collection->addCollection($this->import($className, 'attribute'));
91
        }
92
 
93
        return $collection;
94
    }
95
}