rebuildServiceModulesConfigs()   B
last analyzed

Complexity

Conditions 5
Paths 5

Size

Total Lines 33
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 33
rs 8.439
cc 5
eloc 19
nc 5
nop 3
1
<?php
2
/**
3
 * @link    https://github.com/nnx-framework/module
4
 * @author  Malofeykin Andrey  <[email protected]>
5
 */
6
namespace Nnx\Module\Listener;
7
8
use Zend\EventManager\AbstractListenerAggregate;
9
use Zend\EventManager\EventManagerInterface;
10
use Nnx\Module\IntegrationModuleInterface;
11
use Nnx\Module\Event\IntegrationModuleEventInterface;
12
use Zend\ModuleManager\ModuleEvent;
13
use Zend\ModuleManager\Listener\ConfigMergerInterface;
14
use Zend\ModuleManager\ModuleManagerInterface;
15
use Nnx\ModuleOptions\ModuleConfigKeyProviderInterface;
16
use Nnx\Module\CommonModuleOptionsInterface;
17
use Zend\Stdlib\ArrayUtils;
18
19
/**
20
 * Class ModuleOptions
21
 *
22
 * @package Nnx\Module\Options
23
 */
24
class IntegrationModuleListener extends AbstractListenerAggregate implements IntegrationModuleListenerInterface
25
{
26
27
    /**
28
     * Стек содержащий объекты событий, полученных когда происходит иницилацзия интеграционного модуля.
29
     * (порядок соответствует, тому в какой очередности происходила инициализация модулей)
30
     *
31
     * @var IntegrationModuleEventInterface[]
32
     */
33
    protected $stackInitIntegrationModuleEvent = [];
34
35
    /**
36
     * Идендфикаторы подписчиков на SharedManagerEvent
37
     *
38
     * @var array
39
     */
40
    protected $sharedListeners = [];
41
42
    /**
43
     * Приоритет обработчки отвечающего за конфигурирование модулей сервиса. Для корректной работы
44
     * интеграционного модуля, это значение должно быть больше, по приоритету чем значение свойства
45
     * @see \Nnx\Module\Listener\IntegrationModuleListener::$configuringServiceModulesHandlerPriority, но меньше
46
     * @see \Nnx\Module\IntegrationModuleTrait::$loadModulesPostProxyHandlerPriority
47
     *
48
     *
49
     * @var int
50
     */
51
    protected $configuringServiceModulesHandlerPriority = 50;
52
53
    /**
54
     * @inheritdoc
55
     *
56
     * @param EventManagerInterface $events - это EventManager сервиса \Zend\ModuleManager\ModuleManagerInterface
57
     */
58
    public function attach(EventManagerInterface $events)
59
    {
60
        $sharedEventManager = $events->getSharedManager();
61
        $integrationModuleEventHandler = $sharedEventManager->attach(
62
            IntegrationModuleInterface::class,
63
            IntegrationModuleEventInterface::INIT_INTEGRATION_MODULE_EVENT,
64
            [$this, 'initIntegrationModuleEventHandler']
65
        );
66
        $this->sharedListeners[] = [
67
            'listener' => $integrationModuleEventHandler,
68
            'id' => IntegrationModuleInterface::class
69
        ];
70
71
        $this->listeners[] = $events->attach(
72
            ModuleEvent::EVENT_LOAD_MODULES_POST,
73
            [$this, 'configuringServiceModulesHandler'],
74
            $this->configuringServiceModulesHandlerPriority
75
        );
76
    }
77
78
    /**
79
     * Обработчик события бросаемого, когда все интеграционные модули иницилизированны
80
     *
81
     * @param ModuleEvent $e
82
     */
83
    public function configuringServiceModulesHandler(ModuleEvent $e)
84
    {
85
        $configListener = $e->getConfigListener();
86
87
        $stackIntegrationsModule = $this->getStackInitIntegrationModuleEvent();
88
        /** @var IntegrationModuleEventInterface[] $sortStackIntegrationsModule */
89
        $sortStackIntegrationsModule = array_reverse($stackIntegrationsModule);
90
91
92
        foreach ($sortStackIntegrationsModule as $event) {
93
            $integrationModule = $event->getModule();
94
95
            if (!$integrationModule instanceof IntegrationModuleInterface) {
96
                continue;
97
            }
98
            $moduleManager = $event->getModuleManager();
99
100
            $this->rebuildServiceModulesConfigs($integrationModule, $moduleManager, $configListener);
101
        }
102
    }
103
104
    /**
105
     * Возвращает для итеграционного модуля список настроек, которые должны быть применены, ко всем модулям сервиса
106
     *
107
     * @param mixed                 $integrationModule
108
     * @param ConfigMergerInterface $configListener
109
     *
110
     * @return array
111
     */
112
    public function getCommonModuleOptionsByIntegrationModule($integrationModule, ConfigMergerInterface $configListener)
113
    {
114
        $commonModuleOptions = [];
115
        if (
116
            (!$integrationModule instanceof CommonModuleOptionsInterface)
117
            || (!$integrationModule instanceof ModuleConfigKeyProviderInterface)
118
        ) {
119
            return $commonModuleOptions;
120
        }
121
122
        $listCommonModuleOptions = $integrationModule->getCommonModuleOptions();
123
        $integrationModuleConfigKey = $integrationModule->getModuleConfigKey();
124
125
        $appConfig = $configListener->getMergedConfig(false);
126
        if (!is_array($appConfig)) {
127
            return $commonModuleOptions;
128
        }
129
130
        $integrationModuleConfig = array_key_exists($integrationModuleConfigKey, $appConfig) ? $appConfig[$integrationModuleConfigKey] : [];
131
132
        foreach ($listCommonModuleOptions as $key) {
133
            $commonModuleOptions[$key] = array_key_exists($key, $integrationModuleConfig) ? $integrationModuleConfig[$key] : null;
134
        }
135
136
        return $commonModuleOptions;
137
    }
138
139
    /**
140
     * Применяет настройки определенные в интеграционном модуле, для модулей сервиса
141
     *
142
     * @param IntegrationModuleInterface $integrationModule
143
     * @param ModuleManagerInterface     $moduleManager
144
     * @param ConfigMergerInterface      $configListener
145
     */
146
    public function rebuildServiceModulesConfigs(
147
        IntegrationModuleInterface $integrationModule,
148
        ModuleManagerInterface $moduleManager,
149
        ConfigMergerInterface $configListener
150
    ) {
151
        $serviceModules = $integrationModule->getServiceModules();
152
153
        $loadedModules = $moduleManager->getLoadedModules(false);
154
155
        $appConfig = $configListener->getMergedConfig(false);
156
157
        $commonModuleOptions = $this->getCommonModuleOptionsByIntegrationModule($integrationModule, $configListener);
158
        foreach ($serviceModules as $moduleName) {
159
            if (!array_key_exists($moduleName, $loadedModules)) {
160
                continue;
161
            }
162
            $module = $loadedModules[$moduleName];
163
164
            if (!$module instanceof ModuleConfigKeyProviderInterface) {
165
                continue;
166
            }
167
168
            $moduleConfigKey = $module->getModuleConfigKey();
169
170
            $moduleConfig = array_key_exists($moduleConfigKey, $appConfig) ? $appConfig[$moduleConfigKey] : [];
171
172
            $newModuleConfig = ArrayUtils::merge($moduleConfig, $commonModuleOptions);
173
174
            $appConfig[$moduleConfigKey] = $newModuleConfig;
175
        }
176
177
        $configListener->setMergedConfig($appConfig);
178
    }
179
180
    /**
181
     * {@inheritDoc}
182
     */
183
    public function detach(EventManagerInterface $events)
184
    {
185
        parent::detach($events);
186
        $sharedEventManager = $events->getSharedManager();
187
        foreach ($this->sharedListeners as $index => $item) {
188
            if ($sharedEventManager->detach($item['id'], $item['listener'])) {
189
                unset($this->sharedListeners[$index]);
190
            }
191
        }
192
    }
193
194
    /**
195
     * Обработчик события возникающего при инциализации интеграционного модуля
196
     *
197
     * @param IntegrationModuleEventInterface $event
198
     */
199
    public function initIntegrationModuleEventHandler(IntegrationModuleEventInterface $event)
200
    {
201
        $this->addInitIntegrationModuleEventInStack($event);
202
    }
203
204
    /**
205
     * Добавляет в стек, содержащий объекты событий бросаемых при иницилацзия интеграционного модуля.
206
     *
207
     * @param $initIntegrationModuleEvent $stackInitIntegrationModuleEvent
0 ignored issues
show
Documentation introduced by
The doc-type $initIntegrationModuleEvent could not be parsed: Unknown type name "$initIntegrationModuleEvent" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
Documentation introduced by
There is no parameter named $stackInitIntegrationModuleEvent. Did you maybe mean $initIntegrationModuleEvent?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
208
     *
209
     * @return $this
210
     */
211
    public function addInitIntegrationModuleEventInStack(IntegrationModuleEventInterface $initIntegrationModuleEvent)
212
    {
213
        $this->stackInitIntegrationModuleEvent[] = $initIntegrationModuleEvent;
214
215
        return $this;
216
    }
217
218
    /**
219
     * Стек содержащий объекты событий, полученных когда происходит иницилацзия интеграционного модуля.
220
     * (порядок соответствует, тому в какой очередности происходила инициализация модулей)
221
     *
222
     * @return IntegrationModuleEventInterface[]
223
     */
224
    public function getStackInitIntegrationModuleEvent()
225
    {
226
        return $this->stackInitIntegrationModuleEvent;
227
    }
228
}
229