Passed
Pull Request — master (#186)
by
unknown
07:36
created

ReImportCommand   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 103
Duplicated Lines 0 %

Test Coverage

Coverage 87.18%

Importance

Changes 10
Bugs 1 Features 0
Metric Value
eloc 46
c 10
b 1
f 0
dl 0
loc 103
ccs 34
cts 39
cp 0.8718
rs 10
wmc 8

2 Methods

Rating   Name   Duplication   Size   Complexity  
A getTemporaryIndexName() 0 3 1
B handle() 0 71 7
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * This file is part of Scout Extended.
7
 *
8
 * (c) Algolia Team <[email protected]>
9
 *
10
 *  For the full copyright and license information, please view the LICENSE
11
 *  file that was distributed with this source code.
12
 */
13
14
namespace Algolia\ScoutExtended\Console\Commands;
15
16
use function count;
17
use Illuminate\Console\Command;
18
use Algolia\AlgoliaSearch\SearchIndex;
19
use Algolia\AlgoliaSearch\SearchClient;
20
use Algolia\ScoutExtended\Helpers\SearchableFinder;
21
use Algolia\AlgoliaSearch\Exceptions\NotFoundException;
22
23
final class ReImportCommand extends Command
24
{
25
    /**
26
     * {@inheritdoc}
27
     */
28
    protected $signature = 'scout:reimport {searchable? : The name of the searchable}';
29
30
    /**
31
     * {@inheritdoc}
32
     */
33
    protected $description = 'Reimport the given searchable into the search index';
34
35
    /**
36
     * @var string
37
     */
38
    private static $prefix = 'temp';
39
40
    /**
41
     * {@inheritdoc}
42
     */
43 1
    public function handle(
44
        SearchClient $client,
45
        SearchableFinder $searchableModelsFinder
46
    ): void {
47 1
        $searchables = $searchableModelsFinder->fromCommand($this);
48
49 1
        $config = config();
50
51 1
        $scoutPrefix = $config->get('scout.prefix');
52
53 1
        $this->output->text('🔎 Importing: <info>['.implode(',', $searchables).']</info>');
54 1
        $this->output->newLine();
55 1
        $this->output->progressStart(count($searchables) * 3);
56
57 1
        foreach ($searchables as $searchable) {
58 1
            $index = $client->initIndex((new $searchable)->searchableAs());
59 1
            $temporaryName = $this->getTemporaryIndexName($index);
60
61 1
            tap($this->output)->progressAdvance()->text("Creating temporary index <info>{$temporaryName}</info>");
62
63
            try {
64 1
                $index->getSettings();
65
66 1
                $client->copyIndex($index->getIndexName(), $temporaryName, [
67 1
                    'scope' => [
68
                        'settings',
69
                        'synonyms',
70
                        'rules',
71
                    ],
72 1
                ])->wait();
73
            } catch (NotFoundException $e) {
74
                // ..
75
            }
76
77 1
            tap($this->output)->progressAdvance()->text("Importing records to index <info>{$temporaryName}</info>");
78
79
            try {
80 1
                $config->set('scout.prefix', self::$prefix.'_'.$scoutPrefix);
81 1
                $searchable::makeAllSearchable();
82 1
            } finally {
83 1
                $config->set('scout.prefix', $scoutPrefix);
84
            }
85
86 1
            tap($this->output)->progressAdvance()
87 1
                ->text("Replacing index <info>{$index->getIndexName()}</info> by index <info>{$temporaryName}</info>");
88
89 1
            $temporaryIndex = $client->initIndex($temporaryName);
90
91 1
            $hits = (int) $temporaryIndex->search('')['nbHits'];
92
93 1
            if ($hits === 0) {
94
                $response = $index->clearObjects();
95
                if ($config->get('scout.synchronous', false)) {
96
                    $response->wait();
97
                }
98
            } else {
99
                try {
100 1
                    $temporaryIndex->getSettings();
101
102 1
                    $response = $client->moveIndex($temporaryName, $index->getIndexName());
103
104 1
                    if ($config->get('scout.synchronous', false)) {
105 1
                        $response->wait();
106
                    }
107
                } catch (NotFoundException $e) {
108 1
                    $index->setSettings(['attributesForFaceting' => null])->wait();
109
                }
110
            }
111
        }
112
113 1
        tap($this->output)->success('All ['.implode(',', $searchables).'] records have been imported')->newLine();
114 1
    }
115
116
    /**
117
     * Get a temporary index name.
118
     *
119
     * @param \Algolia\AlgoliaSearch\SearchIndex $index
120
     *
121
     * @return string
122
     */
123 1
    private function getTemporaryIndexName(SearchIndex $index): string
124
    {
125 1
        return self::$prefix.'_'.$index->getIndexName();
126
    }
127
}
128