Completed
Push — master ( ded070...d4021a )
by
unknown
01:26
created

StatusCommand   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 151
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
wmc 14
lcom 1
cbo 4
dl 0
loc 151
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace TeamTNT\Scout\Console;
4
5
use Illuminate\Console\Command;
6
use Illuminate\Contracts\Events\Dispatcher;
7
use TeamTNT\TNTSearch\Exceptions\IndexNotFoundException;
8
use TeamTNT\TNTSearch\Indexer\TNTIndexer;
9
use TeamTNT\TNTSearch\TNTSearch;
10
use Illuminate\Support\Facades\Schema;
11
use Symfony\Component\Finder\Finder;
12
13
class StatusCommand extends Command
14
{
15
    /**
16
     * The name and signature of the console command.
17
     *
18
     * @var string
19
     */
20
    protected $signature = 'scout:status {model? : The name of the model}';
21
22
    /**
23
     * The console command description.
24
     *
25
     * @var string
26
     */
27
    protected $description = 'Status of the search index by TNTSeach';
28
29
    /**
30
     * @var array
31
     */
32
    private static $declaredClasses;
33
34
35
    /**
36
     * Execute the console command.
37
     *
38
     * @param \Illuminate\Contracts\Events\Dispatcher $events
39
     *
40
     * @return void
41
     */
42
    public function handle(Dispatcher $events)
43
    {
44
45
        $searchableModels = $this->getSearchableModels();
46
47
        $this->output->text('🔎 Analysing information from: <info>['.implode(',', $searchableModels).']</info>');
48
        $this->output->newLine();
49
        $this->output->progressStart(count($searchableModels));
50
51
        $headers = ['Searchable', 'Index', 'Indexed Columns', 'Index Records', 'DB Records', 'Records difference'];
52
        $rows = [];
53
        foreach ($searchableModels as $class) {
54
            $model = new $class();
55
56
            $tnt = $this->loadTNTEngine($model);
57
            $indexName = $model->searchableAs().'.index';
58
59
            try {
60
                $tnt->selectIndex($indexName);
61
                $rowsIndexed = $tnt->totalDocumentsInCollection();
62
            } catch (IndexNotFoundException $e) {
63
                $rowsIndexed = 0;
64
            }
65
66
            $indexedColumns = implode(",", array_keys($model->toSearchableArray()));
67
68
            $rowsTotal = $model->count();
69
            $recordsDifference = $rowsTotal - $rowsIndexed;
70
71
            if($recordsDifference == 0) {
72
                $recordsDifference = '<fg=green>Synchronized</>';
73
            } else {
74
                $recordsDifference = "<fg=red>$recordsDifference</>";
75
            }
76
77
            array_push($rows, [$class, $indexName, $indexedColumns, $rowsIndexed, $rowsTotal, $recordsDifference]);
78
79
        }
80
81
        $this->output->progressFinish();
82
        $this->output->table($headers, $rows, $tableStyle = 'default', $columnStyles = []);
83
    }
84
85
    /**
86
     * @return array
87
     */
88
    private function getProjectClasses(): array
89
    {
90
91
        if (self::$declaredClasses === null) {
92
            $configFiles = Finder::create()->files()->name('*.php')->notName('*.blade.php')->in(app()->path());
93
94
            foreach ($configFiles->files() as $file) {
95
                try {
96
                    require_once $file;
97
                } catch (\Exception $e) {
98
                    //skiping if the file cannot be loaded
99
                }
100
                catch (\Throwable $e) {
101
                    //skiping if the file cannot be loaded
102
                }
103
104
            self::$declaredClasses = get_declared_classes();
105
        }
106
107
        return self::$declaredClasses;
108
    }
109
110
    /**
111
     * @return array|void
112
     */
113
    private function getSearchableModelsFromClasses($trait = 'Laravel\Scout\Searchable')
0 ignored issues
show
Bug introduced by
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected T_PRIVATE
Loading history...
114
    {
115
        $projectClasses = $this->getProjectClasses();
116
        $classes = array_filter(
117
            $projectClasses,
118
            $this->isSearchableModel($trait)
119
        );
120
121
        return $classes;
122
    }
123
124
    /**
125
     * @return array
126
     */
127
    private function getSearchableModels()
128
    {
129
        $searchableModels = (array)$this->argument('model');
130
        if (empty($searchableModels)) {
131
            $searchableModels = $this->getSearchableModelsFromClasses();
132
        }
133
134
        return $searchableModels;
135
    }
136
137
    /**
138
     * @param $trait
139
     * @return \Closure
140
     */
141
    private function isSearchableModel($trait)
142
    {
143
        return function ($className) use ($trait) {
144
            $traits = class_uses($className);
145
146
            return isset($traits[$trait]);
147
        };
148
    }
149
150
    /**
151
     * @param $model
152
     * @return TNTSearch
153
     */
154
    private function loadTNTEngine($model)
155
    {
156
        $tnt = new TNTSearch();
157
158
        $driver = $model->getConnectionName() ?: config('database.default');
159
        $config = config('scout.tntsearch') + config("database.connections.$driver");
160
        $tnt->loadConfig($config);
161
162
        return $tnt;
163
    }
164
}
165