|
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) { |
|
|
|
|
|
|
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
|
|
|
|
This error could be the result of:
1. Missing dependencies
PHP Analyzer uses your
composer.jsonfile (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects thecomposer.jsonto 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
requireorrequire-devsection?2. Missing use statement
PHP does not complain about undefined classes in
ìnstanceofchecks. For example, the following PHP code will work perfectly fine:If you have not tested against this specific condition, such errors might go unnoticed.