Completed
Push — master ( 947184...ad3618 )
by
unknown
9s
created

DataProviderManager::init()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
ccs 3
cts 3
cp 1
cc 1
eloc 2
nc 1
nop 2
crap 1
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\CompatibilityCheckDataProviderInterface;
8
use eXpansion\Framework\Core\Model\ProviderListener;
9
use eXpansion\Framework\Core\Storage\GameDataStorage;
10
use Maniaplanet\DedicatedServer\Structures\Map;
11
use oliverde8\AssociativeArraySimplified\AssociativeArray;
12
use Psr\Log\LoggerInterface;
13
use Symfony\Component\DependencyInjection\ContainerInterface;
14
15
/**
16
 * Class DataProviderManager handles all the data providers.
17
 *
18
 * @package eXpansion\Framework\Core\Services
19
 */
20
class DataProviderManager
21
{
22
    /** For compatibility with every title/mode/script */
23
    const COMPATIBLE_ALL = "ALL";
24
25
    /** @var int[][][][]  List of providers by compatibility. */
26
    protected $providersByCompatibility = [];
27
28
    /** @var string[] Name of the provider for a service Id. */
29
    protected $providerById = [];
30
31
    /** @var string[] Interface a plugin needs extend/implement to be used by a provider. */
32
    protected $providerInterfaces = [];
33
34
    /** @var ProviderListener[][] Providers that listen a certain event. */
35
    protected $providerListeners = [];
36
37
    /** @var array[][] Enabled providers that listen to certain events. */
38
    protected $enabledProviderListeners = [];
39
40
    /** @var ContainerInterface */
41
    protected $container;
42
43
    /** @var GameDataStorage */
44
    protected $gameDataStorage;
45
46
    /** @var Console */
47
    protected $console;
48
49
    /** @var LoggerInterface */
50
    protected $logger;
51
52
    /**
53
     * DataProviderManager constructor.
54
     *
55
     * @param ContainerInterface $container
56
     * @param GameDataStorage $gameDataStorage
57
     * @param Console $console
58
     */
59 150
    public function __construct(
60
        ContainerInterface $container,
61
        GameDataStorage $gameDataStorage,
62
        Console $console,
63
        LoggerInterface $logger
64
    ) {
65 150
        $this->container = $container;
66 150
        $this->gameDataStorage = $gameDataStorage;
67 150
        $this->console = $console;
68 150
        $this->logger = $logger;
69 150
    }
70
71
    /**
72
     * Reset
73
     *
74
     * @param PluginManager $pluginManager
75
     * @param Map           $map
76
     */
77 1
    public function reset(PluginManager $pluginManager, Map $map)
78
    {
79 1
        $title = $this->gameDataStorage->getTitle();
80 1
        $mode = $this->gameDataStorage->getGameModeCode();
81 1
        $script = $this->gameDataStorage->getGameInfos()->scriptName;
82 1
        $this->enabledProviderListeners = [];
83
84 1
        foreach ($this->providersByCompatibility as $provider => $data) {
85
86 1
            $providerId = $this->getCompatibleProviderId($provider, $title, $mode, $script, $map);
87
88 1
            if ($providerId) {
89 1
                $providerService = $this->container->get($providerId);
90 1
                if ($pluginManager->isPluginEnabled($providerId)) {
91
92 1
                    foreach ($this->providerListeners[$providerId] as $listener) {
93 1
                        $this->enabledProviderListeners[$listener->getEventName()][] = [
94 1
                            $providerService,
95 1
                            $listener->getMethod(),
96
                        ];
97
                    }
98
                }
99
            }
100
        }
101 1
    }
102
103
    /**
104
     * Register a provider.
105
     *
106
     * @param string $id
107
     * @param string $provider
108
     * @param string $interface
109
     * @param string[][] $compatibilities
110
     * @param string[] $listeners
111
     */
112 150
    public function registerDataProvider($id, $provider, $interface, $compatibilities, $listeners)
113
    {
114 150
        foreach ($compatibilities as $compatibility) {
115 150
            $this->providersByCompatibility[$provider][$compatibility['title']][$compatibility['gamemode']][$compatibility['script']] = $id;
116
        }
117
118 150
        $this->providerListeners[$id] = [];
119 150
        foreach ($listeners as $eventName => $method) {
120 150
            $this->providerListeners[$id][] = new ProviderListener($eventName, $provider, $method);
121
        }
122 150
        $this->providerInterfaces[$provider] = $interface;
123 150
        $this->providerById[$id] = $provider;
124 150
    }
125
126
    /**
127
     * Check of a provider is compatible
128
     *
129
     * @param string $provider
130
     * @param string $title
131
     * @param string $mode
132
     * @param string $script
133
     * @param Map    $map
134
     *
135
     * @return bool
136
     */
137 1
    public function isProviderCompatible($provider, $title, $mode, $script, Map $map)
138
    {
139 1
        return !is_null($this->getCompatibleProviderId($provider, $title, $mode, $script, $map));
140
    }
141
142
    /**
143
     * @param string $provider
144
     * @param string $title
145
     * @param string $mode
146
     * @param string $script
147
     * @param Map $map
148
     *
149
     * @return string|null
150
     */
151 4
    public function getCompatibleProviderId($provider, $title, $mode, $script, Map $map)
152
    {
153
        $parameters = [
154 4
            [$provider, $title, $mode, $script],
155 4
            [$provider, $title, $mode, self::COMPATIBLE_ALL],
156 4
            [$provider, $title, self::COMPATIBLE_ALL, self::COMPATIBLE_ALL],
157 4
            [$provider, self::COMPATIBLE_ALL, self::COMPATIBLE_ALL, self::COMPATIBLE_ALL],
158
            // For modes that are common to all titles.
159 4
            [$provider, self::COMPATIBLE_ALL, $mode, self::COMPATIBLE_ALL],
160 4
            [$provider, self::COMPATIBLE_ALL, $mode, $script],
161
        ];
162
163 4
        foreach ($parameters as $parameter) {
164 4
            $id = AssociativeArray::getFromKey($this->providersByCompatibility, $parameter);
165 4
            if (!is_null($id)) {
166 4
                $provider = $this->container->get($id);
167 4
                if ($provider instanceof CompatibilityCheckDataProviderInterface) {
0 ignored issues
show
Bug introduced by
The class eXpansion\Framework\Core...ckDataProviderInterface does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
168
                    if ($provider->isCompatible($map)) {
169
                        return $id;
170
                    }
171
                } else {
172 4
                    return $id;
173
                }
174
            }
175
        }
176
177 2
        return null;
178
    }
179
180
    /**
181
     * Register a plugin to the DataProviders.
182
     *
183
     * @param string $provider The provider to register the plugin to.
184
     * @param string $pluginId The id of the plugin to be registered.
185
     * @param string $title The title to register it for.
186
     * @param string $mode The mode to register it for.
187
     * @param string $script The script to register it for.
188
     * @param Map    $map Current map
189
     *
190
     * @throws UncompatibleException
191
     */
192 2
    public function registerPlugin($provider, $pluginId, $title, $mode, $script, Map $map)
193
    {
194 2
        $providerId = $this->getCompatibleProviderId($provider, $title, $mode, $script, $map);
195
196 2
        if (empty($providerId)) {
197
            return;
198
        }
199
200
        /** @var AbstractDataProvider $providerService */
201 2
        $providerService = $this->container->get($providerId);
202 2
        $pluginService = $this->container->get($pluginId);
203 2
        $interface = $this->providerInterfaces[$provider];
204
205 2
        if ($pluginService instanceof $interface) {
206 1
            $this->deletePlugin($provider, $pluginId);
207 1
            $providerService->registerPlugin($pluginId, $pluginService);
208
        } else {
209 1
            throw new UncompatibleException("Plugin $pluginId isn't compatible with $provider. Should be instance of $interface");
210
        }
211
212 1
        $this->logger->info("Plugin '$pluginId' will use data provider '$provider' : '$providerId'");
213 1
    }
214
215
    /**
216
     * Provider to delete a plugin from.
217
     *
218
     * @param $provider
219
     * @param $pluginId
220
     *
221
     */
222 1
    public function deletePlugin($provider, $pluginId)
223
    {
224 1
        foreach ($this->providersByCompatibility[$provider] as $titleProviders) {
225 1
            foreach ($titleProviders as $modeProviders) {
226 1
                foreach ($modeProviders as $providerId) {
227 1
                    $providerService = $this->container->get($providerId);
228 1
                    $providerService->deletePlugin($pluginId);
229
                }
230
            }
231
        }
232 1
    }
233
234
    /**
235
     * Dispatch event to the data providers.
236
     *
237
     * @param $eventName
238
     * @param $params
239
     */
240 1
    public function dispatch($eventName, $params)
241
    {
242 1
        if (isset($this->enabledProviderListeners[$eventName])) {
243 1
            foreach ($this->enabledProviderListeners[$eventName] as $callback) {
244 1
                call_user_func_array($callback, $params);
245
            }
246
        }
247 1
    }
248
}
249