Completed
Pull Request — 3.1.x (#1038)
by Karel
25:25 queued 15:24
created

AbstractProvider::configureOptions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 13
ccs 10
cts 10
cp 1
rs 9.4285
cc 1
eloc 9
nc 1
nop 0
crap 1
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
            try {
91 9
                $objects = $this->getSlice($queryBuilder, $options['batch_size'], $offset, $objects);
92 9
                $objects = $this->filterObjects($options, $objects);
93
94 9
                if (!empty($objects)) {
95 8
                    $this->objectPersister->insertMany($objects);
96 7
                }
97 9
            } catch (BulkResponseException $e) {
98 1
                if (!$options['ignore_errors']) {
99 1
                    throw $e;
100
                }
101
102
                if (null !== $loggerClosure) {
103
                    $loggerClosure(
104
                        $options['batch_size'],
105
                        $nbObjects,
106
                        sprintf('<error>%s</error>', $e->getMessage())
107
                    );
108
                }
109
            }
110
111 8
            if ($options['clear_object_manager']) {
112 7
                $manager->clear();
113 7
            }
114
115 8
            usleep($options['sleep']);
116
117 8
            if (null !== $loggerClosure) {
118 1
                $loggerClosure($options['batch_size'], $nbObjects);
119 1
            }
120 8
        }
121 8
    }
122
123
    /**
124
     * If this Provider has a SliceFetcher defined, we use it instead of falling back to
125
     * the fetchSlice methods defined in the ORM/MongoDB subclasses.
126 9
     *
127
     * @param $queryBuilder
128 9
     * @param int   $limit
129
     * @param int   $offset
130 9
     * @param array $lastSlice
131 9
     *
132 9
     * @return array
133 9
     */
134 9
    private function getSlice($queryBuilder, $limit, $offset, $lastSlice)
135 9
    {
136
        if (!$this->sliceFetcher) {
137 9
            return $this->fetchSlice($queryBuilder, $limit, $offset);
138 9
        }
139
140
        $manager = $this->managerRegistry->getManagerForClass($this->objectClass);
141
        $identifierFieldNames = $manager
142
            ->getClassMetadata($this->objectClass)
143
            ->getIdentifierFieldNames();
144
145
        return $this->sliceFetcher->fetch(
146
            $queryBuilder,
147
            $limit,
148
            $offset,
149
            $lastSlice,
150
            $identifierFieldNames
151 9
        );
152
    }
153
}
154