Completed
Push — master ( cac559...b1b643 )
by De Cramer
12s
created

DataProviderManager   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 183
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 21
lcom 1
cbo 5
dl 0
loc 183
ccs 70
cts 70
cp 1
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
B init() 0 22 4
A registerDataProvider() 0 12 3
A isProviderCompatible() 0 4 1
A getCompatibleProviderId() 0 18 3
A registerPlugin() 0 14 2
A deletePlugin() 0 11 4
A dispatch() 0 8 3
1
<?php
2
3
namespace eXpansion\Core\Services;
4
5
use eXpansion\Core\DataProviders\AbstractDataProvider;
6
use eXpansion\Core\Exceptions\DataProvider\UncompatibleException;
7
use eXpansion\Core\Model\ProviderListner;
8
use eXpansion\Core\Plugins\StatusAwarePluginInterface;
9
use oliverde8\AssociativeArraySimplified\AssociativeArray;
10
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
11
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
12
use Symfony\Component\DependencyInjection\ContainerInterface;
13
14
/**
15
 * Class DataProviderManager handles all the data providers.
16
 *
17
 * @TODO handle gamemode change.
18
 *
19
 * @package eXpansion\Core\Services
20
 */
21
class DataProviderManager
22
{
23
    /** For compatibility with every title/mode/script */
24
    const COMPATIBLE_ALL = "ALL";
25
26
    /** @var int[][][][]  List of providers by compatibility. */
27
    protected $providersByCompatibility = [];
28
29
    /** @var string[] Name of the provider for a service Id. */
30
    protected $providerById = [];
31
32
    /** @var string[] Interface a plugin needs extend/implement to be used by a provider. */
33
    protected $providerInterfaces = [];
34
35
    /** @var ProviderListner[][] Providers that listen a certain event. */
36
    protected $providerListeners = [];
37
38
    /** @var ProviderListner[][] Enabled providers that listen to certain events. */
39
    protected $enabledProviderListeners = [];
40
41
    /** @var ContainerInterface */
42
    protected $container;
43
44
    /**
45
     * DataProviderManager constructor.
46
     *
47
     * @param ContainerInterface $container
48
     */
49 4
    public function __construct(ContainerInterface $container)
50
    {
51 4
        $this->container = $container;
52 4
    }
53
54
    /**
55
     * Initialize all the providers properly.
56
     */
57 1
    public function init()
58
    {
59
        // TODO run check in order not  to have same providers multiple times.
60
        // TODO get this data from the dedicated!
61 1
        $title = 'TMStadium@nadeo';
62 1
        $mode = 'script';
63 1
        $script = 'TimeAttack.script.txt';
64
65 1
        foreach ($this->providerListeners as $id => $listeners)
66
        {
67 1
            $providerService = $this->container->get($id);
68
69 1
            foreach ($listeners as $listener) {
70 1
                if ($this->isProviderCompatible($listener->getProvider(), $title, $mode, $script)) {
71 1
                    $this->enabledProviderListeners[$listener->getEventName()][] = [
72 1
                        $providerService,
73 1
                        $listener->getMethod()
74 1
                    ];
75 1
                }
76 1
            }
77 1
        }
78 1
    }
79
80
    /**
81
     * Register a provider.
82
     *
83
     * @param string $id
84
     * @param string $provider
85
     * @param string $interface
86
     * @param string[][] $compatibilities
87
     * @param string[] $listeners
88
     */
89 4
    public function registerDataProvider($id, $provider, $interface, $compatibilities, $listeners)
90
    {
91 4
        foreach ($compatibilities as $compatibility) {
92 4
            $this->providersByCompatibility[$provider][$compatibility['title']][$compatibility['mode']][$compatibility['script']] = $id;
93 4
        }
94
95 4
        foreach ($listeners as $eventName => $method) {
96 4
            $this->providerListeners[$id][] = new ProviderListner($eventName, $provider, $method);
97 4
        }
98 4
        $this->providerInterfaces[$provider] = $interface;
99 4
        $this->providerById[$id] = $provider;
100 4
    }
101
102
    /**
103
     * Checl of a provider is compatible
104
     *
105
     * @param string $provider
106
     * @param string $title
107
     * @param string $mode
108
     * @param string $script
109
     *
110
     * @return bool
111
     */
112 2
    public function isProviderCompatible($provider, $title, $mode, $script)
113
    {
114 2
        return !is_null($this->getCompatibleProviderId($provider, $title, $mode, $script));
115
    }
116
117
    /**
118
     * @param string $provider
119
     * @param string $title
120
     * @param string $mode
121
     * @param string $script
122
     *
123
     * @return string|null
124
     */
125 4
    public function getCompatibleProviderId($provider, $title, $mode, $script)
126
    {
127
        $parameters = [
128 4
            [$provider, $title, $mode, $script],
129 4
            [$provider, $title, $mode, self::COMPATIBLE_ALL],
130 4
            [$provider, $title, self::COMPATIBLE_ALL, self::COMPATIBLE_ALL],
131 4
            [$provider, self::COMPATIBLE_ALL, self::COMPATIBLE_ALL, self::COMPATIBLE_ALL],
132 4
        ];
133
134 4
        foreach ($parameters as $parameter) {
135 4
            $id = AssociativeArray::getFromKey($this->providersByCompatibility, $parameter);
136 4
            if (!is_null($id)) {
137 4
                return $id;
138
            }
139 2
        }
140
141 2
        return null;
142
    }
143
144
    /**
145
     * Register a plugin to the DataProviders.
146
     *
147
     * @param string $provider The provider to register the plugin to.
148
     * @param string $pluginId The id of the plugin to be registered.
149
     * @param string $title The title to register it for.
150
     * @param string $mode The mode to register it for.
151
     * @param string $script The script to register it for.
152
     *
153
     * @throws UncompatibleException
154
     */
155 2
    public function registerPlugin($provider, $pluginId, $title, $mode, $script)
156
    {
157
        /** @var AbstractDataProvider $providerService */
158 2
        $providerService = $this->container->get($this->getCompatibleProviderId($provider, $title, $mode, $script));
159 2
        $pluginService = $this->container->get($pluginId);
160 2
        $interface = $this->providerInterfaces[$provider];
161
162 2
        if ($pluginService instanceof $interface) {
163 1
            $this->deletePlugin($provider, $pluginId);
164 1
            $providerService->registerPlugin($pluginId, $pluginService);
165 1
        } else {
166 1
            throw new UncompatibleException("Plugin $pluginId isn't compatible with $provider. Should be instance of $interface");
167
        }
168 1
    }
169
170
    /**
171
     * Provider to delete a plugin from.
172
     *
173
     * @param $provider
174
     * @param $pluginId
175
     *
176
     */
177 1
    public function deletePlugin($provider, $pluginId)
178
    {
179 1
        foreach ($this->providersByCompatibility[$provider] as $titleProviders) {
180 1
            foreach ($titleProviders as $modeProviders) {
181 1
                foreach ($modeProviders as $providerId) {
182 1
                    $providerService = $this->container->get($providerId);
183 1
                    $providerService->deletePlugin($pluginId);
184 1
                }
185 1
            }
186 1
        }
187 1
    }
188
189
    /**
190
     * Dispatch event to the data providers.
191
     *
192
     * @param $eventName
193
     * @param $params
194
     */
195 1
    public function dispatch($eventName, $params)
196
    {
197 1
        if (isset($this->enabledProviderListeners[$eventName])) {
198 1
            foreach ($this->enabledProviderListeners[$eventName] as $callback) {
199 1
                call_user_func_array($callback, $params);
200 1
            }
201 1
        }
202 1
    }
203
}
204