Completed
Push — master ( fef1f2...3eb154 )
by Tim
7s
created

AbstractProvider   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 161
Duplicated Lines 8.07 %

Coupling/Cohesion

Components 2
Dependencies 6

Test Coverage

Coverage 88.33%

Importance

Changes 1
Bugs 1 Features 0
Metric Value
wmc 12
c 1
b 1
f 0
lcom 2
cbo 6
dl 13
loc 161
ccs 53
cts 60
cp 0.8833
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
countObjects() 0 1 ?
createQueryBuilder() 0 1 ?
fetchSlice() 0 1 ?
A __construct() 0 13 1
C doPopulate() 0 44 8
A configureOptions() 13 13 1
A getSlice() 0 19 2

How to fix   Duplicated Code   

Duplicated Code

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:

1
<?php
2
3
namespace FOS\ElasticaBundle\Doctrine;
4
5
use Doctrine\Common\Persistence\ManagerRegistry;
6
use Elastica\Exception\Bulk\ResponseException as BulkResponseException;
7
use FOS\ElasticaBundle\Persister\ObjectPersisterInterface;
8
use FOS\ElasticaBundle\Provider\AbstractProvider as BaseAbstractProvider;
9
use FOS\ElasticaBundle\Provider\IndexableInterface;
10
use Symfony\Component\OptionsResolver\OptionsResolver;
11
12
abstract class AbstractProvider extends BaseAbstractProvider
13
{
14
    /**
15
     * @var SliceFetcherInterface
16
     */
17
    private $sliceFetcher;
18
19
    /**
20
     * @var ManagerRegistry
21
     */
22
    protected $managerRegistry;
23
24
    /**
25
     * Constructor.
26
     *
27
     * @param ObjectPersisterInterface $objectPersister
28
     * @param IndexableInterface       $indexable
29
     * @param string                   $objectClass
30
     * @param array                    $baseOptions
31
     * @param ManagerRegistry          $managerRegistry
32
     * @param SliceFetcherInterface    $sliceFetcher
33
     */
34 9
    public function __construct(
35
        ObjectPersisterInterface $objectPersister,
36
        IndexableInterface $indexable,
37
        $objectClass,
38
        array $baseOptions,
39
        ManagerRegistry $managerRegistry,
40
        SliceFetcherInterface $sliceFetcher = null
41
    ) {
42 9
        parent::__construct($objectPersister, $indexable, $objectClass, $baseOptions);
43
44 9
        $this->managerRegistry = $managerRegistry;
45 9
        $this->sliceFetcher = $sliceFetcher;
46 9
    }
47
48
    /**
49
     * Counts objects that would be indexed using the query builder.
50
     *
51
     * @param object $queryBuilder
52
     *
53
     * @return integer
54
     */
55
    abstract protected function countObjects($queryBuilder);
56
57
    /**
58
     * Creates the query builder, which will be used to fetch objects to index.
59
     *
60
     * @param string $method
61
     *
62
     * @return object
63
     */
64
    abstract protected function createQueryBuilder($method);
65
66
    /**
67
     * Fetches a slice of objects using the query builder.
68
     *
69
     * @param object  $queryBuilder
70
     * @param integer $limit
71
     * @param integer $offset
72
     *
73
     * @return array
74
     */
75
    abstract protected function fetchSlice($queryBuilder, $limit, $offset);
76
77
    /**
78
     * {@inheritDoc}
79
     */
80 9
    protected function doPopulate($options, \Closure $loggerClosure = null)
81
    {
82 9
        $manager = $this->managerRegistry->getManagerForClass($this->objectClass);
83
84 9
        $queryBuilder = $this->createQueryBuilder($options['query_builder_method']);
85 9
        $nbObjects = $this->countObjects($queryBuilder);
86 9
        $offset = $options['offset'];
87
88 9
        $objects = array();
89 9
        for (; $offset < $nbObjects; $offset += $options['batch_size']) {
90 9
            $sliceSize = $options['batch_size'];
91
            try {
92 9
                $objects = $this->getSlice($queryBuilder, $options['batch_size'], $offset, $objects);
93 9
                $sliceSize = count($objects);
94 9
                $objects = $this->filterObjects($options, $objects);
95
96 9
                if (!empty($objects)) {
97 8
                    $this->objectPersister->insertMany($objects);
98 7
                }
99 9
            } catch (BulkResponseException $e) {
100 1
                if (!$options['ignore_errors']) {
101 1
                    throw $e;
102
                }
103
104
                if (null !== $loggerClosure) {
105
                    $loggerClosure(
106
                        $options['batch_size'],
107
                        $nbObjects,
108
                        sprintf('<error>%s</error>', $e->getMessage())
109
                    );
110
                }
111
            }
112
113 8
            if ($options['clear_object_manager']) {
114 7
                $manager->clear();
115 7
            }
116
117 8
            usleep($options['sleep']);
118
119 8
            if (null !== $loggerClosure) {
120 1
                $loggerClosure($sliceSize, $nbObjects);
121 1
            }
122 8
        }
123 8
    }
124
125
    /**
126
     * {@inheritDoc}
127
     */
128 9 View Code Duplication
    protected function configureOptions()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
129
    {
130 9
        parent::configureOptions();
131
132 9
        $this->resolver->setDefaults(array(
133 9
            'clear_object_manager' => true,
134 9
            'debug_logging'        => false,
135 9
            'ignore_errors'        => false,
136 9
            'offset'               => 0,
137 9
            'query_builder_method' => 'createQueryBuilder',
138
            'sleep'                => 0
139 9
        ));
140 9
    }
141
142
    /**
143
     * If this Provider has a SliceFetcher defined, we use it instead of falling back to
144
     * the fetchSlice methods defined in the ORM/MongoDB subclasses.
145
     *
146
     * @param $queryBuilder
147
     * @param int   $limit
148
     * @param int   $offset
149
     * @param array $lastSlice
150
     *
151
     * @return array
152
     */
153 9
    private function getSlice($queryBuilder, $limit, $offset, $lastSlice)
154
    {
155 9
        if (!$this->sliceFetcher) {
156 2
            return $this->fetchSlice($queryBuilder, $limit, $offset);
157
        }
158
159 7
        $manager = $this->managerRegistry->getManagerForClass($this->objectClass);
160
        $identifierFieldNames = $manager
161 7
            ->getClassMetadata($this->objectClass)
162 7
            ->getIdentifierFieldNames();
163
164 7
        return $this->sliceFetcher->fetch(
165 7
            $queryBuilder,
166 7
            $limit,
167 7
            $offset,
168 7
            $lastSlice,
169
            $identifierFieldNames
170 7
        );
171
    }
172
}
173