Test Failed
Pull Request — master (#187)
by
unknown
08:08
created

ImportCommand   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 87
Duplicated Lines 0 %

Test Coverage

Coverage 42.86%

Importance

Changes 0
Metric Value
eloc 37
dl 0
loc 87
ccs 15
cts 35
cp 0.4286
rs 10
c 0
b 0
f 0
wmc 8

2 Methods

Rating   Name   Duplication   Size   Complexity  
A resultMessage() 0 6 2
B handle() 0 55 6
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 Algolia\AlgoliaSearch\SearchClient;
17
use Illuminate\Console\Command;
18
use Illuminate\Database\QueryException;
19
use Illuminate\Support\Collection;
20
use Illuminate\Support\Facades\Log;
21
use Laravel\Scout\Events\ModelsImported;
22
use Illuminate\Contracts\Events\Dispatcher;
23
use Algolia\ScoutExtended\Helpers\SearchableFinder;
24
use Algolia\ScoutExtended\Searchable\ObjectIdEncrypter;
25
26
final class ImportCommand extends Command
27
{
28
    /**
29
     * {@inheritdoc}
30
     */
31
    protected $signature = 'scout:import {searchable? : The name of the searchable}';
32
33
    /**
34
     * {@inheritdoc}
35
     */
36
    protected $description = 'Import the given searchable into the search index';
37
38
    /**
39
     * {@inheritdoc}
40
     */
41 1
    public function handle(Dispatcher $events, SearchableFinder $searchableFinder, SearchClient $client): void
42
    {
43 1
        foreach ($searchableFinder->fromCommand($this) as $searchable) {
44
45
            $events->listen(ModelsImported::class, function ($event) use ($searchable) {
46 1
                $this->resultMessage($event->models, $searchable);
47 1
            });
48
49 1
            $searchable::makeAllSearchable();
50
51 1
            $this->line("Checking for any records that need to be deleted");
52
53 1
            $model = new $searchable();
54 1
            $index = $client->initIndex($model->searchableAs());
55
56
57 1
            $builder = new \Laravel\Scout\Builder($model, '');
58
59
            // check for objects that should be deleted.
60 1
            $iterator = $index->browseObjects([
61 1
                'hitsPerPage' => 100
62
            ]);
63
64
            foreach ($iterator as $hit) {
65
                $searchKey = [ObjectIdEncrypter::decryptSearchableKey($hit['objectID'])];
66
67
                try {
68
                    $searchableObject = $model->getScoutModelsByIds($builder, $searchKey);
69
70
                    if ($searchableObject->count() === 1) {
71
                        if (! $searchableObject[0]->shouldBeSearchable()) {
72
                            Log::error("ImportCommand delete item unsearchable", [
73
                                'object' => $searchable,
74
                                'id' => $hit['objectID']
75
                            ]);
76
                            $searchableObject[0]->unsearchable();
77
                        }
78
                    } else {
79
                        Log::error("ImportCommand delete item", [
80
                            'object' => $searchable,
81
                            'id' => $hit['objectID']
82
                        ]);
83
                        $index->deleteObject($hit['objectID']);
84
                        $this->line("Found item to delete " . $hit['objectID']);
85
                    }
86
                } catch (QueryException $e) {
87
                    // this should only happen when they are type issues like id is int, and the key is alpha.
88
                    $index->deleteObject($hit['objectID']);
89
                    $this->line("Found item to delete " . $hit['objectID']);
90
                }
91
            }
92
93
            $events->forget(ModelsImported::class);
94
95
            $this->output->success('All ['.$searchable.'] records have been imported.');
96
        }
97
    }
98
99
    /**
100
     * Prints last imported object ID to console output, if any.
101
     *
102
     * @param \Illuminate\Support\Collection $models
103
     * @param string $searchable
104
     *
105
     * @return void
106
     */
107 1
    private function resultMessage(Collection $models, string $searchable): void
108
    {
109 1
        if ($models->count() > 0) {
110 1
            $last = ObjectIdEncrypter::encrypt($models->last());
111
112 1
            $this->line('<comment>Imported ['.$searchable.'] models up to ID:</comment> '.$last);
113
        }
114 1
    }
115
}
116