IndexEntitiesCommand::processRepository()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.9332
c 0
b 0
f 0
cc 3
nc 3
nop 2
1
<?php
2
3
namespace Mdiyakov\DoctrineSolrBundle\Command;
4
5
use Doctrine\Bundle\DoctrineBundle\Registry;
6
use Doctrine\ORM\EntityManager;
7
use Doctrine\ORM\EntityRepository;
8
use Symfony\Component\Console\Input\InputArgument;
9
use Symfony\Component\Console\Input\InputInterface;
10
use Symfony\Component\Console\Output\OutputInterface;
11
use Symfony\Component\Console\Command\Command;
12
use Mdiyakov\DoctrineSolrBundle\Config\Config;
13
use Mdiyakov\DoctrineSolrBundle\Manager\IndexProcessManager;
14
15
class IndexEntitiesCommand extends Command
16
{
17
18
    const BUNCH_COUNT = 100;
19
20
    /**
21
     * @var Registry
22
     */
23
    private $registry;
24
25
    /**
26
     * @var Config
27
     */
28
    private $config;
29
30
    /**
31
     * @var array
32
     */
33
    private $possibleEntityTypes;
34
35
    /**
36
     * @var IndexProcessManager
37
     */
38
    private $indexProcessManager;
39
40
    /**
41
     * @var OutputInterface
42
     */
43
    private $output;
44
45
    /**
46
     * @param Config $config
47
     * @param IndexProcessManager $indexProcessManager
48
     * @param Registry $registry
49
     */
50
    public function __construct(Config $config, IndexProcessManager $indexProcessManager, Registry $registry)
51
    {
52
        $this->config = $config;
53
        $this->indexProcessManager = $indexProcessManager;
54
        $this->possibleEntityTypes = array_keys($this->getAssocEntitiesClasses());
55
        $this->registry = $registry;
56
57
        parent::__construct();
58
    }
59
60
61
    /**
62
     * {@inheritdoc}
63
     */
64
    protected function configure()
65
    {
66
        $this
67
            ->setName('doctrine-solr:index')
68
            ->addArgument(
69
                'entity-type',
70
                InputArgument::OPTIONAL,
71
                'Specify type of entity to be indexed. Possible values are "all", "' . join('","', $this->possibleEntityTypes),
72
                'all'
73
            )
74
            ->addArgument(
75
                'id',
76
                InputArgument::OPTIONAL,
77
                'Specify id of entity to be indexed. Value must be integer. Also entity-type must be specify'
78
            )
79
        ;
80
    }
81
82
    /**
83
     * {@inheritdoc}
84
     */
85
    protected function execute(InputInterface $input, OutputInterface $output)
86
    {
87
        $this->output = $output;
88
        $entityType = $input->getArgument('entity-type');
89
        $entityId = (int) $input->getArgument('id');
90
91
        if ($entityType == 'all') {
92
            foreach ($this->config->getIndexedClasses() as $entityClass) {
93
                $this->indexEntityClass($entityClass);
94
            }
95
        } else {
96
            $entitiesClasses = $this->getAssocEntitiesClasses();
97
            if (!array_key_exists($entityType, $entitiesClasses )) {
98
                throw new \Exception('There is no such possible entity-type. Check help section for possible values');
99
            }
100
            $entityClass = $entitiesClasses[$entityType];
101
            $this->indexEntityClass($entityClass, $entityId);
102
        }
103
    }
104
105
    /**
106
     * @param string $entityClass
107
     * @param int|null $id
108
     * @throws \Exception
109
     * @throws \LogicException
110
     */
111
    private function indexEntityClass($entityClass, $id = null)
112
    {
113
        $em = $this->registry->getManagerForClass($entityClass);
114
        if (!$em instanceof EntityManager) {
115
            throw new \LogicException('EntityManager must be instance of EntityManager');
116
        }
117
118
        $repository = $em->getRepository($entityClass);
119
        if ($id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $id of type null|integer is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
120
            $entity = $repository->find($id);
121
            if (!$entity) {
122
                throw new \Exception(
123
                    sprintf('There is no %s with id %s in database', $entityClass, $id)
124
                );
125
            }
126
            $this->processEntity($entity);
127
        } else {
128
            $this->processRepository($repository, $em);
129
        }
130
    }
131
132
    /**
133
     * @param EntityRepository $repository
134
     * @param EntityManager $em
135
     */
136
    private function processRepository(EntityRepository $repository, EntityManager $em)
137
    {
138
        $offset = 0;
139
        while ($entities = $repository->findBy([],['id'=> 'asc'], self::BUNCH_COUNT, $offset)) {
140
            foreach ($entities as $entity) {
141
                $this->processEntity($entity);
142
            }
143
144
            $em->clear($repository->getClassName());
145
            $offset += self::BUNCH_COUNT;
146
        }
147
    }
148
149
    /**
150
     * @param $entity
151
     */
152
    private function processEntity($entity)
153
    {
154
        $result = $this->indexProcessManager->reindex($entity);
155
        $status = $result->isSuccess() ? 'successfully' : 'failed. Error ' . $result->getError();
156
        $message = sprintf('Indexing of %s with id %s is %s',
157
            get_class($entity),
158
            $entity->getId(),
159
            $status
160
        );
161
        $this->output->writeln($message);
162
    }
163
164
    /**
165
     * @return string[]
166
     */
167
    private function getAssocEntitiesClasses()
168
    {
169
        $entitiesConfigs = $this->config->getIndexedEntities();
170
171
        $result = [];
172
        foreach ($entitiesConfigs as $entityKey => $entityConfig) {
173
            $result[$entityKey] = $entityConfig['class'];
174
        }
175
176
        return $result;
177
    }
178
}