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

DriverManager   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 79
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 7
lcom 1
cbo 9
dl 0
loc 79
ccs 27
cts 27
cp 1
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A boot() 0 9 2
A get() 0 14 2
A validateParameters() 0 16 2
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