Complex classes like FOSElasticaExtension 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 FOSElasticaExtension, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
23 | class FOSElasticaExtension extends Extension |
||
24 | { |
||
25 | /** |
||
26 | * Definition of elastica clients as configured by this extension. |
||
27 | * |
||
28 | * @var array |
||
29 | */ |
||
30 | private $clients = array(); |
||
31 | |||
32 | /** |
||
33 | * An array of indexes as configured by the extension. |
||
34 | * |
||
35 | * @var array |
||
36 | */ |
||
37 | private $indexConfigs = array(); |
||
38 | |||
39 | /** |
||
40 | * If we've encountered a type mapped to a specific persistence driver, it will be loaded |
||
41 | * here. |
||
42 | * |
||
43 | * @var array |
||
44 | */ |
||
45 | private $loadedDrivers = array(); |
||
46 | |||
47 | 14 | public function load(array $configs, ContainerBuilder $container) |
|
91 | |||
92 | /** |
||
93 | * @param array $config |
||
94 | * @param ContainerBuilder $container |
||
95 | * |
||
96 | * @return Configuration |
||
97 | */ |
||
98 | 14 | public function getConfiguration(array $config, ContainerBuilder $container) |
|
102 | |||
103 | /** |
||
104 | * Loads the configured clients. |
||
105 | * |
||
106 | * @param array $clients An array of clients configurations |
||
107 | * @param ContainerBuilder $container A ContainerBuilder instance |
||
108 | * |
||
109 | * @return array |
||
110 | */ |
||
111 | 14 | private function loadClients(array $clients, ContainerBuilder $container) |
|
134 | |||
135 | /** |
||
136 | * Loads the configured indexes. |
||
137 | * |
||
138 | * @param array $indexes An array of indexes configurations |
||
139 | * @param ContainerBuilder $container A ContainerBuilder instance |
||
140 | * |
||
141 | * @throws \InvalidArgumentException |
||
142 | * |
||
143 | * @return array |
||
144 | */ |
||
145 | 14 | private function loadIndexes(array $indexes, ContainerBuilder $container) |
|
188 | |||
189 | /** |
||
190 | * Loads the configured index finders. |
||
191 | * |
||
192 | * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container |
||
193 | * @param string $name The index name |
||
194 | * @param Reference $index Reference to the related index |
||
195 | * |
||
196 | * @return string |
||
197 | */ |
||
198 | private function loadIndexFinder(ContainerBuilder $container, $name, Reference $index) |
||
214 | |||
215 | /** |
||
216 | * Loads the configured types. |
||
217 | * |
||
218 | * @param array $types |
||
219 | * @param ContainerBuilder $container |
||
220 | * @param array $indexConfig |
||
221 | * @param array $indexableCallbacks |
||
222 | */ |
||
223 | 14 | private function loadTypes(array $types, ContainerBuilder $container, array $indexConfig, array &$indexableCallbacks) |
|
224 | { |
||
225 | 14 | foreach ($types as $name => $type) { |
|
226 | 14 | $indexName = $indexConfig['name']; |
|
227 | |||
228 | 14 | $typeId = sprintf('%s.%s', $indexConfig['reference'], $name); |
|
229 | 14 | $typeDef = new DefinitionDecorator('fos_elastica.type_prototype'); |
|
230 | 14 | $typeDef->setFactory(array($indexConfig['reference'], 'getType')); |
|
231 | 14 | $typeDef->replaceArgument(0, $name); |
|
232 | |||
233 | 14 | $container->setDefinition($typeId, $typeDef); |
|
234 | |||
235 | $typeConfig = array( |
||
236 | 14 | 'name' => $name, |
|
237 | 'mapping' => array(), // An array containing anything that gets sent directly to ElasticSearch |
||
238 | 'config' => array(), |
||
239 | ); |
||
240 | |||
241 | foreach (array( |
||
242 | 14 | 'dynamic_templates', |
|
243 | 'properties', |
||
244 | '_all', |
||
245 | '_boost', |
||
246 | '_id', |
||
247 | '_parent', |
||
248 | '_routing', |
||
249 | '_source', |
||
250 | '_timestamp', |
||
251 | '_ttl', |
||
252 | ) as $field) { |
||
253 | 14 | if (isset($type[$field])) { |
|
254 | 14 | $typeConfig['mapping'][$field] = $type[$field]; |
|
255 | } |
||
256 | } |
||
257 | |||
258 | foreach (array( |
||
259 | 14 | 'persistence', |
|
260 | 'serializer', |
||
261 | 'analyzer', |
||
262 | 'search_analyzer', |
||
263 | 'dynamic', |
||
264 | 'date_detection', |
||
265 | 'dynamic_date_formats', |
||
266 | 'numeric_detection', |
||
267 | ) as $field) { |
||
268 | 14 | $typeConfig['config'][$field] = array_key_exists($field, $type) ? |
|
269 | 14 | $type[$field] : |
|
270 | 14 | null; |
|
271 | } |
||
272 | |||
273 | 14 | $this->indexConfigs[$indexName]['types'][$name] = $typeConfig; |
|
274 | |||
275 | 14 | if (isset($type['persistence'])) { |
|
276 | 10 | $this->loadTypePersistenceIntegration($type['persistence'], $container, new Reference($typeId), $indexName, $name); |
|
277 | |||
278 | 10 | $typeConfig['persistence'] = $type['persistence']; |
|
279 | } |
||
280 | |||
281 | 14 | if (isset($type['_parent'])) { |
|
282 | // _parent mapping cannot contain `property` and `identifier`, so removing them after building `persistence` |
||
283 | 5 | unset($indexConfig['types'][$name]['mapping']['_parent']['property'], $indexConfig['types'][$name]['mapping']['_parent']['identifier']); |
|
284 | } |
||
285 | |||
286 | 14 | if (isset($type['indexable_callback'])) { |
|
287 | 5 | $indexableCallbacks[sprintf('%s/%s', $indexName, $name)] = $type['indexable_callback']; |
|
288 | } |
||
289 | |||
290 | 14 | if ($container->hasDefinition('fos_elastica.serializer_callback_prototype')) { |
|
291 | 3 | $typeSerializerId = sprintf('%s.serializer.callback', $typeId); |
|
292 | 3 | $typeSerializerDef = new DefinitionDecorator('fos_elastica.serializer_callback_prototype'); |
|
293 | |||
294 | 3 | if (isset($type['serializer']['groups'])) { |
|
295 | 3 | $typeSerializerDef->addMethodCall('setGroups', array($type['serializer']['groups'])); |
|
296 | } |
||
297 | |||
298 | 3 | if (isset($type['serializer']['serialize_null'])) { |
|
299 | 3 | $typeSerializerDef->addMethodCall('setSerializeNull', array($type['serializer']['serialize_null'])); |
|
300 | } |
||
301 | |||
302 | 3 | if (isset($type['serializer']['version'])) { |
|
303 | 3 | $typeSerializerDef->addMethodCall('setVersion', array($type['serializer']['version'])); |
|
304 | } |
||
305 | |||
306 | 3 | $typeDef->addMethodCall('setSerializer', array(array(new Reference($typeSerializerId), 'serialize'))); |
|
307 | 14 | $container->setDefinition($typeSerializerId, $typeSerializerDef); |
|
308 | } |
||
309 | } |
||
310 | 14 | } |
|
311 | |||
312 | /** |
||
313 | * Loads the optional provider and finder for a type. |
||
314 | * |
||
315 | * @param array $typeConfig |
||
316 | * @param ContainerBuilder $container |
||
317 | * @param Reference $typeRef |
||
318 | * @param string $indexName |
||
319 | * @param string $typeName |
||
320 | */ |
||
321 | 10 | private function loadTypePersistenceIntegration(array $typeConfig, ContainerBuilder $container, Reference $typeRef, $indexName, $typeName) |
|
341 | |||
342 | /** |
||
343 | * Creates and loads an ElasticaToModelTransformer. |
||
344 | * |
||
345 | * @param array $typeConfig |
||
346 | * @param ContainerBuilder $container |
||
347 | * @param string $indexName |
||
348 | * @param string $typeName |
||
349 | * |
||
350 | * @return string |
||
351 | */ |
||
352 | 10 | private function loadElasticaToModelTransformer(array $typeConfig, ContainerBuilder $container, $indexName, $typeName) |
|
377 | |||
378 | /** |
||
379 | * Creates and loads a ModelToElasticaTransformer for an index/type. |
||
380 | * |
||
381 | * @param array $typeConfig |
||
382 | * @param ContainerBuilder $container |
||
383 | * @param string $indexName |
||
384 | * @param string $typeName |
||
385 | * |
||
386 | * @return string |
||
387 | */ |
||
388 | 10 | private function loadModelToElasticaTransformer(array $typeConfig, ContainerBuilder $container, $indexName, $typeName) |
|
407 | |||
408 | /** |
||
409 | * Creates and loads an object persister for a type. |
||
410 | * |
||
411 | * @param array $typeConfig |
||
412 | * @param Reference $typeRef |
||
413 | * @param ContainerBuilder $container |
||
414 | * @param string $indexName |
||
415 | * @param string $typeName |
||
416 | * @param string $transformerId |
||
417 | * |
||
418 | * @return string |
||
419 | */ |
||
420 | 10 | private function loadObjectPersister(array $typeConfig, Reference $typeRef, ContainerBuilder $container, $indexName, $typeName, $transformerId) |
|
456 | |||
457 | /** |
||
458 | * Loads a provider for a type. |
||
459 | * |
||
460 | * @param array $typeConfig |
||
461 | * @param ContainerBuilder $container |
||
462 | * @param string $objectPersisterId |
||
463 | * @param string $indexName |
||
464 | * @param string $typeName |
||
465 | * |
||
466 | * @return string |
||
467 | */ |
||
468 | 10 | private function loadTypeProvider(array $typeConfig, ContainerBuilder $container, $objectPersisterId, $indexName, $typeName) |
|
491 | |||
492 | /** |
||
493 | * Loads doctrine listeners to handle indexing of new or updated objects. |
||
494 | * |
||
495 | * @param array $typeConfig |
||
496 | * @param ContainerBuilder $container |
||
497 | * @param string $objectPersisterId |
||
498 | * @param string $indexName |
||
499 | * @param string $typeName |
||
500 | * |
||
501 | * @return string |
||
502 | */ |
||
503 | 10 | private function loadTypeListener(array $typeConfig, ContainerBuilder $container, $objectPersisterId, $indexName, $typeName) |
|
560 | |||
561 | /** |
||
562 | * Map Elastica to Doctrine events for the current driver. |
||
563 | */ |
||
564 | 10 | private function getDoctrineEvents(array $typeConfig) |
|
596 | |||
597 | /** |
||
598 | * Loads a Type specific Finder. |
||
599 | * |
||
600 | * @param array $typeConfig |
||
601 | * @param ContainerBuilder $container |
||
602 | * @param string $elasticaToModelId |
||
603 | * @param Reference $typeRef |
||
604 | * @param string $indexName |
||
605 | * @param string $typeName |
||
606 | * |
||
607 | * @return string |
||
608 | */ |
||
609 | 10 | private function loadTypeFinder(array $typeConfig, ContainerBuilder $container, $elasticaToModelId, Reference $typeRef, $indexName, $typeName) |
|
610 | { |
||
611 | 10 | if (isset($typeConfig['finder']['service'])) { |
|
612 | $finderId = $typeConfig['finder']['service']; |
||
613 | } else { |
||
614 | 10 | $finderId = sprintf('fos_elastica.finder.%s.%s', $indexName, $typeName); |
|
615 | 10 | $finderDef = new DefinitionDecorator('fos_elastica.finder'); |
|
616 | 10 | $finderDef->replaceArgument(0, $typeRef); |
|
617 | 10 | $finderDef->replaceArgument(1, new Reference($elasticaToModelId)); |
|
618 | 10 | $container->setDefinition($finderId, $finderDef); |
|
619 | } |
||
620 | |||
621 | 10 | $indexTypeName = "$indexName/$typeName"; |
|
622 | 10 | $arguments = array($indexTypeName, new Reference($finderId)); |
|
623 | 10 | if (isset($typeConfig['repository'])) { |
|
624 | 5 | $arguments[] = $typeConfig['repository']; |
|
625 | } |
||
626 | |||
627 | 10 | $container->getDefinition('fos_elastica.repository_manager') |
|
628 | 10 | ->addMethodCall('addType', $arguments); |
|
629 | |||
630 | 10 | $managerId = sprintf('fos_elastica.manager.%s', $typeConfig['driver']); |
|
631 | 10 | $container->getDefinition($managerId) |
|
632 | 10 | ->addMethodCall('addEntity', array($typeConfig['model'], $indexTypeName)); |
|
633 | |||
634 | 10 | return $finderId; |
|
635 | } |
||
636 | |||
637 | /** |
||
638 | * Loads the index manager. |
||
639 | * |
||
640 | * @param ContainerBuilder $container |
||
641 | **/ |
||
642 | private function loadIndexManager(ContainerBuilder $container) |
||
651 | |||
652 | /** |
||
653 | * Makes sure a specific driver has been loaded. |
||
654 | * |
||
655 | * @param ContainerBuilder $container |
||
656 | * @param string $driver |
||
657 | */ |
||
658 | 10 | private function loadDriver(ContainerBuilder $container, $driver) |
|
668 | |||
669 | /** |
||
670 | * Loads and configures the serializer prototype. |
||
671 | * |
||
672 | * @param array $config |
||
673 | * @param ContainerBuilder $container |
||
674 | */ |
||
675 | 3 | private function loadSerializer($config, ContainerBuilder $container) |
|
686 | |||
687 | /** |
||
688 | * Creates a default manager alias for defined default manager or the first loaded driver. |
||
689 | * |
||
690 | * @param string $defaultManager |
||
691 | * @param ContainerBuilder $container |
||
692 | */ |
||
693 | 14 | private function createDefaultManagerAlias($defaultManager, ContainerBuilder $container) |
|
709 | |||
710 | /** |
||
711 | * Returns a reference to a client given its configured name. |
||
712 | * |
||
713 | * @param string $clientName |
||
714 | * |
||
715 | * @return Reference |
||
716 | * |
||
717 | * @throws \InvalidArgumentException |
||
718 | */ |
||
719 | 2 | private function getClient($clientName) |
|
727 | } |
||
728 |