Completed
Pull Request — master (#50)
by De Cramer
03:04
created

DataProviderManager::dispatch()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 3.576

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
ccs 3
cts 5
cp 0.6
cc 3
eloc 4
nc 3
nop 2
crap 3.576
1
<?php
2
3
namespace eXpansion\Framework\Core\Services;
4
5
use eXpansion\Framework\Core\DataProviders\AbstractDataProvider;
6
use eXpansion\Framework\Core\Exceptions\DataProvider\UncompatibleException;
7
use eXpansion\Framework\Core\Model\ProviderListner;
8
use eXpansion\Framework\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\Framework\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 44
    public function __construct(ContainerInterface $container)
50
    {
51 44
        $this->container = $container;
52 44
    }
53
54
    /**
55
     * Initialize all the providers properly.
56
     */
57 1
    public function init(PluginManager $pluginManager)
0 ignored issues
show
Unused Code introduced by
The parameter $pluginManager 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...
58
    {
59 1
        $this->reset();
60
    }
61
62 1
    public function reset()
63
    {
64
        // TODO run check in order not  to have same providers multiple times.
65
        // TODO get this data from the dedicated!
66 1
        $title = 'TMStadium@nadeo';
67 1
        $mode = 'script';
68 1
        $script = 'TimeAttack.script.txt';
69
70 1
        foreach ($this->providersByCompatibility as $provider => $data) {
71
72 1
            $providerId = $this->getCompatibleProviderId($provider, $title, $mode, $script);
73
74 1
            if ($providerId) {
75 1
                $providerService = $this->container->get($providerId);
76
77 1
                if ($pluginManager->isPluginEnabled($providerId)) {
0 ignored issues
show
Bug introduced by
The variable $pluginManager does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
78
                    foreach ($this->providerListeners[$providerId] as $listener) {
79
                        $this->enabledProviderListeners[$listener->getEventName()][] = [
80
                            $providerService,
81
                            $listener->getMethod()
82
                        ];
83
                    }
84
                }
85
            }
86
        }
87
    }
88
89
    /**
90
     * Register a provider.
91
     *
92
     * @param string $id
93
     * @param string $provider
94
     * @param string $interface
95
     * @param string[][] $compatibilities
96
     * @param string[] $listeners
97
     */
98 44
    public function registerDataProvider($id, $provider, $interface, $compatibilities, $listeners)
99
    {
100 44
        foreach ($compatibilities as $compatibility) {
101 44
            $this->providersByCompatibility[$provider][$compatibility['title']][$compatibility['mode']][$compatibility['script']] = $id;
102
        }
103
104 44
        foreach ($listeners as $eventName => $method) {
105 44
            $this->providerListeners[$id][] = new ProviderListner($eventName, $provider, $method);
106
        }
107 44
        $this->providerInterfaces[$provider] = $interface;
108 44
        $this->providerById[$id] = $provider;
109 44
    }
110
111
    /**
112
     * Checl of a provider is compatible
113
     *
114
     * @param string $provider
115
     * @param string $title
116
     * @param string $mode
117
     * @param string $script
118
     *
119
     * @return bool
120
     */
121 1
    public function isProviderCompatible($provider, $title, $mode, $script)
122
    {
123 1
        return !is_null($this->getCompatibleProviderId($provider, $title, $mode, $script));
124
    }
125
126
    /**
127
     * @param string $provider
128
     * @param string $title
129
     * @param string $mode
130
     * @param string $script
131
     *
132
     * @return string|null
133
     */
134 4
    public function getCompatibleProviderId($provider, $title, $mode, $script)
135
    {
136
        $parameters = [
137 4
            [$provider, $title, $mode, $script],
138 4
            [$provider, $title, $mode, self::COMPATIBLE_ALL],
139 4
            [$provider, $title, self::COMPATIBLE_ALL, self::COMPATIBLE_ALL],
140 4
            [$provider, self::COMPATIBLE_ALL, self::COMPATIBLE_ALL, self::COMPATIBLE_ALL],
141
        ];
142
143 4
        foreach ($parameters as $parameter) {
144 4
            $id = AssociativeArray::getFromKey($this->providersByCompatibility, $parameter);
145 4
            if (!is_null($id)) {
146 4
                return $id;
147
            }
148
        }
149
150 1
        return null;
151
    }
152
153
    /**
154
     * Register a plugin to the DataProviders.
155
     *
156
     * @param string $provider The provider to register the plugin to.
157
     * @param string $pluginId The id of the plugin to be registered.
158
     * @param string $title The title to register it for.
159
     * @param string $mode The mode to register it for.
160
     * @param string $script The script to register it for.
161
     *
162
     * @throws UncompatibleException
163
     */
164 2
    public function registerPlugin($provider, $pluginId, $title, $mode, $script)
165
    {
166
        /** @var AbstractDataProvider $providerService */
167 2
        $providerService = $this->container->get($this->getCompatibleProviderId($provider, $title, $mode, $script));
168 2
        $pluginService = $this->container->get($pluginId);
169 2
        $interface = $this->providerInterfaces[$provider];
170
171 2
        if ($pluginService instanceof $interface) {
172 1
            $this->deletePlugin($provider, $pluginId);
173 1
            $providerService->registerPlugin($pluginId, $pluginService);
174
        } else {
175 1
            throw new UncompatibleException("Plugin $pluginId isn't compatible with $provider. Should be instance of $interface");
176
        }
177 1
    }
178
179
    /**
180
     * Provider to delete a plugin from.
181
     *
182
     * @param $provider
183
     * @param $pluginId
184
     *
185
     */
186 1
    public function deletePlugin($provider, $pluginId)
187
    {
188 1
        foreach ($this->providersByCompatibility[$provider] as $titleProviders) {
189 1
            foreach ($titleProviders as $modeProviders) {
190 1
                foreach ($modeProviders as $providerId) {
191 1
                    $providerService = $this->container->get($providerId);
192 1
                    $providerService->deletePlugin($pluginId);
193
                }
194
            }
195
        }
196 1
    }
197
198
    /**
199
     * Dispatch event to the data providers.
200
     *
201
     * @param $eventName
202
     * @param $params
203
     */
204 24
    public function dispatch($eventName, $params)
205
    {
206 24
        if (isset($this->enabledProviderListeners[$eventName])) {
207
            foreach ($this->enabledProviderListeners[$eventName] as $callback) {
208
                call_user_func_array($callback, $params);
209
            }
210
        }
211 24
    }
212
}
213