Passed
Push — master ( 6223b9...5fd62f )
by Thomas Mauro
07:54
created

ClientAbstractFactory::canCreate()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
eloc 5
c 0
b 0
f 0
dl 0
loc 11
ccs 0
cts 6
cp 0
rs 10
cc 2
nc 2
nop 2
crap 6
1
<?php
2
3
declare(strict_types=1);
4
5
namespace TMV\HTTPlugModule\DIFactory;
6
7
use Http\Client\Common\PluginClient;
8
use Http\Client\HttpClient;
9
use Interop\Container\ContainerInterface;
10
use InvalidArgumentException;
11
use function is_array;
12
use function is_string;
13
use TMV\HTTPlugModule\ClientFactory\AutoDiscoveryFactory;
14
use TMV\HTTPlugModule\ClientFactory\ClientFactory;
15
use TMV\HTTPlugModule\PluginFactoryManager;
16
use Zend\ServiceManager\Exception\ServiceNotCreatedException;
17
use Zend\ServiceManager\Exception\ServiceNotFoundException;
18
use Zend\ServiceManager\Factory\AbstractFactoryInterface;
19
20
class ClientAbstractFactory implements AbstractFactoryInterface
21
{
22
    protected function getServiceTypeName(): string
23
    {
24
        return 'clients';
25
    }
26
27
    public function canCreate(ContainerInterface $container, $requestedName): bool
28
    {
29
        if (! preg_match('/^httplug\.clients\.[^.]+$/', $requestedName)) {
30
            throw new InvalidArgumentException('Invalid service name');
31
        }
32
33
        [,, $clientName] = explode('.', $requestedName);
34
35
        $config = $container->get('config')['httplug']['clients'][$clientName] ?? null;
36
37
        return is_array($config);
38
    }
39
40
    /**
41
     * Create an object
42
     *
43
     * @param ContainerInterface $container
44
     * @param string $requestedName
45
     * @param null|array $options
46
     *
47
     * @throws ServiceNotFoundException if unable to resolve the service
48
     * @throws ServiceNotCreatedException if an exception is raised when
49
     *     creating a service
50
     *
51
     * @return HttpClient
52
     */
53 1
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null): HttpClient
54
    {
55 1
        if (! preg_match('/^httplug\.clients\.[^.]+$/', $requestedName)) {
56
            throw new InvalidArgumentException('Invalid service name');
57
        }
58
59 1
        [,, $clientName] = explode('.', $requestedName);
60
61 1
        $config = $container->get('config')['httplug']['clients'][$clientName] ?? null;
62
63 1
        if (! is_array($config)) {
64
            throw new InvalidArgumentException('Invalid service name');
65
        }
66
67 1
        if (! empty($config['service'])) {
68
            $client = $container->get($config['service']);
69
        } else {
70
            /** @var ClientFactory $factory */
71 1
            $factory = $container->get($config['factory'] ?? AutoDiscoveryFactory::class);
72 1
            $client = $factory->createClient($config['config'] ?? []);
73
        }
74
75 1
        $plugins = $this->retrievePlugins($container, $config['plugins'] ?? []);
76
77 1
        if (0 === count($plugins)) {
78
            return $client;
79
        }
80
81 1
        return new PluginClient(
82 1
            $client,
83
            $plugins
84
        );
85
    }
86
87 1
    private function retrievePlugins(ContainerInterface $container, array $config): array
88
    {
89
        /** @var PluginFactoryManager $pluginFactoryManager */
90 1
        $pluginFactoryManager = $container->get(PluginFactoryManager::class);
91
92 1
        $plugins = [];
93
94 1
        foreach ($config as $nameOrConfig) {
95 1
            if (is_string($nameOrConfig)) {
96 1
                $plugins[] = $container->get($nameOrConfig);
97 1
                continue;
98
            }
99
100 1
            if (! is_array($nameOrConfig) || ! is_string($nameOrConfig['name'] ?? null)) {
101
                throw new InvalidArgumentException('Invalid client plugin');
102
            }
103
104 1
            $plugins[] = $pluginFactoryManager->getFactory($nameOrConfig['name'])
105 1
                ->createPlugin($nameOrConfig['config'] ?? []);
106
        }
107
108 1
        return $plugins;
109
    }
110
}
111