Completed
Push — master ( 73c9d5...d07a45 )
by
unknown
02:32
created

EmitterFactory::loadListeners()   B

Complexity

Conditions 6
Paths 8

Size

Total Lines 26

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 0
Metric Value
dl 0
loc 26
ccs 0
cts 20
cp 0
rs 8.8817
c 0
b 0
f 0
cc 6
nc 8
nop 2
crap 42
1
<?php
2
3
/**
4
 * TechDivision\Import\Events\EmitterFactory
5
 *
6
 * NOTICE OF LICENSE
7
 *
8
 * This source file is subject to the Open Software License (OSL 3.0)
9
 * that is available through the world-wide-web at this URL:
10
 * http://opensource.org/licenses/osl-3.0.php
11
 *
12
 * PHP version 5
13
 *
14
 * @author    Tim Wagner <[email protected]>
15
 * @copyright 2019 TechDivision GmbH <[email protected]>
16
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
 * @link      https://github.com/techdivision/import
18
 * @link      http://www.techdivision.com
19
 */
20
21
namespace TechDivision\Import\Events;
22
23
use Doctrine\Common\Collections\Collection;
24
use League\Event\Emitter;
25
use League\Event\EmitterInterface;
26
use Symfony\Component\DependencyInjection\TaggedContainerInterface;
27
use TechDivision\Import\ConfigurationManagerInterface;
28
use TechDivision\Import\Configuration\ListenerAwareConfigurationInterface;
29
use TechDivision\Import\SystemLoggerTrait;
30
31
/**
32
 * A factory implementation to create a new event emitter instance.
33
 *
34
 * @author    Tim Wagner <[email protected]>
35
 * @copyright 2019 TechDivision GmbH <[email protected]>
36
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
37
 * @link      https://github.com/techdivision/import
38
 * @link      http://www.techdivision.com
39
 */
