Passed
Branch 1.0 (f7255b)
by Vladimir
06:00
created

DriverManager::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 7
ccs 5
cts 5
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 2
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace FondBot\Drivers;
6
7
use FondBot\Helpers\Arr;
8
use FondBot\Channels\Channel;
9
use FondBot\Contracts\Container;
10
use TheCodingMachine\Discovery\Asset;
11
use TheCodingMachine\Discovery\Discovery;
12
use FondBot\Drivers\Exceptions\DriverNotFound;
13
use TheCodingMachine\Discovery\ImmutableAssetType;
14
use FondBot\Drivers\Exceptions\InvalidConfiguration;
15
16
class DriverManager
17
{
18
    protected $container;
19
    protected $discovery;
20
21
    /** @var Driver[] */
22
    protected $drivers;
23
24 3
    public function __construct(Container $container, Discovery $discovery = null)
25
    {
26 3
        $this->container = $container;
27 3
        $this->discovery = $discovery ?? Discovery::getInstance();
28
29 3
        $this->boot();
30 3
    }
31
32
    /**
33
     * Boot drivers.
34
     */
35 3
    protected function boot(): void
36
    {
37
        /** @var ImmutableAssetType $assets */
38 3
        $assets = $this->discovery->getAssetType(Driver::class);
39
40 3
        foreach ($assets->getAssets() as $asset) {
41 3
            $this->drivers[$asset->getMetadata()['name']] = $this->container->make($asset->getValue());
42
        }
43 3
    }
44
45
    /**
46
     * Get driver instance.
47
     *
48
     * @param Channel $channel
49
     *
50
     * @param array   $request
51
     * @param array   $headers
52
     * @param array   $parameters
53
     *
54
     * @return Driver
55
     * @throws DriverNotFound
56
     */
57 3
    public function get(Channel $channel, array $request = [], array $headers = [], array $parameters = []): Driver
58
    {
59 3
        $driver = $this->drivers[$channel->getDriver()];
60
61 3
        if ($driver === null) {
62 1
            throw new DriverNotFound('Driver `'.$channel->getDriver().'` not found.');
63
        }
64
65 2
        $this->validateParameters($channel, $driver);
66
67 1
        $driver->fill($parameters, $request, $headers);
68
69 1
        return $driver;
70
    }
71
72
    /**
73
     * Validate channel parameters with driver requirements.
74
     *
75
     * @param Channel $channel
76
     * @param Driver  $driver
77
     */
78 2
    protected function validateParameters(Channel $channel, Driver $driver): void
79
    {
80
        /** @var Asset $asset */
81 2
        $asset = collect($this->discovery->getAssetType(Driver::class)->getAssets())
82
            ->first(function (Asset $asset) use ($driver) {
83 2
                return hash_equals($asset->getValue(), get_class($driver));
84 2
            });
85
86 2
        $parameters = Arr::get($asset->getMetadata(), 'parameters', []);
87
88 2
        collect($parameters)->each(function (string $parameter) use ($channel) {
89 1
            if ($channel->getParameter($parameter) === null) {
90 1
                throw new InvalidConfiguration('Invalid `'.$channel->getName().'` channel configuration.');
91
            }
92 2
        });
93 1
    }
94
}
95