1<?php
2
3declare(strict_types=1);
4
5namespace Metadata\Driver;
6
7class FileLocator implements AdvancedFileLocatorInterface
8{
9    /**
10     * @var string[]
11     */
12    private $dirs;
13
14    /**
15     * @param string[] $dirs
16     */
17    public function __construct(array $dirs)
18    {
19        $this->dirs = $dirs;
20    }
21
22    public function findFileForClass(\ReflectionClass $class, string $extension): ?string
23    {
24        foreach ($this->dirs as $prefix => $dir) {
25            if ('' !== $prefix && 0 !== strpos($class->getNamespaceName(), $prefix)) {
26                continue;
27            }
28
29            $len = '' === $prefix ? 0 : strlen($prefix) + 1;
30            $path = $dir . '/' . str_replace('\\', '.', substr($class->name, $len)) . '.' . $extension;
31            if (file_exists($path)) {
32                return $path;
33            }
34        }
35
36        return null;
37    }
38
39    /**
40     * {@inheritDoc}
41     */
42    public function findAllClasses(string $extension): array
43    {
44        $classes = [];
45        foreach ($this->dirs as $prefix => $dir) {
46            /** @var \RecursiveIteratorIterator|\SplFileInfo[] $iterator */
47            $iterator = new \RecursiveIteratorIterator(
48                new \RecursiveDirectoryIterator($dir),
49                \RecursiveIteratorIterator::LEAVES_ONLY
50            );
51            $nsPrefix = '' !== $prefix ? $prefix . '\\' : '';
52            foreach ($iterator as $file) {
53                if (($fileName = $file->getBasename('.' . $extension)) === $file->getBasename()) {
54                    continue;
55                }
56
57                $classes[] = $nsPrefix . str_replace('.', '\\', $fileName);
58            }
59        }
60
61        return $classes;
62    }
63}
64