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

PluginManager::disablePlugin()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 16
Code Lines 9

Duplication

Lines 7
Ratio 43.75 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
dl 7
loc 16
rs 9.2
c 0
b 0
f 0
ccs 0
cts 10
cp 0
cc 4
eloc 9
nc 6
nop 1
crap 20
1
<?php
2
3
namespace eXpansion\Framework\Core\Services;
4
5
use eXpansion\Framework\Core\Model\Plugin\PluginDescription;
6
use eXpansion\Framework\Core\Model\Plugin\PluginDescriptionFactory;
7
use eXpansion\Framework\Core\Plugins\StatusAwarePluginInterface;
8
use Symfony\Component\DependencyInjection\ContainerInterface;
9
10
/**
11
 * Class PluginManager handles all the plugins.
12
 *
13
 * @TODO handle gamemode change.
14
 *
15
 * @package eXpansion\Framework\Core\Services
16
 */
17
class PluginManager
18
{
19
    /** @var PluginDescription[] List of all the plugins adescriptions. */
20
    protected $plugins = [];
21
22
    /** @var PluginDescription[] Current List of enabled plugins */
23
    protected $enabledPlugins = [];
24
25
    /** @var PluginDescriptionFactory  */
26
    protected $pluginDescriptionFactory;
27
28
    /** @var ContainerInterface  */
29
    protected $container;
30
31
    /** @var DataProviderManager  */
32
    protected $dataProviderManager;
33
34
    /**
35
     * PluginManager constructor.
36
     *
37
     * @param ContainerInterface $container
38
     * @param DataProviderManager $dataProviderManager
39
     */
40 40
    public function __construct(
41
        ContainerInterface $container,
42
        PluginDescriptionFactory $pluginDescriptionFactory,
43
        DataProviderManager $dataProviderManager
44
    )
45
    {
46 40
        $this->container = $container;
47 40
        $this->pluginDescriptionFactory = $pluginDescriptionFactory;
48 40
        $this->dataProviderManager = $dataProviderManager;
49 40
    }
50
51
    /**
52
     * Initialize plugins.
53
     */
54
    public function init()
55
    {
56
        $this->reset();
57
    }
58
59
    public function reset()
60
    {
61
        // TODO get this data from the dedicated!
62
        $title = 'TMStadium@nadeo';
63
        $mode = 'script';
64
        $script = 'TimeAttack.script.txt';
65
66
        $this->enableDisablePlugins($title, $mode, $script);    }
67
68
    /**
69
     * Enable all possible plugins.
70
     *
71
     * @param string $title
72
     * @param string $mode
73
     * @param string $script
74
     */
75
    protected function enableDisablePlugins($title, $mode, $script)
76
    {
77
        $pluginsToEnable = [];
78
        $pluginsToProcess = $this->plugins;
79
80
        do {
81
            $lastEnabledPluginCount = count($pluginsToEnable);
82
            $pluginsToProcessNew = [];
83
84
            foreach ($pluginsToProcess
85
86
                     as $pluginId => $plugin) {
87
                if ($this->isPluginCompatible($plugin, $pluginsToEnable, $title, $mode, $script)) {
88
                    $pluginsToEnable[$pluginId] = $plugin;
89
                } else {
90
                    $pluginsToProcessNew[$pluginId] = $plugin;
91
                }
92
            }
93
94
            $pluginsToProcess = $pluginsToProcessNew;
95
        } while ($lastEnabledPluginCount != count($pluginsToEnable) && !empty($pluginsToProcess));
96
97
        foreach ($pluginsToEnable as $plugin) {
98
            $this->enablePlugin($plugin, $title, $mode, $script);
99
        }
100
101
        foreach ($pluginsToProcess as $plugin) {
102
            $this->disablePlugin($plugin);
103
        }
104
    }
105
106
    /**
107
     * Check if a plugin is compatible or not.
108
     *
109
     * @param PluginDescription $plugin
110
     * @param $enabledPlugins
111
     * @param $title
112
     * @param $mode
113
     * @param $script
114
     *
115
     * @return bool
116
     */
117
    protected function isPluginCompatible(PluginDescription $plugin, $enabledPlugins, $title, $mode, $script) {
118
119
        // first check for other plugins.
120
        foreach ($plugin->getParents() as $parentPluginId) {
121
            if (!isset($enabledPlugins[$parentPluginId])) {
122
                // A parent plugin is missing. Can't enable plugin.
123
                return false;
124
            }
125
        }
126
127
        // Now check  for data providers.
128
        foreach ($plugin->getDataProviders() as $dataProvider) {
129
            $providerId = $this->dataProviderManager->getCompatibleProviderId($dataProvider, $title, $mode, $script);
130
131
            if (is_null($providerId) || !isset($enabledPlugins[$providerId])) {
132
                // Either there are no data providers compatible or the only one compatible
133
                return false;
134
            }
135
        }
136
137
        // If data provider need to check if it was "the chosen one".
138
        if ($plugin->isIsDataProvider()) {
139
            $selectedProvider = $this->dataProviderManager->getCompatibleProviderId($plugin->getDataProviderName(), $title, $mode, $script);
140
141
            if ($plugin->getPluginId() != $selectedProvider) {
142
                // This data provider wasn't the one selected and therefore the plugin isn't compatible.
143
                return false;
144
            }
145
        }
146
147
        return true;
148
    }
149
150
151
    /**
152
     * Enable a plugin for a certain game mode.
153
     *
154
     * @param PluginDescription $plugin
155
     * @param $title
156
     * @param $mode
157
     * @param $script
158
     */
159
    protected function enablePlugin(PluginDescription $plugin, $title, $mode, $script) {
160
        $plugin->setIsEnabled(true);
161
        $pluginService = $this->container->get($plugin->getPluginId());
162
163 View Code Duplication
        if ($pluginService instanceof StatusAwarePluginInterface && !isset($this->enabledPlugins[$plugin->getPluginId()])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
164
            $pluginService->setStatus(true);
165
        }
166
167
        foreach ($plugin->getDataProviders() as $provider) {
168
            $this->dataProviderManager->registerPlugin($provider, $plugin->getPluginId(), $title, $mode, $script);
169
        }
170
171
        $this->enabledPlugins[$plugin->getPluginId()] = $plugin;
172
    }
173
174
    /**
175
     * Disable a plugin.
176
     *
177
     * @param PluginDescription $plugin
178
     *
179
     */
180
    protected function disablePlugin(PluginDescription $plugin) {
181
        $plugin->setIsEnabled(false);
182
        $pluginService = $this->container->get($plugin->getPluginId());
183
184
        foreach ($plugin->getDataProviders() as $provider) {
185
            $this->dataProviderManager->deletePlugin($provider, $plugin->getPluginId());
186
        }
187
188 View Code Duplication
        if (isset($this->enabledPlugins[$plugin->getPluginId()])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
189
            unset($this->enabledPlugins[$plugin->getPluginId()]);
190
191
            if ($pluginService instanceof StatusAwarePluginInterface) {
192
                $pluginService->setStatus(true);
193
            }
194
        }
195
    }
196
197
    /**
198
     * Check if a plugin is enabled or not.
199
     *
200
     * @param $pluginId
201
     *
202
     * @return bool
203
     */
204
    public function isPluginEnabled($pluginId) {
205
        return isset($this->enabledPlugins[$pluginId]);
206
    }
207
208
    /**
209
     * Register a plugin.
210
     *
211
     * @param string $id The service id of the plugin to register.
212
     * @param string[] $dataProviders The data providers it needs to work.
213
     * @param string[] $parents The parent plugins.
214
     */
215 40
    public function registerPlugin($id, $dataProviders, $parents, $dataProviderName = null) {
216 40
        if (!isset($this->plugins[$id])) {
217 40
            $this->plugins[$id] = $this->pluginDescriptionFactory->create($id);
218
        }
219
220 40
        $this->plugins[$id]->setDataProviders($dataProviders);
221 40
        $this->plugins[$id]->setParents($parents);
222 40
        $this->plugins[$id]->setDataProviderName($dataProviderName);
223 40
    }
224
}
225