Passed
Push — master ( 679877...b03fda )
by Alexander
03:23
created

ClearUnusedTranslationsCommand::getAllIdentifier()   C

Complexity

Conditions 7
Paths 6

Size

Total Lines 48
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 48
rs 6.7272
c 0
b 0
f 0
cc 7
eloc 26
nc 6
nop 0
1
<?php
2
3
namespace Hokan22\LaravelTranslator\Commands;
4
5
use Hokan22\LaravelTranslator\Models\TranslationIdentifier;
6
use Hokan22\LaravelTranslator\Models\Translations;
7
use Hokan22\LaravelTranslator\TranslatorFacade;
8
use Illuminate\Support\Facades\File;
9
use Illuminate\Console\Command;
10
11
class ClearUnusedTranslationsCommand extends Command {
12
13
    /**
14
     * The name and signature of the console command.
15
     *
16
     * @var string
17
     */
18
    protected $signature = 'translator:clear-unused';
19
20
    /**
21
     * The console command description.
22
     *
23
     * @var string
24
     */
25
    protected $description = '';
26
27
    protected $cache = [];
28
29
    protected $found_identifier = 0;
30
31
    protected $folders;
32
    protected $extensions;
33
34
35
    /**
36
     * Create a new command instance.
37
     *
38
     */
39
    public function __construct() {
40
        parent::__construct();
41
    }
42
43
    public function handle() {
44
        // Get start time
45
        $start = microtime(true);
46
        $not_used = 0;
47
        $found_plain = 0;
48
        $removed = 0;
49
50
        $this->folders = TranslatorFacade::getConfigValue('search_folders');
51
        $this->extensions = TranslatorFacade::getConfigValue('search_extensions');
52
53
        $aFiles = $this->getAllIdentifier();
54
55
        $aDB = $this->loadFromDB();
56
57
        foreach ($aDB as $identifier) {
58
59
            if(!in_array($identifier->identifier, $aFiles)) {
60
61
                $found_as_plain = $this->verifyMissing($identifier->identifier);
62
63
                $this->line('');
64
65
                if ($found_as_plain) {
66
                    $this->warn('\''.$identifier->identifier.'\' was not found withing Translator directives');
67
                    $found_plain++;
68
                } else {
69
                    $this->line('\''.$identifier->identifier.'\' seems to be not used anymore');
70
                    $not_used++;
71
                }
72
73
                $task = $this->choice('What do you want me to do?', ['Nothing' ,'Remove'], 0);
74
75
                if ($task === 'Remove') {
76
                    $identifier->delete();
77
                    Translations::where('translation_identifier_id', $identifier->id)->delete();
78
                    $removed++;
79
                }
80
            }
81
        }
82
        
83
        $this->table(['Num', 'Identifier'],[
84
            [$this->found_identifier,  "In DB"],
85
            [$not_used,     "Not Found"],
86
            [$found_plain,  "Found Plain"],
87
            [$removed,  "Removed"],
88
        ]);
89
        
90
        $this->info($not_used.' Translations no longer used.');
91
        $this->line('');
92
93
        $this->info('Finished in: ' . number_format(microtime(true) - $start, 2) . 'sec');
94
    }
95
96
    /**
97
     * @param $identifier string The Identifier to search
98
     * @return boolean boolean True if Identifier was found false if it was not
99
     */
100
    public function verifyMissing($identifier) {
101
        $aFiles = [];
102
        $found = false;
103
104
        $valid_extensions = ['php', 'html', 'js'];
105
        $folders = [
106
            'app',
107
            'config',
108
            'resources/views',
109
            'resources/assets/js',
110
        ];
111
112
        foreach($folders as $folder){
113
            $aFiles = array_merge($aFiles, File::allFiles(base_path().'/'.$folder));
114
        }
115
116
        $num_files = count($aFiles);
117
118
        $this->bar = $this->output->createProgressBar($num_files);
0 ignored issues
show
Bug Best Practice introduced by
The property bar does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
119
        $this->bar->setMessage('Analyzing '.$num_files.' files');
120
        $this->bar->setFormat('very_verbose');
121
122
        $pattern = preg_quote($identifier, '/');
123
        $pattern = "/^.*$pattern.*\$/m";
124
125
        /** @var File $file */
126
        foreach ($aFiles as $file) {
127
128
            $extension = $file->getExtension();
129
130
            if(in_array($extension, $valid_extensions)){
131
132
                $content = file_get_contents($file);
133
                if (preg_match_all($pattern, $content, $matches)){
134
                    $this->bar->clear();
135
                    $this->warn('\''.$identifier.'\' is used in: \''. $file->getPath().'\'!');
136
137
                    foreach ($matches[0] as $match) {
138
                         $this->warn($match);
139
                    }
140
                    $found = true;
141
                    $this->bar->display();
142
                }
143
            }
144
            $this->bar->advance();
145
        }
146
        $this->bar->finish();
147
148
        return $found;
149
    }
150
151
    /**
152
     * @return array
153
     */
154
    public function getAllIdentifier() {
155
        $aFiles = [];
156
        $return = [];
157
158
        $regexes = [
159
            'default'   => '/(?:[\@|\_]t\()["\'](?\'identifier\'.*?)["\'](?:\)|(?:, (?\'parameters\'\[.*\]))(?:\)|, \'(?\'locale\'\w*?)\'))/',
160
            'js'        => '/\$filter\(\'translate\'\)\(\'(?\'identifier\'.*?)\'\)/'
161
        ];
162
163
        foreach($this->folders as $folder){
164
            $aFiles = array_merge($aFiles, File::allFiles(base_path().'/'.$folder));
165
        }
166
167
        //TranslatorFacade::setLocale('de_DE');
168
169
        $num_files = count($aFiles);
170
171
        $this->bar = $this->output->createProgressBar($num_files);
0 ignored issues
show
Bug Best Practice introduced by
The property bar does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
172
        $this->bar->setMessage('Analyzing '.$num_files.' files');
173
        $this->bar->setFormat('very_verbose');
174
175
        foreach ($aFiles as $file) {
176
177
            $extension = $file->getExtension();
178
179
            if(in_array($extension, $this->extensions)){
180
                $content = file_get_contents($file);
181
182
                foreach ($regexes as $key => $regex) {
183
                    preg_match_all($regex, $content, $result, PREG_SET_ORDER);
184
185
                    if(!empty($result[0])){
186
                        foreach ($result as $item) {
187
                            $this->found_identifier++;
188
                            $return[] = $item['identifier'];
189
                        }
190
                    }
191
                }
192
            }
193
            $this->bar->advance();
194
        }
195
196
        $this->bar->finish();
197
        $this->line('');
198
199
        $this->info($this->found_identifier.' Translations found.');
200
201
        return $return;
202
    }
203
204
    /**
205
     * Get all translation identifier with translation from the given locale
206
     *
207
     * @return TranslationIdentifier|\Illuminate\Database\Eloquent\Collection|static[]
208
     */
209
    private function loadFromDB () {
210
        // Get all Texts with translations for the given locale
211
        $trans_identifier =   TranslationIdentifier::select(['id', 'identifier'])->get();
212
213
        return $trans_identifier;
214
    }
215
}
216