DamaxChargeableApiExtension::configureListener()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 10
nc 1
nop 2
dl 0
loc 16
c 0
b 0
f 0
cc 1
rs 9.9332
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Damax\ChargeableApi\Bridge\Symfony\Bundle\DependencyInjection;
6
7
use Damax\ChargeableApi\Bridge\Symfony\Bundle\Listener\PurchaseListener;
8
use Damax\ChargeableApi\Bridge\Symfony\EventDispatcher\NotificationStore;
9
use Damax\ChargeableApi\Bridge\Symfony\HttpFoundation\ProductResolver;
10
use Damax\ChargeableApi\Bridge\Symfony\Security\TokenIdentityFactory;
11
use Damax\ChargeableApi\Identity\FixedIdentityFactory;
12
use Damax\ChargeableApi\Identity\IdentityFactory;
13
use Damax\ChargeableApi\Processor;
14
use Damax\ChargeableApi\Product\Product;
15
use Damax\ChargeableApi\Store\Store;
16
use Damax\ChargeableApi\Store\StoreProcessor;
17
use Damax\ChargeableApi\Store\WalletStore;
18
use Damax\ChargeableApi\Wallet\InMemoryWalletFactory;
19
use Damax\ChargeableApi\Wallet\MongoWalletFactory;
20
use Damax\ChargeableApi\Wallet\RedisWalletFactory;
21
use Damax\ChargeableApi\Wallet\WalletFactory;
22
use Symfony\Component\Config\FileLocator;
23
use Symfony\Component\DependencyInjection\ContainerBuilder;
24
use Symfony\Component\DependencyInjection\Definition;
25
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
26
use Symfony\Component\DependencyInjection\Reference;
27
use Symfony\Component\HttpFoundation\RequestMatcher;
28
use Symfony\Component\HttpKernel\DependencyInjection\ConfigurableExtension;
29
30
final class DamaxChargeableApiExtension extends ConfigurableExtension
31
{
32
    protected function loadInternal(array $config, ContainerBuilder $container)
33
    {
34
        $loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
35
        $loader->load('services.xml');
36
37
        $this
38
            ->configureWallet($config['wallet'], $container)
39
            ->configureIdentity($config['identity'], $container)
40
            ->configureProduct($config['product'], $container)
41
            ->configureListener($config['listener'], $container)
42
            ->configureStore($container)
43
        ;
44
    }
45
46
    private function configureWallet(array $config, ContainerBuilder $container): self
47
    {
48
        switch ($config['type']) {
49
            case Configuration::WALLET_FIXED:
50
                $container
51
                    ->register(WalletFactory::class, InMemoryWalletFactory::class)
52
                    ->addArgument($config['accounts'])
53
                ;
54
                break;
55
            case Configuration::WALLET_REDIS:
56
                $container
57
                    ->register(WalletFactory::class, RedisWalletFactory::class)
58
                    ->addArgument(new Reference($config['redis_client_id']))
59
                    ->addArgument($config['wallet_key'])
60
                ;
61
                break;
62
            case Configuration::WALLET_MONGO:
63
                $container
64
                    ->register(WalletFactory::class, MongoWalletFactory::class)
65
                    ->addArgument(new Reference($config['mongo_client_id']))
66
                    ->addArgument($config['db_name'])
67
                    ->addArgument($config['collection_name'])
68
                ;
69
                break;
70
            case Configuration::WALLET_SERVICE:
71
                $container->setAlias(WalletFactory::class, $config['factory_service_id']);
72
                break;
73
        }
74
75
        return $this;
76
    }
77
78
    private function configureIdentity(array $config, ContainerBuilder $container): self
79
    {
80
        switch ($config['type']) {
81
            case Configuration::IDENTITY_FIXED:
82
                $container
83
                    ->register(IdentityFactory::class, FixedIdentityFactory::class)
84
                    ->addArgument($config['identity'])
85
                ;
86
                break;
87
            case Configuration::IDENTITY_SECURITY:
88
                $container->autowire(IdentityFactory::class, TokenIdentityFactory::class);
89
                break;
90
            case Configuration::IDENTITY_SERVICE:
91
                $container->setAlias(IdentityFactory::class, $config['factory_service_id']);
92
                break;
93
        }
94
95
        return $this;
96
    }
97
98
    private function configureProduct(array $config, ContainerBuilder $container): self
99
    {
100
        $resolver = $container
101
            ->register(ProductResolver::class)
102
            ->addTag('damax.chargeable_api.product_resolver', ['priority' => 0])
103
        ;
104
105
        foreach ($config as $item) {
106
            $product = (new Definition(Product::class))
107
                ->addArgument($item['name'])
108
                ->addArgument($item['price'])
109
            ;
110
            $matcher = $this->createMatcher($item['matcher'] ?? []);
111
112
            $resolver->addMethodCall('addProduct', [$product, $matcher]);
113
        }
114
115
        return $this;
116
    }
117
118
    private function configureListener(array $config, ContainerBuilder $container): self
119
    {
120
        $matcher = $this->createMatcher($config['matcher'] ?? []);
121
122
        $container
123
            ->register(PurchaseListener::class)
124
            ->addArgument($matcher)
125
            ->addArgument(new Reference(Processor::class))
126
            ->addTag('kernel.event_listener', [
127
                'event' => 'kernel.request',
128
                'method' => 'onKernelRequest',
129
                'priority' => $config['priority'],
130
            ])
131
        ;
132
133
        return $this;
134
    }
135
136
    private function configureStore(ContainerBuilder $container): self
137
    {
138
        // Decorated store.
139
        $store = (new Definition(WalletStore::class))->setAutowired(true);
140
141
        $container
142
            ->autowire(Store::class, NotificationStore::class)
143
            ->addArgument($store)
144
        ;
145
        $container->autowire(Processor::class, StoreProcessor::class);
146
147
        return $this;
148
    }
149
150
    private function createMatcher(array $config): Definition
151
    {
152
        $ips = !empty($config['ips']) ? $config['ips'] : null;
153
        $methods = !empty($config['methods']) ? $config['methods'] : null;
154
155
        return (new Definition(RequestMatcher::class))
156
            ->addArgument($config['path'] ?? null)
157
            ->addArgument($config['host'] ?? null)
158
            ->addArgument($methods)
159
            ->addArgument($ips)
160
        ;
161
    }
162
}
163