Completed
Push — master ( 4e2354...6b5601 )
by Saulius
07:38 queued 05:16
created

PersistentBatchObjectsManager::splitToChunks()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file is part of the sauls/object-registry-bundle package.
4
 *
5
 * @author    Saulius Vaičeliūnas <[email protected]>
6
 * @link      http://saulius.vaiceliunas.lt
7
 * @copyright 2018
8
 *
9
 * For the full copyright and license information, please view the LICENSE
10
 * file that was distributed with this source code.
11
 */
12
13
namespace Sauls\Bundle\ObjectRegistryBundle\Manager;
14
15
use Doctrine\ORM\EntityManagerInterface;
16
use Psr\Log\LoggerInterface;
17
use Sauls\Bundle\ObjectRegistryBundle\Batch\Operation\OperationInterface;
18
use Sauls\Bundle\ObjectRegistryBundle\Batch\Operation\PersistOperation;
19
use Sauls\Bundle\ObjectRegistryBundle\Batch\Operation\RemoveOperation;
20
use Sauls\Bundle\ObjectRegistryBundle\Collection\BatchOperationCollectionInterface;
21
use Sauls\Bundle\ObjectRegistryBundle\Event\GenericDoctrineCollectionEvent;
22
use Sauls\Bundle\ObjectRegistryBundle\EventDispatcher\EventDispatcherInterface;
23
use Sauls\Bundle\ObjectRegistryBundle\Exception\EmptyDataException;
24
use Sauls\Bundle\ObjectRegistryBundle\Exception\ManagerNotFoundException;
25
use Sauls\Bundle\ObjectRegistryBundle\Exception\OperationNotFoundException;
26
27
class PersistentBatchObjectsManager implements PersistentBatchObjectsManagerInterface
28
{
29
    /**
30
     * @var array
31
     */
32
    private $chunks;
33
34
    /**
35
     * @var DoctrineEntityManagerInterface
36
     */
37
    private $manager;
38
    /**
39
     * @var EntityManagerInterface
40
     */
41
    private $entityManager;
42
    /**
43
     * @var EventDispatcherInterface
44
     */
45
    private $eventDispatcher;
46
    /**
47
     * @var LoggerInterface
48
     */
49
    private $logger;
50
    /**
51
     * @var BatchOperationCollectionInterface
52
     */
53
    private $batchOperations;
54
55
    /**
56
     * @var array
57
     */
58
    private $refreshProperties;
0 ignored issues
show
introduced by
The private property $refreshProperties is not used, and could be removed.
Loading history...
59
60 6
    public function __construct(
61
        EntityManagerInterface $entityManager,
62
        EventDispatcherInterface $eventDispatcher,
63
        BatchOperationCollectionInterface $batchOperations,
64
        LoggerInterface $logger
65
    ) {
66 6
        $this->entityManager = $entityManager;
67 6
        $this->eventDispatcher = $eventDispatcher;
68 6
        $this->batchOperations = $batchOperations;
69 6
        $this->logger = $logger;
70 6
    }
71
72 5
    public function save(): bool
73
    {
74 5
        return $this->process(PersistOperation::NAME);
75
    }
76
77 6
    private function process(string $operationName): bool
78
    {
79 6
        $this->checkManagerIsNotNull();
80 5
        $this->checkChunksIsNotEmpty();
81
82
        try {
83 4
            $self = $this;
84
            $this->entityManager->transactional(function () use ($operationName, $self) {
85 3
                $self->processChunks($operationName);
86 4
            });
87 2
            return true;
88 2
        } catch (\Throwable $exception) {
89 2
            $this->logger->critical($exception->getMessage(), [$exception]);
90 2
            return false;
91
        }
92
    }
93
94 6
    private function checkManagerIsNotNull(): void
95
    {
96 6
        if (null === $this->manager) {
97 1
            throw new ManagerNotFoundException(
98 1
                'Manager cannot be `null` maybe you forgot to assign it? To do so use `setManager` method'
99
            );
100
        }
101 5
    }
102
103 5
    private function checkChunksIsNotEmpty(): void
104
    {
105 5
        if (true === empty($this->chunks)) {
106 1
            throw new EmptyDataException(
107 1
                \sprintf('No data to work with maybe you forgot to fill?')
108
            );
109
        }
110 4
    }
111
112 3
    private function processChunks(string $operationName): void
113
    {
114 3
        $operation = $this->getOperationByName($operationName);
115
116 2
        foreach ($this->chunks as $chunk) {
117 2
            $event = new GenericDoctrineCollectionEvent($chunk);
118 2
            $this->eventDispatcher->dispatch($operation->getPreEventName(), $event);
119 2
            $this->processChunk($operation, $chunk);
120 2
            $this->entityManager->flush();
121 2
            $this->eventDispatcher->dispatch($operation->getPostEventName(), $event);
122 2
            $this->entityManager->clear();
123
        }
124 2
    }
125
126 3
    private function getOperationByName(string $operationName): OperationInterface
127
    {
128 3
        $operation = $this->batchOperations->get($operationName);
129
130 3
        if (null === $operation) {
131 1
            throw new OperationNotFoundException(sprintf('Batch operation `%s` was not found', $operationName));
132
        }
133
134 2
        return $operation;
135
    }
136
137 2
    private function processChunk(OperationInterface $operation, array $chunk): void
138
    {
139 2
        foreach ($chunk as $object) {
140 2
            $this->manager->checkObjectIntegrity($object);
141 2
            $operation->execute($object);
142
        }
143 2
    }
144
145 1
    public function remove(): bool
146
    {
147 1
        return $this->process(RemoveOperation::NAME);
148
    }
149
150 4
    public function fill(array $objects, int $batchSize): void
151
    {
152 4
        $this->chunks = $this->splitToChunks($objects, $batchSize);
153 4
    }
154
155 4
    private function splitToChunks(array $objects, int $batchSize): array
156
    {
157 4
        return \array_chunk($objects, $batchSize);
158
    }
159
160 5
    public function setManager(DoctrineEntityManagerInterface $manager): void
161
    {
162 5
        $this->manager = $manager;
163 5
    }
164
}
165