Completed
Push — master ( 7ab81f...96a3d6 )
by Cees-Jan
08:29
created

src/Factory.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php declare(strict_types=1);
2
3
namespace ApiClients\Foundation;
4
5
use ApiClients\Foundation\Events\CommandLocatorEvent;
6
use ApiClients\Foundation\Hydrator\Factory as HydratorFactory;
7
use ApiClients\Foundation\Hydrator\Hydrator;
8
use ApiClients\Foundation\Transport\Client as TransportClient;
9
use ApiClients\Foundation\Transport\Factory as TransportFactory;
10
use Interop\Container\ContainerInterface;
11
use League\Container\Container;
12
use League\Container\ReflectionContainer;
13
use League\Event\Emitter;
14
use League\Event\EmitterInterface;
15
use League\Tactician\CommandBus;
16
use League\Tactician\Container\ContainerLocator;
17
use League\Tactician\Handler\CommandHandlerMiddleware;
18
use League\Tactician\Handler\CommandNameExtractor\ClassNameExtractor;
19
use League\Tactician\Handler\MethodNameInflector\HandleInflector;
20
use React\EventLoop\LoopInterface;
21
22
final class Factory
23
{
24
    public static function create(
25
        LoopInterface $loop = null,
26
        ContainerInterface $wrappedContainer = null,
27
        array $options = []
28
    ): Client {
29
        $container = self::createContainer($wrappedContainer);
30
31
        $container->share(EmitterInterface::class, new Emitter());
32
        $container->share(TransportClient::class, self::createTransport($container, $loop, $options));
33
        $container->share(Hydrator::class, self::createHydrator($container, $options));
34
        $container->share(CommandBus::class, function () use ($container) {
35
            return self::createCommandBus($container);
36
        });
37
38
        return new Client(
39
            $container
40
        );
41
    }
42
43
    private static function createContainer(ContainerInterface $wrappedContainer = null): Container
44
    {
45
        $container = new Container();
46
        $container->delegate(new ReflectionContainer());
47
48
        if ($wrappedContainer instanceof ContainerInterface) {
49
            $container->delegate($wrappedContainer);
50
        }
51
52
        return $container;
53
    }
54
55
    private static function createCommandBus(ContainerInterface $container): CommandBus
56
    {
57
        $commandToHandlerMap = self::mapCommandsToHandlers($container->get(EmitterInterface::class));
58
59
        $containerLocator = new ContainerLocator(
60
            $container,
61
            $commandToHandlerMap
62
        );
63
64
        $commandHandlerMiddleware = new CommandHandlerMiddleware(
65
            new ClassNameExtractor(),
66
            $containerLocator,
67
            new HandleInflector()
68
        );
69
70
        return new CommandBus([
71
            $commandHandlerMiddleware,
72
        ]);
73
    }
74
75
    private static function mapCommandsToHandlers(Emitter $emitter): array
76
    {
77
        return $emitter->emit(CommandLocatorEvent::create())->getMap();
78
    }
79
80
    private static function createTransport(
81
        ContainerInterface $container,
82
        LoopInterface $loop = null,
83
        array $options = []
84
    ): TransportClient {
85
        return TransportFactory::create($container, $loop, $options);
86
    }
87
88
    private static function createHydrator(ContainerInterface $container, array $options = [])
0 ignored issues
show
The parameter $container is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
89
    {
90
        if (isset($options[Options::HYDRATOR]) && $options[Options::HYDRATOR] instanceof Hydrator) {
91
            return $options[Options::HYDRATOR];
92
        }
93
94
        if (!isset($options[Options::HYDRATOR_OPTIONS])) {
95
            throw new \Exception('Missing Hydrator options');
96
        }
97
98
        return HydratorFactory::create($options[Options::HYDRATOR_OPTIONS]);
99
    }
100
}
101