Completed
Push — master ( 4e4cd8...063296 )
by Maksim
16s
created

PopulateCommand::populateIndexType()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 33
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
dl 0
loc 33
ccs 0
cts 25
cp 0
rs 8.5806
c 0
b 0
f 0
cc 4
eloc 21
nc 4
nop 5
crap 20
1
<?php
2
3
/*
4
 * This file is part of the FOSElasticaBundle package.
5
 *
6
 * (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace FOS\ElasticaBundle\Command;
13
14
use FOS\ElasticaBundle\Event\IndexPopulateEvent;
15
use FOS\ElasticaBundle\Event\TypePopulateEvent;
16
use FOS\ElasticaBundle\Index\IndexManager;
17
use FOS\ElasticaBundle\Index\Resetter;
18
use FOS\ElasticaBundle\Persister\PagerPersisterInterface;
19
use FOS\ElasticaBundle\Provider\PagerProviderRegistry;
20
use FOS\ElasticaBundle\Provider\ProviderRegistry;
21
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
22
use Symfony\Component\Console\Helper\ProgressBar;
23
use Symfony\Component\Console\Helper\QuestionHelper;
24
use Symfony\Component\Console\Input\InputInterface;
25
use Symfony\Component\Console\Input\InputOption;
26
use Symfony\Component\Console\Output\OutputInterface;
27
use Symfony\Component\Console\Question\Question;
28
29
/**
30
 * Populate the search index.
31
 */
