1<?php
2
3declare(strict_types=1);
4
5namespace Metadata\Driver;
6
7use Metadata\ClassMetadata;
8
9final class DriverChain implements AdvancedDriverInterface
10{
11    /**
12     * @var DriverInterface[]
13     */
14    private $drivers;
15
16    /**
17     * @param DriverInterface[] $drivers
18     */
19    public function __construct(array $drivers = [])
20    {
21        $this->drivers = $drivers;
22    }
23
24    public function addDriver(DriverInterface $driver): void
25    {
26        $this->drivers[] = $driver;
27    }
28
29    public function loadMetadataForClass(\ReflectionClass $class): ?ClassMetadata
30    {
31        foreach ($this->drivers as $driver) {
32            if (null !== $metadata = $driver->loadMetadataForClass($class)) {
33                return $metadata;
34            }
35        }
36
37        return null;
38    }
39
40    /**
41     * {@inheritDoc}
42     */
43    public function getAllClassNames(): array
44    {
45        $classes = [];
46        foreach ($this->drivers as $driver) {
47            if (!$driver instanceof AdvancedDriverInterface) {
48                throw new \RuntimeException(
49                    sprintf(
50                        'Driver "%s" must be an instance of "AdvancedDriverInterface" to use ' .
51                        '"DriverChain::getAllClassNames()".',
52                        get_class($driver)
53                    )
54                );
55            }
56            $driverClasses = $driver->getAllClassNames();
57            if (!empty($driverClasses)) {
58                $classes = array_merge($classes, $driverClasses);
59            }
60        }
61
62        return $classes;
63    }
64}
65