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 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 |
||
26 | class FOSElasticaExtension extends Extension |
||
27 | { |
||
28 | /** |
||
29 | * Definition of elastica clients as configured by this extension. |
||
30 | * |
||
31 | * @var array |
||
32 | */ |
||
33 | private $clients = []; |
||
34 | |||
35 | /** |
||
36 | * An array of indexes as configured by the extension. |
||
37 | * |
||
38 | * @var array |
||
39 | */ |
||
40 | private $indexConfigs = []; |
||
41 | |||
42 | /** |
||
43 | * An array of index templates as configured by the extension. |
||
44 | * |
||
45 | * @var array |
||
46 | */ |
||
47 | private $indexTemplateConfigs = array(); |
||
48 | |||
49 | /** |
||
50 | * If we've encountered a type mapped to a specific persistence driver, it will be loaded |
||
51 | * here. |
||
52 | * |
||
53 | * @var array |
||
54 | */ |
||
55 | private $loadedDrivers = []; |
||
56 | |||
57 | 21 | public function load(array $configs, ContainerBuilder $container) |
|
121 | |||
122 | /** |
||
123 | * @param array $config |
||
124 | * @param ContainerBuilder $container |
||
125 | * |
||
126 | * @return Configuration |
||
127 | */ |
||
128 | 21 | public function getConfiguration(array $config, ContainerBuilder $container) |
|
132 | |||
133 | /** |
||
134 | * Loads the configured clients. |
||
135 | * |
||
136 | * @param array $clients An array of clients configurations |
||
137 | * @param ContainerBuilder $container A ContainerBuilder instance |
||
138 | * |
||
139 | * @return array |
||
140 | */ |
||
141 | 21 | private function loadClients(array $clients, ContainerBuilder $container) |
|
164 | |||
165 | /** |
||
166 | * Loads the configured indexes. |
||
167 | * |
||
168 | * @param array $indexes An array of indexes configurations |
||
169 | * @param ContainerBuilder $container A ContainerBuilder instance |
||
170 | * |
||
171 | * @throws \InvalidArgumentException |
||
172 | * |
||
173 | * @return array |
||
174 | */ |
||
175 | 21 | private function loadIndexes(array $indexes, ContainerBuilder $container) |
|
176 | { |
||
177 | 21 | $indexableCallbacks = []; |
|
178 | |||
179 | 21 | foreach ($indexes as $name => $index) { |
|
180 | 21 | $indexId = sprintf('fos_elastica.index.%s', $name); |
|
181 | 21 | $indexName = isset($index['index_name']) ? $index['index_name'] : $name; |
|
182 | |||
183 | 21 | $indexDef = new ChildDefinition('fos_elastica.index_prototype'); |
|
184 | 21 | $indexDef->setFactory([new Reference('fos_elastica.client'), 'getIndex']); |
|
185 | 21 | $indexDef->replaceArgument(0, $indexName); |
|
186 | 21 | $indexDef->addTag('fos_elastica.index', [ |
|
187 | 21 | 'name' => $name, |
|
188 | ]); |
||
189 | |||
190 | 21 | View Code Duplication | if (isset($index['client'])) { |
191 | 2 | $client = $this->getClient($index['client']); |
|
192 | |||
193 | 2 | $indexDef->setFactory([$client, 'getIndex']); |
|
194 | } |
||
195 | |||
196 | 21 | $container->setDefinition($indexId, $indexDef); |
|
197 | 21 | $reference = new Reference($indexId); |
|
198 | |||
199 | 21 | $this->indexConfigs[$name] = [ |
|
200 | 21 | 'elasticsearch_name' => $indexName, |
|
201 | 21 | 'reference' => $reference, |
|
202 | 21 | 'name' => $name, |
|
203 | 21 | 'settings' => $index['settings'], |
|
204 | 21 | 'type_prototype' => isset($index['type_prototype']) ? $index['type_prototype'] : [], |
|
205 | 21 | 'use_alias' => $index['use_alias'], |
|
206 | ]; |
||
207 | |||
208 | 21 | if ($index['finder']) { |
|
209 | $this->loadIndexFinder($container, $name, $reference); |
||
210 | } |
||
211 | |||
212 | 21 | $this->loadTypes((array) $index['types'], $container, $this->indexConfigs[$name], $indexableCallbacks); |
|
213 | } |
||
214 | |||
215 | 21 | $indexable = $container->getDefinition('fos_elastica.indexable'); |
|
216 | 21 | $indexable->replaceArgument(0, $indexableCallbacks); |
|
217 | 21 | } |
|
218 | |||
219 | /** |
||
220 | * Loads the configured indexes. |
||
221 | * |
||
222 | * @param array $indexTemplates An array of indexes configurations |
||
223 | * @param ContainerBuilder $container A ContainerBuilder instance |
||
224 | * |
||
225 | * @throws \InvalidArgumentException |
||
226 | * |
||
227 | * @return void |
||
228 | */ |
||
229 | 21 | private function loadIndexTemplates(array $indexTemplates, ContainerBuilder $container) |
|
230 | { |
||
231 | 21 | $indexableCallbacks = array(); |
|
232 | 21 | foreach ($indexTemplates as $name => $indexTemplate) { |
|
233 | 6 | $indexId = sprintf('fos_elastica.index_template.%s', $name); |
|
234 | 6 | $indexTemplateName = isset($indexTemplate['template_name']) ? $indexTemplate['template_name'] : $name; |
|
235 | |||
236 | 6 | $indexDef = new ChildDefinition('fos_elastica.index_template_prototype'); |
|
237 | 6 | $indexDef->setFactory([new Reference('fos_elastica.client'), 'getIndexTemplate']); |
|
238 | 6 | $indexDef->replaceArgument(0, $indexTemplateName); |
|
239 | 6 | $indexDef->addTag('fos_elastica.index_template', array( |
|
240 | 6 | 'name' => $name, |
|
241 | )); |
||
242 | |||
243 | 6 | View Code Duplication | if (isset($indexTemplate['client'])) { |
244 | 6 | $client = $this->getClient($indexTemplate['client']); |
|
245 | 6 | $indexDef->setFactory([$client, 'getIndexTemplate']); |
|
246 | } |
||
247 | |||
248 | 6 | $container->setDefinition($indexId, $indexDef); |
|
249 | 6 | $reference = new Reference($indexId); |
|
250 | |||
251 | 6 | $this->indexTemplateConfigs[$name] = array( |
|
252 | 6 | 'elasticsearch_name' => $indexTemplateName, |
|
253 | 6 | 'reference' => $reference, |
|
254 | 6 | 'name' => $name, |
|
255 | 6 | 'settings' => $indexTemplate['settings'], |
|
256 | 6 | 'template' => $indexTemplate['template'], |
|
257 | ); |
||
258 | |||
259 | 6 | $this->loadTypes( |
|
260 | 6 | (array) $indexTemplate['types'], |
|
261 | $container, |
||
262 | 6 | $this->indexTemplateConfigs[$name], |
|
263 | $indexableCallbacks |
||
264 | ); |
||
265 | } |
||
266 | |||
267 | 21 | if ($indexableCallbacks) { |
|
|
|||
268 | throw new \RuntimeException('`indexable_callback` option is not supported by index templates'); |
||
269 | } |
||
270 | 21 | } |
|
271 | |||
272 | /** |
||
273 | * Loads the configured index finders. |
||
274 | * |
||
275 | * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container |
||
276 | * @param string $name The index name |
||
277 | * @param Reference $index Reference to the related index |
||
278 | * |
||
279 | * @return string |
||
280 | */ |
||
281 | private function loadIndexFinder(ContainerBuilder $container, $name, Reference $index) |
||
297 | |||
298 | /** |
||
299 | * Loads the configured types. |
||
300 | * |
||
301 | * @param array $types |
||
302 | * @param ContainerBuilder $container |
||
303 | * @param array $indexConfig |
||
304 | * @param array $indexableCallbacks |
||
305 | */ |
||
306 | 21 | private function loadTypes(array $types, ContainerBuilder $container, array &$indexConfig, array &$indexableCallbacks) |
|
391 | |||
392 | 4 | private function buildCallback($indexCallback, $typeName) |
|
417 | |||
418 | 4 | private function transformServiceReference($classOrService) |
|
422 | |||
423 | /** |
||
424 | * Loads the optional provider and finder for a type. |
||
425 | * |
||
426 | * @param array $typeConfig |
||
427 | * @param ContainerBuilder $container |
||
428 | * @param Reference $typeRef |
||
429 | * @param string $indexName |
||
430 | * @param string $typeName |
||
431 | */ |
||
432 | 15 | private function loadTypePersistenceIntegration(array $typeConfig, ContainerBuilder $container, Reference $typeRef, $indexName, $typeName) |
|
452 | |||
453 | /** |
||
454 | * Creates and loads an ElasticaToModelTransformer. |
||
455 | * |
||
456 | * @param array $typeConfig |
||
457 | * @param ContainerBuilder $container |
||
458 | * @param string $indexName |
||
459 | * @param string $typeName |
||
460 | * |
||
461 | * @return string |
||
462 | */ |
||
463 | 15 | private function loadElasticaToModelTransformer(array $typeConfig, ContainerBuilder $container, $indexName, $typeName) |
|
485 | |||
486 | /** |
||
487 | * Creates and loads a ModelToElasticaTransformer for an index/type. |
||
488 | * |
||
489 | * @param array $typeConfig |
||
490 | * @param ContainerBuilder $container |
||
491 | * @param string $indexName |
||
492 | * @param string $typeName |
||
493 | * |
||
494 | * @return string |
||
495 | */ |
||
496 | 15 | private function loadModelToElasticaTransformer(array $typeConfig, ContainerBuilder $container, $indexName, $typeName) |
|
516 | |||
517 | /** |
||
518 | * Creates and loads an object persister for a type. |
||
519 | * |
||
520 | * @param array $typeConfig |
||
521 | * @param Reference $typeRef |
||
522 | * @param ContainerBuilder $container |
||
523 | * @param string $indexName |
||
524 | * @param string $typeName |
||
525 | * @param string $transformerId |
||
526 | * |
||
527 | * @return string |
||
528 | */ |
||
529 | 15 | private function loadObjectPersister(array $typeConfig, Reference $typeRef, ContainerBuilder $container, $indexName, $typeName, $transformerId) |
|
569 | |||
570 | /** |
||
571 | * Loads a pager provider for a type. |
||
572 | * |
||
573 | * @param array $typeConfig |
||
574 | * @param ContainerBuilder $container |
||
575 | * @param string $indexName |
||
576 | * @param string $typeName |
||
577 | * |
||
578 | * @return string |
||
579 | */ |
||
580 | 15 | private function loadTypePagerProvider(array $typeConfig, ContainerBuilder $container, $indexName, $typeName) |
|
624 | |||
625 | /** |
||
626 | * Loads doctrine listeners to handle indexing of new or updated objects. |
||
627 | * |
||
628 | * @param array $typeConfig |
||
629 | * @param ContainerBuilder $container |
||
630 | * @param string $objectPersisterId |
||
631 | * @param string $indexName |
||
632 | * @param string $typeName |
||
633 | * |
||
634 | * @return string |
||
635 | */ |
||
636 | 14 | private function loadTypeListener(array $typeConfig, ContainerBuilder $container, $objectPersisterId, $indexName, $typeName) |
|
697 | |||
698 | /** |
||
699 | * Map Elastica to Doctrine events for the current driver. |
||
700 | */ |
||
701 | 14 | private function getDoctrineEvents(array $typeConfig) |
|
733 | |||
734 | /** |
||
735 | * Loads a Type specific Finder. |
||
736 | * |
||
737 | * @param array $typeConfig |
||
738 | * @param ContainerBuilder $container |
||
739 | * @param string $elasticaToModelId |
||
740 | * @param Reference $typeRef |
||
741 | * @param string $indexName |
||
742 | * @param string $typeName |
||
743 | * |
||
744 | * @return string |
||
745 | */ |
||
746 | 15 | private function loadTypeFinder(array $typeConfig, ContainerBuilder $container, $elasticaToModelId, Reference $typeRef, $indexName, $typeName) |
|
773 | |||
774 | /** |
||
775 | * Loads the index manager. |
||
776 | * |
||
777 | * @param ContainerBuilder $container |
||
778 | **/ |
||
779 | View Code Duplication | private function loadIndexManager(ContainerBuilder $container) |
|
788 | |||
789 | /** |
||
790 | * Load index template manager |
||
791 | * |
||
792 | * @param ContainerBuilder $container |
||
793 | * |
||
794 | * @return void |
||
795 | */ |
||
796 | View Code Duplication | private function loadIndexTemplateManager(ContainerBuilder $container) |
|
805 | |||
806 | /** |
||
807 | * Makes sure a specific driver has been loaded. |
||
808 | * |
||
809 | * @param ContainerBuilder $container |
||
810 | * @param string $driver |
||
811 | */ |
||
812 | 15 | private function loadDriver(ContainerBuilder $container, $driver) |
|
822 | |||
823 | /** |
||
824 | * Loads and configures the serializer prototype. |
||
825 | * |
||
826 | * @param array $config |
||
827 | * @param ContainerBuilder $container |
||
828 | */ |
||
829 | 1 | private function loadSerializer($config, ContainerBuilder $container) |
|
840 | |||
841 | /** |
||
842 | * Creates a default manager alias for defined default manager or the first loaded driver. |
||
843 | * |
||
844 | * @param string $defaultManager |
||
845 | * @param ContainerBuilder $container |
||
846 | */ |
||
847 | 21 | private function createDefaultManagerAlias($defaultManager, ContainerBuilder $container) |
|
866 | |||
867 | /** |
||
868 | * Returns a reference to a client given its configured name. |
||
869 | * |
||
870 | * @param string $clientName |
||
871 | * |
||
872 | * @return Reference |
||
873 | * |
||
874 | * @throws \InvalidArgumentException |
||
875 | */ |
||
876 | 8 | private function getClient($clientName) |
|
884 | } |
||
885 |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.