40
class EmitterFactory implements EmitterFactoryInterface
41
{
42
43
    /**
44
     * The trait that provides basic filesystem handling functionality.
45
     *
46
     * @var \TechDivision\Import\SystemLoggerTrait
47
     */
48
    use SystemLoggerTrait;
49
50
    /**
51
     * The configuration instance.
52
     *
53
     * @var \TechDivision\Import\ConfigurationManagerInterface
54
     */
55
    protected $configurationManager;
56
57
    /**
58
     * The DI container builder instance.
59
     *
60
     * @var \Symfony\Component\DependencyInjection\TaggedContainerInterface
61
     */
62
    protected $container;
63
64
    /**
65
     * The array with the event name => DI ID mapping
66
     *
67
     * @var array
68
     */
69
    protected $listeners = array();
70
71
    /**
72
     * The constructor to initialize the instance.
73
     *
74
     * @param \TechDivision\Import\ConfigurationManagerInterface              $configurationManager The configuration instance
75
     * @param \Symfony\Component\DependencyInjection\TaggedContainerInterface $container            The container instance
76
     * @param \Doctrine\Common\Collections\Collection                         $systemLoggers        The array with the system logger instances
77
     */
78
    public function __construct(
79
        ConfigurationManagerInterface $configurationManager,
80
        TaggedContainerInterface $container,
81
        Collection $systemLoggers
82
    ) {
83
        $this->container = $container;
84
        $this->configurationManager = $configurationManager;
85
        $this->systemLoggers = $systemLoggers;
0 ignored issues
show
Documentation Bug introduced by
It seems like $systemLoggers of type object<Doctrine\Common\Collections\Collection> is incompatible with the declared type array of property $systemLoggers.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
86
    }
87
88
    /**
89
     * The factory method that creates a new emitter instance.
90
     *
91
     * @return void
92
     */
93
    public function createEmitter()
94
    {
95
96
        // load the listener configuration from the configuration
97
        $this->loadListeners($this->configurationManager->getConfiguration());
0 ignored issues
show
Documentation introduced by
$this->configurationManager->getConfiguration() is of type object<TechDivision\Impo...ConfigurationInterface>, but the function expects a object<TechDivision\Impo...ConfigurationInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
98
99
        // load the operations that has to be executed from the configuration
100
        $operations = $this->configurationManager->getOperations();
101
102
        // load, initialize and add the configured listeners for the actual operation
103
        /** @var \TechDivision\Import\Configuration\OperationConfigurationInterface $operation */
104
        foreach ($operations as $operation) {
105
            // load the operation's listeners
106
            $this->loadListeners($operation);
0 ignored issues
show
Documentation introduced by
$operation is of type object<TechDivision\Impo...ConfigurationInterface>, but the function expects a object<TechDivision\Impo...ConfigurationInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
107
            // load the operation's registered plugins
108
            /** @var \TechDivision\Import\Configuration\PluginConfigurationInterface $plugin */
109
            foreach ($operation->getPlugins() as $plugin) {
110
                // load the plugin listeners
111
                $this->loadListeners($plugin, sprintf('%s.%s', $operationName = $operation->getName(), $pluginName = $plugin->getName()));
112
                // load the plugin's registered subjects
113
                /** @var \TechDivision\Import\Configuration\SubjectConfigurationInterface $subject */
114
                foreach ($plugin->getSubjects() as $subject) {
115
                    // load the subject listeners
116
                    $this->loadListeners($subject, sprintf('%s.%s.%s', $operationName, $pluginName, $subject->getName()));
117
                }
118
            }
119
        }
120
121
        // initialize the event emitter, register the listeners
122
        return $this->registerListener(new Emitter());
123
    }
124
125
    /**
126
     * Loads the listener configuration for the passed configuration instance.
127
     *
128
     * @param \TechDivision\Import\Configuration\ListenerAwareConfigurationInterface $configuration The configuration with the listener definition
129
     * @param string                                                                 $parentName    The parent configuration name
130
     *
131
     * @return void
132
     */
133
    protected function loadListeners(ListenerAwareConfigurationInterface $configuration, $parentName = null)
134
    {
135
136
        // load the listener configurations
137
        $listenerConfigurations = $configuration->getListeners();
138
139
        // prepare the listeners with the even names as key and the DI ID as value
140
        foreach ($listenerConfigurations as $listeners) {
141
            foreach ($listeners as $key => $listenerArray) {
142
                $uniqueKeyForListener = $parentName == null ? $key : sprintf('%s.%s', $parentName, $key);
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $parentName of type string|null against null; this is ambiguous if the string can be empty. Consider using a strict comparison === instead.
Loading history...
143
                // no registert listener for the unique key? Simply add to optimise speed
144
                if (!isset($this->listeners[$uniqueKeyForListener])) {
145
                    $this->listeners[$uniqueKeyForListener] = $listenerArray;
146
                    continue;
147
                }
148
                // Already registert listeners? Add each new single one
149
                foreach ($listenerArray as $diValue) {
150
                    $this->listeners[$uniqueKeyForListener][] = $diValue;
151
                }
152
                $this->getSystemLogger()->debug(
153
                    sprintf("More than one registert listeners for %s", $uniqueKeyForListener),
154
                    $this->listeners[$uniqueKeyForListener]
155
                );
156
            }
157
        }
158
    }
159
160
    /**
161
     * Registers the listeners defined in the system configuration.
162
     *
163
     * @param \League\Event\EmitterInterface $emitter The event emitter to prepare the listeners for
164
     *
165
     * @return \League\Event\EmitterInterface $emitter The initialized event emitter instance
166
     */
167
    protected function registerListener(EmitterInterface $emitter)
168
    {
169
170
        // iterate over the found listeners and add instances to the emitter
171
        foreach ($this->listeners as $eventName => $listeners) {
172
            foreach ($listeners as $id) {
173
                $emitter->addListener($eventName, $this->container->get($id));
0 ignored issues
show
Bug introduced by
It seems like $this->container->get($id) targeting Symfony\Component\Depend...ntainerInterface::get() can also be of type null; however, League\Event\ListenerAcc...nterface::addListener() does only seem to accept callable, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
174
            }
175
        }
176
177
        // return the emitter instance
178
        return $emitter;
179
    }
180
}
181