PluginRepository::load()   A
last analyzed

Complexity

Conditions 5
Paths 8

Size

Total Lines 32
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 5.0061

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 17
c 1
b 0
f 0
nc 8
nop 1
dl 0
loc 32
ccs 15
cts 16
cp 0.9375
crap 5.0061
rs 9.3888
1
<?php
2
/**
3
 * @author PhileCMS
4
 * @link https://philecms.github.io/
5
 * @license http://opensource.org/licenses/MIT
6
 * @package Phile\Plugin
7
 */
8
9
namespace Phile\Plugin;
10
11
use Phile\Core\Config;
12
use Phile\Core\Event;
13
use Phile\Exception\PluginException;
14
15
/**
16
 * Class PluginRepository manages plugin loading
17
 */
18
class PluginRepository
19
{
20
    /**
21
     * @var array array of \Phile\Plugin\PluginDirectory
22
     */
23
    protected $directories = [];
24
25
    /**
26
     * @var Event the event-bus
27
     */
28
    protected $eventBus;
29
30 36
    public function __construct(Event $eventBus)
31
    {
32 36
        $this->eventBus = $eventBus;
33
    }
34
35
    /**
36
     * Adds plugin directory to repository
37
     *
38
     * @param string $directory path to plugin-directory
39
     * @return self
40
     */
41 36
    public function addDirectory(string $directory): self
42
    {
43 36
        $this->directories[] = new PluginDirectory($directory);
44 36
        return $this;
45
    }
46
47
    /**
48
     * Loads all plug-ins
49
     *
50
     * @param Config $config phile config with plugin config
51
     * @throws \Phile\Exception\PluginException
52
     */
53 36
    public function load(Config $config): void
54
    {
55 36
        $errors = $plugins = [];
56 36
        $pluginsToLoad = $config->get('plugins');
57
58 36
        foreach ($pluginsToLoad as $pluginKey => $pluginConfig) {
59 36
            if (empty($pluginConfig['active'])) {
60
                continue;
61
            }
62
            try {
63 36
                $plugins[$pluginKey] = $this->loadSingle($pluginKey, $config);
64 1
            } catch (PluginException $e) {
65 1
                $errors[] = [
66 1
                    'message' => $e->getMessage(),
67 1
                    'code' => $e->getCode()
68
                ];
69
            }
70
        }
71
72 36
        $this->eventBus->trigger('plugins_loaded', ['plugins' => $plugins]);
73
74
        // Throw after 'plugins_loaded' so that error handler service is set.
75
        // Even with setupErrorHandler() not run yet, the global app try/catch
76
        // block uses the handler if present.
77 36
        if (count($errors) > 0) {
78 1
            throw new PluginException($errors[0]['message'], $errors[0]['code']);
79
        }
80
81
        // settings include initialized plugin-configs now
82 35
        $this->eventBus->trigger(
83
            'config_loaded',
84 35
            ['config' => $config->toArray(), 'class' => $config]
85
        );
86
    }
87
88
    /**
89
     * Loads and returns single plugin
90
     *
91
     * @param string $pluginKey plugin key e.g. 'phile\errorHandler'
92
     * @return AbstractPlugin Plugin class
93
     * @throws PluginException
94
     */
95 36
    protected function loadSingle(string $pluginKey, Config $config): AbstractPlugin
96
    {
97 36
        $plugin = $directory = null;
98 36
        foreach ($this->directories as $directory) {
99 36
            $plugin = $directory->newPluginInstance($pluginKey);
100 36
            if ($plugin) {
101 35
                break;
102
            }
103
        }
104 36
        if ($plugin === null) {
105 1
            throw new PluginException(
106 1
                "the plugin '{$pluginKey}' could not be loaded!",
107
                1398536479
108
            );
109
        }
110 35
        $plugin->initializePlugin($pluginKey, $directory->getPath(), $this->eventBus, $config);
111
112 35
        return $plugin;
113
    }
114
}
115