PluginService::getCssResources()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 18
Code Lines 11

Duplication

Lines 18
Ratio 100 %

Importance

Changes 0
Metric Value
cc 2
eloc 11
nc 2
nop 0
dl 18
loc 18
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * Copyright (c) 2017
4
 *
5
 * @package   Majima
6
 * @author    David Neustadt <[email protected]>
7
 * @copyright 2017 David Neustadt
8
 * @license   MIT
9
 */
10
11
namespace Majima\PluginBundle\Services;
12
13
use Majima\PluginBundle\Components\RouteConfig;
14
use Majima\PluginBundle\PluginAbstract;
15
use Majima\Services\FluentPdoFactory;
16
use Symfony\Component\DependencyInjection\ContainerBuilder;
17
use Symfony\Component\DependencyInjection\Reference;
18
19
/**
20
 * Class PluginService
21
 * @package Majima\PluginBundle\Services
22
 */
23
class PluginService implements PluginServiceInterface
24
{
25
    /**
26
     * @var FluentPdoFactory
27
     */
28
    private $dbal;
29
30
    /**
31
     * @var ContainerBuilder
32
     */
33
    private $container;
34
35
    /**
36
     * @var array
37
     */
38
    private $pluginClasses = [];
39
40
    /**
41
     * @var PluginAbstract
42
     */
43
    private $pluginClass;
44
45
    /**
46
     * @var array
47
     */
48
    private $registeredPlugins;
49
50
    /**
51
     * PluginService constructor.
52
     * @param FluentPdoFactory $dbal
53
     */
54
    public function __construct(FluentPdoFactory $dbal)
55
    {
56
        $this->dbal = $dbal;
57
58
        $this->registeredPlugins = $this->dbal
59
            ->from('plugins')
60
            ->fetchAll('name');
61
    }
62
63
    /**
64
     * @return array
65
     */
66
    public function getRegisteredPlugins()
67
    {
68
        $dirs = glob(BASE_DIR . 'plugins/*', GLOB_ONLYDIR);
0 ignored issues
show
Bug introduced by
The constant Majima\PluginBundle\Services\BASE_DIR was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
69
70
        foreach ($dirs as $dir) {
71
            $pluginName = basename($dir);
72
            if (isset($this->registeredPlugins[$pluginName]['active']) && !$this->registeredPlugins[$pluginName]['active']) {
73
                unset($this->registeredPlugins[$pluginName]);
74
            } else {
75
                $this->registeredPlugins[$pluginName]['dir'] = $dir;
76
            }
77
        }
78
79
        foreach ($this->registeredPlugins as $pluginName => $pluginInfo) {
80
            if (!array_key_exists('dir', $pluginInfo)) {
81
                $this->dbal->delete('plugins')
82
                    ->where('id', $pluginInfo['id'])
83
                    ->execute();
84
                unset($this->registeredPlugins[$pluginName]);
85
            }
86
        }
87
88
        return $this->registeredPlugins;
89
    }
90
91
    public function instantiatePluginClasses()
92
    {
93
        foreach ($this->getRegisteredPlugins() as $pluginName => $pluginInfo) {
94
            $pluginClass = 'Plugins\\' . $pluginName . '\\' . $pluginName;
95
            if (class_exists($pluginClass)) {
96
                $this->pluginClasses[] = new $pluginClass($this->container);
97
            }
98
        }
99
100
        usort($this->pluginClasses, function(PluginAbstract $a, PluginAbstract $b) {
101
            return $a->getPriority() - $b->getPriority();
102
        });
103
    }
104
105
    /**
106
     * @param ContainerBuilder $container
107
     */
108
    public function registerPlugins(ContainerBuilder $container)
109
    {
110
        $this->container = $container;
111
        $this->instantiatePluginClasses();
112
        foreach ($this->pluginClasses as $pluginClass) {
113
            $this->pluginClass = $pluginClass;
114
            $pluginNamespace = explode('\\', get_class($pluginClass));
115
            $pluginName = array_pop($pluginNamespace);
116
            if (!isset($this->registeredPlugins[$pluginName]['id'])) {
117
                $pluginClass->install();
118
                $this->dbal->insertInto('plugins', [
119
                    'name' => $pluginName,
120
                    'version' => $pluginClass->getVersion(),
121
                    'active' => 1,
122
                ])->execute();
123
            } else if (version_compare($pluginClass->getVersion(), $this->registeredPlugins[$pluginName]['version'], '>')) {
124
                $pluginClass->update($this->registeredPlugins[$pluginName]['version']);
125
                $this->dbal->update('plugins')
126
                    ->set([
127
                        'version' => $pluginClass->getVersion()
128
                    ])
129
                    ->where('id', $this->registeredPlugins[$pluginName]['id'])
130
                    ->execute();
131
            }
132
            $pluginClass->build();
133
            $this->registerRoutes();
134
            $this->registerControllers($pluginName);
135
        }
136
    }
137
138
    public function registerRoutes()
139
    {
140
        $routes = $this->container->hasParameter('majima.plugin.routes') ? $this->container->getParameter('majima.plugin.routes') : [];
141
        /**
142
         * @var RouteConfig $route
143
         */
144
        foreach ($this->pluginClass->setRoutes()->getRoutes() as $route) {
145
            array_push($routes, [
146
                'name' => $route->getName(),
147
                'slug' => $route->getSlug(),
148
                'defaults' => ['_controller' => $route->getAction()],
149
                'params' => $route->getParams(),
150
            ]);
151
        }
152
        $this->container->setParameter('majima.plugin.routes', $routes);
153
    }
154
155
    /**
156
     * @param $pluginName string
157
     */
158
    public function registerControllers($pluginName)
159
    {
160
        $pluginId = $this->classNameToUnderscore($pluginName);
161
        foreach ($this->pluginClass->registerControllers()->getControllers() as $id => $class) {
162
            $serviceId = $pluginId . '.' . $id;
163
            if ($this->container->has($id)) {
164
                $service = $this->container->register($serviceId, $class)
165
                    ->setDecoratedService($id)
166
                    ->addArgument(new Reference($serviceId . '.inner'))
167
                    ->setPublic(true);
168
            } else {
169
                $service = $this->container->register($serviceId, $class);
170
            }
171
            $service->addArgument(new Reference('service_container'))
172
                ->addArgument(new Reference('router'));
173
        }
174
    }
175
176
    /**
177
     * @return array
178
     */
179
    public function getViewResources()
180
    {
181
        $viewDirs = [];
182
        foreach ($this->pluginClasses as $pluginClass) {
183
            $viewDirs = array_merge(
184
                $viewDirs,
185
                $pluginClass->setViewResources()->getViews()
186
            );
187
        }
188
189
        return $viewDirs;
190
    }
191
192
    /**
193
     * @return array
194
     */
195 View Code Duplication
    public function getCssResources()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
196
    {
197
        $cssFiles = [
198
            'frontend' => [],
199
            'backend' => [],
200
        ];
201
        foreach ($this->pluginClasses as $pluginClass) {
202
            $cssFiles['frontend'] = array_merge(
203
                $cssFiles['frontend'],
204
                $pluginClass->setCssResources()->getFrontendAssets()
205
            );
206
            $cssFiles['backend'] = array_merge(
207
                $cssFiles['backend'],
208
                $pluginClass->setCssResources()->getBackendAssets()
209
            );
210
        }
211
212
        return $cssFiles;
213
    }
214
215
    /**
216
     * @return array
217
     */
218 View Code Duplication
    public function getJsResources()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
219
    {
220
        $jsFiles = [
221
            'frontend' => [],
222
            'backend' => [],
223
        ];
224
        foreach ($this->pluginClasses as $pluginClass) {
225
            $jsFiles['frontend'] = array_merge(
226
                $jsFiles['frontend'],
227
                $pluginClass->setJsResources()->getFrontendAssets()
228
            );
229
            $jsFiles['backend'] = array_merge(
230
                $jsFiles['backend'],
231
                $pluginClass->setJsResources()->getBackendAssets()
232
            );
233
        }
234
235
        return $jsFiles;
236
    }
237
238
    /**
239
     * @param $str string
240
     * @return string
241
     */
242
    private function classNameToUnderscore($str) {
243
        $str[0] = strtolower($str[0]);
244
        $func = create_function('$c', 'return "_" . strtolower($c[1]);');
245
        return preg_replace_callback('/([A-Z])/', $func, $str);
246
    }
247
}