Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like EzPublishCoreExtension often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use EzPublishCoreExtension, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
30 | class EzPublishCoreExtension extends Extension implements PrependExtensionInterface |
||
31 | { |
||
32 | /** |
||
33 | * @var \eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Configuration\Suggestion\Collector\SuggestionCollector |
||
34 | */ |
||
35 | private $suggestionCollector; |
||
36 | |||
37 | /** |
||
38 | * @var \eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Configuration\ParserInterface |
||
39 | */ |
||
40 | private $mainConfigParser; |
||
41 | |||
42 | /** |
||
43 | * @var \eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Configuration\ParserInterface[] |
||
44 | */ |
||
45 | private $configParsers; |
||
46 | |||
47 | /** |
||
48 | * @var PolicyProviderInterface[] |
||
49 | */ |
||
50 | private $policyProviders = []; |
||
51 | |||
52 | /** |
||
53 | * Holds a collection of YAML files, as an array with directory path as a |
||
54 | * key to the array of contained file names. |
||
55 | * |
||
56 | * @var array |
||
57 | */ |
||
58 | private $defaultSettingsCollection = []; |
||
59 | |||
60 | public function __construct(array $configParsers = array()) |
||
65 | |||
66 | public function getAlias() |
||
70 | |||
71 | /** |
||
72 | * Loads a specific configuration. |
||
73 | * |
||
74 | * @param mixed[] $configs An array of configuration values |
||
75 | * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container A ContainerBuilder instance |
||
76 | * |
||
77 | * @throws \InvalidArgumentException When provided tag is not defined in this extension |
||
78 | * |
||
79 | * @api |
||
80 | */ |
||
81 | public function load(array $configs, ContainerBuilder $container) |
||
136 | |||
137 | /** |
||
138 | * @param array $config |
||
139 | * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container |
||
140 | * |
||
141 | * @return \eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Configuration |
||
142 | */ |
||
143 | public function getConfiguration(array $config, ContainerBuilder $container) |
||
147 | |||
148 | /** |
||
149 | * @return \eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Configuration\ParserInterface |
||
150 | */ |
||
151 | private function getMainConfigParser() |
||
165 | |||
166 | /** |
||
167 | * Handle default settings. |
||
168 | * |
||
169 | * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container |
||
170 | * @param \Symfony\Component\DependencyInjection\Loader\FileLoader $loader |
||
171 | */ |
||
172 | private function handleDefaultSettingsLoading(ContainerBuilder $container, FileLoader $loader) |
||
183 | |||
184 | private function registerRepositoriesConfiguration(array $config, ContainerBuilder $container) |
||
185 | { |
||
186 | if (!isset($config['repositories'])) { |
||
187 | $config['repositories'] = array(); |
||
188 | } |
||
189 | |||
190 | foreach ($config['repositories'] as $name => &$repository) { |
||
191 | if (empty($repository['fields_groups']['list'])) { |
||
192 | $repository['fields_groups']['list'] = $container->getParameter('ezsettings.default.content.field_groups.list'); |
||
193 | } |
||
194 | } |
||
195 | |||
196 | $container->setParameter('ezpublish.repositories', $config['repositories']); |
||
197 | } |
||
198 | |||
199 | private function registerSiteAccessConfiguration(array $config, ContainerBuilder $container) |
||
200 | { |
||
201 | if (!isset($config['siteaccess'])) { |
||
202 | $config['siteaccess'] = array(); |
||
203 | $config['siteaccess']['list'] = array('setup'); |
||
204 | $config['siteaccess']['default_siteaccess'] = 'setup'; |
||
205 | $config['siteaccess']['groups'] = array(); |
||
206 | $config['siteaccess']['match'] = null; |
||
207 | } |
||
208 | |||
209 | $container->setParameter('ezpublish.siteaccess.list', $config['siteaccess']['list']); |
||
210 | ConfigurationProcessor::setAvailableSiteAccesses($config['siteaccess']['list']); |
||
211 | $container->setParameter('ezpublish.siteaccess.default', $config['siteaccess']['default_siteaccess']); |
||
212 | $container->setParameter('ezpublish.siteaccess.match_config', $config['siteaccess']['match']); |
||
213 | |||
214 | // Register siteaccess groups + reverse |
||
215 | $container->setParameter('ezpublish.siteaccess.groups', $config['siteaccess']['groups']); |
||
216 | $groupsBySiteaccess = array(); |
||
217 | View Code Duplication | foreach ($config['siteaccess']['groups'] as $groupName => $groupMembers) { |
|
|
|||
218 | foreach ($groupMembers as $member) { |
||
219 | if (!isset($groupsBySiteaccess[$member])) { |
||
220 | $groupsBySiteaccess[$member] = array(); |
||
221 | } |
||
222 | |||
223 | $groupsBySiteaccess[$member][] = $groupName; |
||
224 | } |
||
225 | } |
||
226 | $container->setParameter('ezpublish.siteaccess.groups_by_siteaccess', $groupsBySiteaccess); |
||
227 | ConfigurationProcessor::setGroupsBySiteAccess($groupsBySiteaccess); |
||
228 | } |
||
229 | |||
230 | private function registerImageMagickConfiguration(array $config, ContainerBuilder $container) |
||
231 | { |
||
232 | if (isset($config['imagemagick'])) { |
||
233 | $container->setParameter('ezpublish.image.imagemagick.enabled', $config['imagemagick']['enabled']); |
||
234 | if ($config['imagemagick']['enabled']) { |
||
235 | $container->setParameter('ezpublish.image.imagemagick.executable_path', dirname($config['imagemagick']['path'])); |
||
236 | $container->setParameter('ezpublish.image.imagemagick.executable', basename($config['imagemagick']['path'])); |
||
237 | } |
||
238 | } |
||
239 | |||
240 | $filters = isset($config['imagemagick']['filters']) ? $config['imagemagick']['filters'] : array(); |
||
241 | $filters = $filters + $container->getParameter('ezpublish.image.imagemagick.filters'); |
||
242 | $container->setParameter('ezpublish.image.imagemagick.filters', $filters); |
||
243 | } |
||
244 | |||
245 | private function registerPageConfiguration(array $config, ContainerBuilder $container) |
||
246 | { |
||
247 | if (isset($config['ezpage']['layouts'])) { |
||
248 | $container->setParameter( |
||
249 | 'ezpublish.ezpage.layouts', |
||
250 | $config['ezpage']['layouts'] + $container->getParameter('ezpublish.ezpage.layouts') |
||
251 | ); |
||
252 | } |
||
253 | if (isset($config['ezpage']['blocks'])) { |
||
254 | $container->setParameter( |
||
255 | 'ezpublish.ezpage.blocks', |
||
256 | $config['ezpage']['blocks'] + $container->getParameter('ezpublish.ezpage.blocks') |
||
257 | ); |
||
258 | } |
||
259 | if (isset($config['ezpage']['enabledLayouts'])) { |
||
260 | $container->setParameter( |
||
261 | 'ezpublish.ezpage.enabledLayouts', |
||
262 | $config['ezpage']['enabledLayouts'] + $container->getParameter('ezpublish.ezpage.enabledLayouts') |
||
263 | ); |
||
264 | } |
||
265 | if (isset($config['ezpage']['enabledBlocks'])) { |
||
266 | $container->setParameter( |
||
267 | 'ezpublish.ezpage.enabledBlocks', |
||
268 | $config['ezpage']['enabledBlocks'] + $container->getParameter('ezpublish.ezpage.enabledBlocks') |
||
269 | ); |
||
270 | } |
||
271 | } |
||
272 | |||
273 | /** |
||
274 | * Handle routing parameters. |
||
275 | * |
||
276 | * @param array $config |
||
277 | * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container |
||
278 | * @param \Symfony\Component\DependencyInjection\Loader\FileLoader $loader |
||
279 | */ |
||
280 | private function handleRouting(array $config, ContainerBuilder $container, FileLoader $loader) |
||
281 | { |
||
282 | $loader->load('routing.yml'); |
||
283 | $container->setAlias('router', 'ezpublish.chain_router'); |
||
284 | |||
285 | if (isset($config['router']['default_router']['non_siteaccess_aware_routes'])) { |
||
286 | $container->setParameter( |
||
287 | 'ezpublish.default_router.non_siteaccess_aware_routes', |
||
288 | array_merge( |
||
289 | $container->getParameter('ezpublish.default_router.non_siteaccess_aware_routes'), |
||
290 | $config['router']['default_router']['non_siteaccess_aware_routes'] |
||
291 | ) |
||
292 | ); |
||
293 | } |
||
294 | } |
||
295 | |||
296 | /** |
||
297 | * Handle public API loading. |
||
298 | * |
||
299 | * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container |
||
300 | * @param \Symfony\Component\DependencyInjection\Loader\FileLoader $loader |
||
301 | */ |
||
302 | private function handleApiLoading(ContainerBuilder $container, FileLoader $loader) |
||
303 | { |
||
304 | // Loading configuration from Core/settings |
||
305 | $coreLoader = new Loader\YamlFileLoader( |
||
306 | $container, |
||
307 | new FileLocator(__DIR__ . '/../../../Publish/Core/settings') |
||
308 | ); |
||
309 | $coreLoader->load('repository.yml'); |
||
310 | $coreLoader->load('fieldtype_external_storages.yml'); |
||
311 | $coreLoader->load('fieldtypes.yml'); |
||
312 | $coreLoader->load('indexable_fieldtypes.yml'); |
||
313 | $coreLoader->load('roles.yml'); |
||
314 | $coreLoader->load('storage_engines/common.yml'); |
||
315 | $coreLoader->load('storage_engines/cache.yml'); |
||
316 | $coreLoader->load('storage_engines/legacy.yml'); |
||
317 | $coreLoader->load('storage_engines/shortcuts.yml'); |
||
318 | $coreLoader->load('search_engines/common.yml'); |
||
319 | $coreLoader->load('utils.yml'); |
||
320 | $coreLoader->load('io.yml'); |
||
321 | |||
322 | // Public API services |
||
323 | $loader->load('papi.yml'); |
||
324 | |||
325 | // Built-in field types |
||
326 | $loader->load('fieldtype_services.yml'); |
||
327 | |||
328 | // Storage engine |
||
329 | $loader->load('storage_engines.yml'); |
||
330 | } |
||
331 | |||
332 | /** |
||
333 | * Handle templating parameters. |
||
334 | * |
||
335 | * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container |
||
336 | * @param \Symfony\Component\DependencyInjection\Loader\FileLoader $loader |
||
337 | */ |
||
338 | private function handleTemplating(ContainerBuilder $container, FileLoader $loader) |
||
339 | { |
||
340 | $loader->load('templating.yml'); |
||
341 | } |
||
342 | |||
343 | /** |
||
344 | * Handle session parameters. |
||
345 | * |
||
346 | * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container |
||
347 | * @param \Symfony\Component\DependencyInjection\Loader\FileLoader $loader |
||
348 | */ |
||
349 | private function handleSessionLoading(ContainerBuilder $container, FileLoader $loader) |
||
350 | { |
||
351 | $loader->load('session.yml'); |
||
352 | } |
||
353 | |||
354 | /** |
||
355 | * Handle cache parameters. |
||
356 | * |
||
357 | * @param array $config |
||
358 | * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container |
||
359 | * @param \Symfony\Component\DependencyInjection\Loader\FileLoader $loader |
||
360 | * |
||
361 | * @throws \InvalidArgumentException |
||
362 | */ |
||
363 | private function handleCache(array $config, ContainerBuilder $container, FileLoader $loader) |
||
364 | { |
||
365 | $loader->load('cache.yml'); |
||
366 | |||
367 | if (isset($config['http_cache']['purge_type'])) { |
||
368 | switch ($config['http_cache']['purge_type']) { |
||
369 | case 'local': |
||
370 | $purgeService = 'ezpublish.http_cache.purge_client.local'; |
||
371 | break; |
||
372 | case 'http': |
||
373 | $purgeService = 'ezpublish.http_cache.purge_client.fos'; |
||
374 | break; |
||
375 | default: |
||
376 | if (!$container->has($config['http_cache']['purge_type'])) { |
||
377 | throw new \InvalidArgumentException("Invalid ezpublish.http_cache.purge_type. Can be 'single', 'multiple' or a valid service identifier implementing PurgeClientInterface."); |
||
378 | } |
||
379 | |||
380 | $purgeService = $config['http_cache']['purge_type']; |
||
381 | } |
||
382 | |||
383 | $container->setAlias('ezpublish.http_cache.purge_client', $purgeService); |
||
384 | } |
||
385 | } |
||
386 | |||
387 | /** |
||
388 | * Handle locale parameters. |
||
389 | * |
||
390 | * @param array $config |
||
391 | * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container |
||
392 | * @param \Symfony\Component\DependencyInjection\Loader\FileLoader $loader |
||
393 | */ |
||
394 | private function handleLocale(array $config, ContainerBuilder $container, FileLoader $loader) |
||
395 | { |
||
396 | $loader->load('locale.yml'); |
||
397 | $container->setParameter( |
||
398 | 'ezpublish.locale.conversion_map', |
||
399 | $config['locale_conversion'] + $container->getParameter('ezpublish.locale.conversion_map') |
||
400 | ); |
||
401 | } |
||
402 | |||
403 | /** |
||
404 | * Handle helpers. |
||
405 | * |
||
406 | * @param array $config |
||
407 | * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container |
||
408 | * @param \Symfony\Component\DependencyInjection\Loader\FileLoader $loader |
||
409 | */ |
||
410 | private function handleHelpers(array $config, ContainerBuilder $container, FileLoader $loader) |
||
411 | { |
||
412 | $loader->load('helpers.yml'); |
||
413 | } |
||
414 | |||
415 | /** |
||
416 | * Handles relation between SiteAccesses. |
||
417 | * Related SiteAccesses share the same repository and root location id. |
||
418 | * |
||
419 | * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container |
||
420 | */ |
||
421 | private function handleSiteAccessesRelation(ContainerBuilder $container) |
||
453 | |||
454 | /** |
||
455 | * @param array $config |
||
456 | * @param ContainerBuilder $container |
||
457 | * @param FileLoader $loader |
||
458 | */ |
||
459 | private function handleImage(array $config, ContainerBuilder $container, FileLoader $loader) |
||
463 | |||
464 | private function buildPolicyMap(ContainerBuilder $container) |
||
471 | |||
472 | View Code Duplication | public function prepend(ContainerBuilder $container) |
|
480 | |||
481 | /** |
||
482 | * Adds a new policy provider to the internal collection. |
||
483 | * One can call this method from a bundle `build()` method. |
||
484 | * |
||
485 | * ```php |
||
486 | * public function build(ContainerBuilder $container) |
||
487 | * { |
||
488 | * $ezExtension = $container->getExtension('ezpublish'); |
||
489 | * $ezExtension->addPolicyProvider($myPolicyProvider); |
||
490 | * } |
||
491 | * ``` |
||
492 | * |
||
493 | * @since 6.0 |
||
494 | * |
||
495 | * @param PolicyProviderInterface $policyProvider |
||
496 | */ |
||
497 | public function addPolicyProvider(PolicyProviderInterface $policyProvider) |
||
501 | |||
502 | /** |
||
503 | * Adds a new config parser to the internal collection. |
||
504 | * One can call this method from a bundle `build()` method. |
||
505 | * |
||
506 | * ```php |
||
507 | * public function build(ContainerBuilder $container) |
||
508 | * { |
||
509 | * $ezExtension = $container->getExtension('ezpublish'); |
||
510 | * $ezExtension->addConfigParser($myConfigParser); |
||
511 | * } |
||
512 | * ``` |
||
513 | * |
||
514 | * @since 6.0 |
||
515 | * |
||
516 | * @param \eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Configuration\ParserInterface $configParser |
||
517 | */ |
||
518 | public function addConfigParser(ParserInterface $configParser) |
||
526 | |||
527 | /** |
||
528 | * Adds new default settings to the internal collection. |
||
529 | * One can call this method from a bundle `build()` method. |
||
530 | * |
||
531 | * ```php |
||
532 | * public function build(ContainerBuilder $container) |
||
533 | * { |
||
534 | * $ezExtension = $container->getExtension('ezpublish'); |
||
535 | * $ezExtension->addDefaultSettings( |
||
536 | * __DIR__ . '/Resources/config', |
||
537 | * ['default_settings.yml'] |
||
538 | * ); |
||
539 | * } |
||
540 | * ``` |
||
541 | * |
||
542 | * @since 6.0 |
||
543 | * |
||
544 | * @param string $fileLocation |
||
545 | * @param array $files |
||
546 | */ |
||
547 | public function addDefaultSettings($fileLocation, array $files) |
||
551 | } |
||
552 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.