32
class PopulateCommand extends ContainerAwareCommand
33
{
34
    /**
35
     * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
36
     */
37
    private $dispatcher;
38
39
    /**
40
     * @var IndexManager
41
     */
42
    private $indexManager;
43
44
    /**
45
     * @var ProgressClosureBuilder
46
     */
47
    private $progressClosureBuilder;
48
49
    /**
50
     * @var ProviderRegistry
51
     */
52
    private $providerRegistry;
53
54
    /**
55
     * @var PagerProviderRegistry
56
     */
57
    private $pagerProviderRegistry;
58
59
    /**
60
     * @var PagerPersisterInterface
61
     */
62
    private $pagerPersister;
63
64
    /**
65
     * @var Resetter
66
     */
67
    private $resetter;
68
69
    /**
70
     * {@inheritdoc}
71
     */
72
    protected function configure()
73
    {
74
        $this
75
            ->setName('fos:elastica:populate')
76
            ->addOption('index', null, InputOption::VALUE_OPTIONAL, 'The index to repopulate')
77
            ->addOption('type', null, InputOption::VALUE_OPTIONAL, 'The type to repopulate')
78
            ->addOption('no-reset', null, InputOption::VALUE_NONE, 'Do not reset index before populating')
79
            ->addOption('no-delete', null, InputOption::VALUE_NONE, 'Do not delete index after populate')
80
            ->addOption('offset', null, InputOption::VALUE_REQUIRED, 'Start indexing at offset', 0)
81
            ->addOption('sleep', null, InputOption::VALUE_REQUIRED, 'Sleep time between persisting iterations (microseconds)', 0)
82
            ->addOption('batch-size', null, InputOption::VALUE_REQUIRED, 'Index packet size (overrides provider config option)')
83
            ->addOption('ignore-errors', null, InputOption::VALUE_NONE, 'Do not stop on errors')
84
            ->addOption('no-overwrite-format', null, InputOption::VALUE_NONE, 'Prevent this command from overwriting ProgressBar\'s formats')
85
            ->setDescription('Populates search indexes from providers')
86
        ;
87
    }
88
89
    /**
90
     * {@inheritdoc}
91
     */
92
    protected function initialize(InputInterface $input, OutputInterface $output)
93
    {
94
        $this->dispatcher = $this->getContainer()->get('event_dispatcher');
95
        $this->indexManager = $this->getContainer()->get('fos_elastica.index_manager');
96
        $this->providerRegistry = $this->getContainer()->get('fos_elastica.provider_registry');
97
        $this->pagerProviderRegistry = $this->getContainer()->get('fos_elastica.pager_provider_registry');
98
        $this->pagerPersister = $this->getContainer()->get('fos_elastica.pager_persister');
99
        $this->resetter = $this->getContainer()->get('fos_elastica.resetter');
100
        $this->progressClosureBuilder = new ProgressClosureBuilder();
101
102
        if (!$input->getOption('no-overwrite-format') && class_exists('Symfony\\Component\\Console\\Helper\\ProgressBar')) {
103
            ProgressBar::setFormatDefinition('normal', " %current%/%max% [%bar%] %percent:3s%%\n%message%");
104
            ProgressBar::setFormatDefinition('verbose', " %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%\n%message%");
105
            ProgressBar::setFormatDefinition('very_verbose', " %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s%\n%message%");
106
            ProgressBar::setFormatDefinition('debug', " %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s% %memory:6s%\n%message%");
107
        }
108
    }
109
110
    /**
111
     * {@inheritdoc}
112
     */
113
    protected function execute(InputInterface $input, OutputInterface $output)
114
    {
115
        $index = $input->getOption('index');
116
        $type = $input->getOption('type');
117
        $reset = !$input->getOption('no-reset');
118
        $delete = !$input->getOption('no-delete');
119
120
        $options = [
121
            'delete' => $delete,
122
            'reset' => $reset,
123
            'ignore_errors' => $input->getOption('ignore-errors'),
124
            'offset' => $input->getOption('offset'),
125
            'sleep' => $input->getOption('sleep'),
126
        ];
127
128
        if ($input->getOption('batch-size')) {
129
            $options['batch_size'] = (int) $input->getOption('batch-size');
130
        }
131
132
        if ($input->isInteractive() && $reset && $input->getOption('offset')) {
133
            /** @var QuestionHelper $dialog */
134
            $dialog = $this->getHelperSet()->get('question');
135
            if (!$dialog->ask($input, $output, new Question('<question>You chose to reset the index and start indexing with an offset. Do you really want to do that?</question>'))) {
136
                return;
137
            }
138
        }
139
140
        if (null === $index && null !== $type) {
141
            throw new \InvalidArgumentException('Cannot specify type option without an index.');
142
        }
143
144
        if (null !== $index) {
145
            if (null !== $type) {
146
                $this->populateIndexType($output, $index, $type, $reset, $options);
147
            } else {
148
                $this->populateIndex($output, $index, $reset, $options);
149
            }
150
        } else {
151
            $indexes = array_keys($this->indexManager->getAllIndexes());
152
153
            foreach ($indexes as $index) {
154
                $this->populateIndex($output, $index, $reset, $options);
155
            }
156
        }
157
    }
158
159
    /**
160
     * Recreates an index, populates its types, and refreshes the index.
161
     *
162
     * @param OutputInterface $output
163
     * @param string          $index
164
     * @param bool            $reset
165
     * @param array           $options
166
     */
167
    private function populateIndex(OutputInterface $output, $index, $reset, $options)
168
    {
169
        $event = new IndexPopulateEvent($index, $reset, $options);
170
        $this->dispatcher->dispatch(IndexPopulateEvent::PRE_INDEX_POPULATE, $event);
171
172
        if ($event->isReset()) {
173
            $output->writeln(sprintf('<info>Resetting</info> <comment>%s</comment>', $index));
174
            $this->resetter->resetIndex($index, true);
175
        }
176
177
        $types = array_keys($this->providerRegistry->getIndexProviders($index));
178
        foreach ($types as $type) {
179
            $this->populateIndexType($output, $index, $type, false, $event->getOptions());
180
        }
181
182
        $this->dispatcher->dispatch(IndexPopulateEvent::POST_INDEX_POPULATE, $event);
183
184
        $this->refreshIndex($output, $index, $reset);
0 ignored issues
show
Unused Code introduced by
The call to PopulateCommand::refreshIndex() has too many arguments starting with $reset.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
185
    }
186
187
    /**
188
     * Deletes/remaps an index type, populates it, and refreshes the index.
189
     *
190
     * @param OutputInterface $output
191
     * @param string          $index
192
     * @param string          $type
193
     * @param bool            $reset
194
     * @param array           $options
195
     */
196
    private function populateIndexType(OutputInterface $output, $index, $type, $reset, $options)
197
    {
198
        $event = new TypePopulateEvent($index, $type, $reset, $options);
199
        $this->dispatcher->dispatch(TypePopulateEvent::PRE_TYPE_POPULATE, $event);
200
201
        if ($event->isReset()) {
202
            $output->writeln(sprintf('<info>Resetting</info> <comment>%s/%s</comment>', $index, $type));
203
            $this->resetter->resetIndexType($index, $type);
204
        }
205
206
        $offset = $options['offset'];
207
        $loggerClosure = $this->progressClosureBuilder->build($output, 'Populating', $index, $type, $offset);
208
209
        if ($this->getContainer()->getParameter('fos_elastica.use_v5_api') || getenv('FOS_ELASTICA_USE_V5_API')) {
210
            $provider = $this->pagerProviderRegistry->getProvider($index, $type);
211
212
            $pager = $provider->provide($options);
213
214
            $options['indexName'] = $index;
215
            $options['typeName'] = $type;
216
            $options['batch_size'] = 100;
217
            $options['skip_indexable_check'] = false;
218
219
            $this->pagerPersister->insert($pager, $options);
220
        } else {
221
            $provider = $this->providerRegistry->getProvider($index, $type);
222
            $provider->populate($loggerClosure, $options);
223
        }
224
225
        $this->dispatcher->dispatch(TypePopulateEvent::POST_TYPE_POPULATE, $event);
226
227
        $this->refreshIndex($output, $index);
228
    }
229
230
    /**
231
     * Refreshes an index.
232
     *
233
     * @param OutputInterface $output
234
     * @param string          $index
235
     */
236
    private function refreshIndex(OutputInterface $output, $index)
237
    {
238
        $output->writeln(sprintf('<info>Refreshing</info> <comment>%s</comment>', $index));
239
        $this->indexManager->getIndex($index)->refresh();
240
    }
241
}
242