Issues (3627)

DependencyInjection/MauticCoreExtension.php (1 issue)

1
<?php
2
3
/*
4
 * @copyright   2014 Mautic Contributors. All rights reserved
5
 * @author      Mautic
6
 *
7
 * @link        http://mautic.org
8
 *
9
 * @license     GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
10
 */
11
12
namespace Mautic\CoreBundle\DependencyInjection;
13
14
use Symfony\Component\DependencyInjection\ContainerBuilder;
15
use Symfony\Component\DependencyInjection\Definition;
16
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
17
use Symfony\Component\DependencyInjection\Reference;
18
use Symfony\Component\ExpressionLanguage\Expression;
19
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
20
21
/**
22
 * Class MauticCoreExtension.
23
 *
24
 * This is the class that loads and manages your bundle configuration
25
 * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html}
26
 */
27
class MauticCoreExtension extends Extension
28
{
29
    /**
30
     * {@inheritdoc}
31
     */
32
    public function load(array $configs, ContainerBuilder $container)
33
    {
34
        $bundles = array_merge($container->getParameter('mautic.bundles'), $container->getParameter('mautic.plugin.bundles'));
35
36
        // Store menu renderer options to create unique renderering classes per menu
37
        // since KNP menus doesn't seem to support a Renderer factory
38
        $menus = [];
39
40
        // Keep track of names used to prevent overwriting any and thus losing functionality
41
        $serviceNames = [];
42
43
        foreach ($bundles as $bundle) {
44
            if (!empty($bundle['config']['services'])) {
45
                $config = $bundle['config']['services'];
46
                foreach ($config as $type => $services) {
47
                    switch ($type) {
48
                        case 'events':
49
                            $defaultTag = 'kernel.event_subscriber';
50
                            break;
51
                        case 'forms':
52
                            $defaultTag = 'form.type';
53
                            break;
54
                        case 'helpers':
55
                            $defaultTag = 'templating.helper';
56
                            break;
57
                        case 'menus':
58
                            $defaultTag = 'knp_menu.menu';
59
                            break;
60
                        case 'models':
61
                            $defaultTag = 'mautic.model';
62
                            break;
63
                        case 'integrations':
64
                            $defaultTag = 'mautic.integration';
65
                            break;
66
                        case 'command':
67
                            $defaultTag = 'console.command';
68
                            break;
69
                        default:
70
                            $defaultTag = false;
71
                            break;
72
                    }
73
74
                    foreach ($services as $name => $details) {
75
                        if (isset($serviceNames[$name])) {
76
                            throw new \InvalidArgumentException("$name is already registered");
77
                        }
78
                        $serviceNames[$name] = true;
79
80
                        if (!is_array($details)) {
81
                            // Set parameter
82
                            $container->setParameter($name, $details);
83
                            continue;
84
                        }
85
86
                        // Setup default menu details
87
                        if ('menus' == $type) {
88
                            $details = array_merge(
89
                                [
90
                                    'class'   => 'Knp\Menu\MenuItem',
91
                                    'factory' => ['@mautic.menu.builder', $details['alias'].'Menu'],
92
                                ],
93
                                $details
94
                            );
95
96
                            $menus[$details['alias']] = (isset($details['options'])) ? $details['options'] : [];
97
                        }
98
99
                        // Set service alias
100
                        if (isset($details['serviceAlias'])) {
101
                            // Fix escaped sprintf placeholders
102
                            $details['serviceAlias'] = str_replace('%%', '%', $details['serviceAlias']);
103
                            $container->setAlias(sprintf($details['serviceAlias'], $name), $name);
104
                        } elseif (isset($details['serviceAliases'])) {
105
                            foreach ($details['serviceAliases'] as $alias) {
106
                                $alias = str_replace('%%', '%', $alias);
107
                                $container->setAlias(sprintf($alias, $name), $name);
108
                            }
109
                        }
110
                        // Alias with class name
111
                        if ($name !== $details['class']) {
112
                            $container->setAlias($details['class'], $name);
113
                        }
114
115
                        // Generate definition arguments
116
                        $definitionArguments = [];
117
                        if (!isset($details['arguments'])) {
118
                            $details['arguments'] = [];
119
                        } elseif (!is_array($details['arguments'])) {
120
                            $details['arguments'] = [$details['arguments']];
121
                        }
122
123
                        foreach ($details['arguments'] as $argument) {
124
                            $this->processArgument($argument, $container, $definitionArguments);
125
                        }
126
127
                        // Add the service
128
                        $definition = $container->setDefinition($name, new Definition(
129
                            $details['class'],
130
                            $definitionArguments
131
                        ));
132
133
                        if (isset($details['public'])) {
134
                            $definition->setPublic($details['public']);
135
                        }
136
137
                        // Generate tag and tag arguments
138
                        if (isset($details['tags'])) {
139
                            $tagArguments = (!empty($details['tagArguments'])) ? $details['tagArguments'] : [];
140
                            foreach ($details['tags'] as $k => $tag) {
141
                                if (!isset($tagArguments[$k])) {
142
                                    $tagArguments[$k] = [];
143
                                }
144
145
                                if (!empty($details['alias'])) {
146
                                    $tagArguments[$k]['alias'] = $details['alias'];
147
                                }
148
149
                                $definition->addTag($tag, $tagArguments[$k]);
150
151
                                if ('mautic.email_transport' === $tag) {
152
                                    $container->setAlias(sprintf('swiftmailer.mailer.transport.%s', $name), $name);
153
                                }
154
                            }
155
                        } else {
156
                            $tag          = (!empty($details['tag'])) ? $details['tag'] : $defaultTag;
157
                            $tagArguments = (!empty($details['tagArguments'])) ? $details['tagArguments'] : [];
158
159
                            if (!empty($tag)) {
160
                                if (!empty($details['alias'])) {
161
                                    $tagArguments['alias'] = $details['alias'];
162
                                }
163
164
                                $definition->addTag($tag, $tagArguments);
165
166
                                if ('mautic.email_transport' === $tag) {
167
                                    $container->setAlias(sprintf('swiftmailer.mailer.transport.%s', $name), $name);
168
                                }
169
                            }
170
171
                            if ('events' == $type) {
172
                                $definition->addTag('mautic.event_subscriber');
173
                            }
174
                        }
175
176
                        // Set public service
177
                        if (!empty($details['public'])) {
178
                            $definition->setPublic($details['public']);
179
                        }
180
181
                        // Set lazy service
182
                        if (!empty($details['lazy'])) {
183
                            $definition->setLazy($details['lazy']);
184
                        }
185
186
                        // Set synthetic service
187
                        if (!empty($details['synthetic'])) {
188
                            $definition->setSynthetic($details['synthetic']);
189
                        }
190
191
                        // Set abstract service
192
                        if (!empty($details['abstract'])) {
193
                            $definition->setAbstract($details['abstract']);
194
                        }
195
196
                        // Set include file
197
                        if (!empty($details['file'])) {
198
                            $definition->setFile($details['file']);
199
                        }
200
201
                        // Set service configurator
202
                        if (!empty($details['configurator'])) {
203
                            $definition->setConfigurator($details['configurator']);
204
                        }
205
206
                        // Set scope - Deprecated as of Symfony 2.8 and removed in 3.0
207
                        if (!empty($details['scope'])) {
208
                            $definition->setScope($details['scope']);
209
                        } elseif ('templating' == $type) {
210
                            $definition->setScope('request');
211
                        }
212
213
                        // Set factory service - Deprecated as of Symfony 2.6 and removed in Symfony 3.0
214
                        if (!empty($details['factoryService'])) {
215
                            $definition->setFactoryService($details['factoryService']);
216
                        }
217
218
                        // Set factory class - Deprecated as of Symfony 2.6 and removed in Symfony 3.0
219
                        if (!empty($details['factoryClass'])) {
220
                            $definition->setFactoryClass($details['factoryClass']);
0 ignored issues
show
The method setFactoryClass() does not exist on Symfony\Component\DependencyInjection\Definition. Did you maybe mean setFactory()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

220
                            $definition->/** @scrutinizer ignore-call */ 
221
                                         setFactoryClass($details['factoryClass']);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
221
                        }
222
223
                        // Set factory method - Deprecated as of Symfony 2.6 and removed in Symfony 3.0
224
                        if (!empty($details['factoryMethod'])) {
225
                            $definition->setFactoryMethod($details['factoryMethod']);
226
                        }
227
228
                        // Set factory - Preferred API since Symfony 2.6
229
                        if (!empty($details['factory'])) {
230
                            $factory = $details['factory'];
231
232
                            /*
233
                             * Standardize to an array then convert a service to a Reference if needed
234
                             *
235
                             * This supports three syntaxes:
236
                             *
237
                             * 1) @service::method or Class::method
238
                             * 2) array('@service', 'method') or array('Class', 'method')
239
                             * 3) "Unknown" - Just pass it to the definition
240
                             *
241
                             * Services must always be prefaced with an @ symbol (similar to "normal" config files)
242
                             */
243
                            if (is_string($factory) && false !== strpos($factory, '::')) {
244
                                $factory = explode('::', $factory, 2);
245
                            }
246
247
                            // Check if the first item in the factory array is a service and if so fetch its reference
248
                            if (is_array($factory) && 0 === strpos($factory[0], '@')) {
249
                                // Exclude the leading @ character in the service ID
250
                                $factory[0] = new Reference(substr($factory[0], 1));
251
                            }
252
253
                            $definition->setFactory($factory);
254
                        }
255
256
                        // Set method calls
257
                        if (!empty($details['methodCalls'])) {
258
                            foreach ($details['methodCalls'] as $method => $methodArguments) {
259
                                $methodCallArguments = [];
260
                                foreach ($methodArguments as $argument) {
261
                                    $this->processArgument($argument, $container, $methodCallArguments);
262
                                }
263
264
                                $definition->addMethodCall($method, $methodCallArguments);
265
                            }
266
                        }
267
268
                        // Set deprecated service
269
                        if (!empty($details['decoratedService'])) {
270
                            // This should be an array and the first parameter cannot be empty
271
                            if (!is_array($details['decoratedService'])) {
272
                                throw new InvalidArgumentException('The "decoratedService" definition must be an array.');
273
                            }
274
275
                            // The second parameter of setDecoratedService is optional, check if there is a second key in the array
276
                            $secondParam = !empty($details['decoratedService'][1]) ? $details['decoratedService'][1] : null;
277
278
                            $definition->setDecoratedService($details['decoratedService'][0], $secondParam);
279
                        }
280
281
                        unset($definition);
282
                    }
283
                }
284
            }
285
        }
286
287
        foreach ($menus as $alias => $options) {
288
            $container->setDefinition('mautic.menu_renderer.'.$alias, new Definition(
289
                \Mautic\CoreBundle\Menu\MenuRenderer::class,
290
                [
291
                    new Reference('knp_menu.matcher'),
292
                    new Reference('mautic.helper.templating'),
293
                    $options,
294
                ]
295
            ))
296
                ->addTag('knp_menu.renderer',
297
                    [
298
                        'alias' => $alias,
299
                    ]
300
                );
301
        }
302
303
        unset($bundles);
304
    }
305
306
    /**
307
     * @param $argument
308
     * @param $container
309
     * @param $definitionArguments
310
     */
311
    private function processArgument($argument, $container, &$definitionArguments)
312
    {
313
        if ('' === $argument) {
314
            // To be added during compilation
315
            $definitionArguments[] = '';
316
        } elseif (is_array($argument) || is_object($argument)) {
317
            foreach ($argument as &$v) {
318
                if (0 === strpos($v, '%')) {
319
                    $v = str_replace('%%', '%', $v);
320
                    $v = $container->getParameter(substr($v, 1, -1));
321
                }
322
            }
323
            $definitionArguments[] = $argument;
324
        } elseif (0 === strpos($argument, '%')) {
325
            // Parameter
326
            $argument              = str_replace('%%', '%', $argument);
327
            $definitionArguments[] = $container->getParameter(substr($argument, 1, -1));
328
        } elseif (is_bool($argument) || false !== strpos($argument, '\\')) {
329
            // Parameter or Class
330
            $definitionArguments[] = $argument;
331
        } elseif (0 === strpos($argument, '"')) {
332
            // String
333
            $definitionArguments[] = substr($argument, 1, -1);
334
        } elseif (0 === strpos($argument, '@=')) {
335
            // Expression
336
            $argument              = substr($argument, 2);
337
            $definitionArguments[] = new Expression($argument);
338
        } elseif (0 === strpos($argument, '@')) {
339
            // Service
340
            $argument              = substr($argument, 1);
341
            $definitionArguments[] = new Reference($argument);
342
        } else {
343
            // Reference
344
            $definitionArguments[] = new Reference($argument);
345
        }
346
    }
347
}
348