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
|
|||
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 |
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.