Completed
Push — master ( 0957a7...85c2d9 )
by David
13:49 queued 01:49
created

ValidateUKMobileCommand::validateOutputPath()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 6
nc 2
nop 0
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace App\Commands;
4
5
use App\PhoneNumberValidator;
6
use Illuminate\Support\Carbon;
7
use Illuminate\Support\Collection;
8
use Illuminate\Support\Facades\File;
9
use LaravelZero\Framework\Commands\Command;
10
use Symfony\Component\Console\Exception\RuntimeException;
11
12
class ValidateUKMobileCommand extends Command
13
{
14
    /**
15
     * The name and signature of the console command.
16
     *
17
     * @var string
18
     */
19
    protected $signature = 'validate:uk-mobile
20
                            {source* : A list of numbers or files to validate against}
21
                            {--file : Specifies that the source is a list of files}
22
                            {--output= : Specifies that the output path}';
23
24
    /**
25
     * The console command description.
26
     *
27
     * @var string
28
     */
29
    protected $description = 'Validate UK mobile numbers and ouput to a CSV';
30
31
    /**
32
     * @var mixed
33
     */
34
    protected $source;
35
36
    /**
37
     * @var array
38
     */
39
    protected $validCountryCodes = [
40
        'GB', 'GG', 'JE',
41
    ];
42
43
    /**
44
     * Create a new command instance.
45
     *
46
     * @return void
47
     */
48
    public function __construct()
49
    {
50
        parent::__construct();
51
52
        $date = Carbon::now()->format('Ymd_his');
53
        $rand = mb_strtolower(str_random(6));
54
55
        $this->fileName = $date.'-'.$rand.'.csv';
0 ignored issues
show
Bug Best Practice introduced by
The property fileName does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
56
        $this->outputPath = base_path('output');
0 ignored issues
show
Bug Best Practice introduced by
The property outputPath does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
57
    }
58
59
    /**
60
     * Execute the console command.
61
     *
62
     * @return mixed
63
     */
64
    public function handle(): void
65
    {
66
        $this->setSource();
67
        $this->validateOutputPath();
68
69
        $this->buildCsvFromRows(
70
            $this->compileRowsFromSource($this->source)
71
        );
72
73
        $this->info('Total: '.count($this->source));
74
        $this->info('Filename: '.$this->fileName);
75
    }
76
77
    /**
78
     * Build a CSV from the rows.
79
     *
80
     * @param  Collection $rows
81
     * @return void
82
     */
83
    protected function buildCsvFromRows(Collection $rows)
84
    {
85
        $path = $this->outputPath.'/'.$this->fileName;
86
        File::put($path, implode("\n", $rows->toArray()));
87
    }
88
89
    /**
90
     * Process a list of numbers.
91
     *
92
     * @param array $source
93
     * @return Illuminate\Support\Collection
0 ignored issues
show
Bug introduced by
The type App\Commands\Illuminate\Support\Collection was not found. Did you mean Illuminate\Support\Collection? If so, make sure to prefix the type with \.
Loading history...
94
     */
95
    protected function compileRowsFromSource(array $source): Collection
96
    {
97
        return collect($source)
98
            ->map(function ($number) {
99
                return app(PhoneNumberValidator::class)->make($number, 'GB');
100
            })->map(function ($number) {
101
                return $this->buildRowFromValidator($number);
102
            })
103
            ->prepend(['phone number', 'carrier', 'status'])
104
            ->map(function ($row) {
105
                return implode(',', $row);
106
            });
107
    }
108
109
    /**
110
     * Build a row.
111
     *
112
     * @param  App\PhoneNumberValidator $validator
0 ignored issues
show
Bug introduced by
The type App\Commands\App\PhoneNumberValidator was not found. Did you mean App\PhoneNumberValidator? If so, make sure to prefix the type with \.
Loading history...
113
     * @return array
114
     */
115
    protected function buildRowFromValidator(PhoneNumberValidator $validator): array
116
    {
117
        $row = [$validator->getNumber(), '', 'not valid'];
0 ignored issues
show
Bug introduced by
The method getNumber() does not exist on App\PhoneNumberValidator. Since it exists in all sub-types, consider adding an abstract or default implementation to App\PhoneNumberValidator. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

117
        $row = [$validator->/** @scrutinizer ignore-call */ getNumber(), '', 'not valid'];
Loading history...
118
119
        if ($validator->isValidMobile() && $validator->isValidForCountry($this->validCountryCodes)) {
120
            $row[1] = $validator->getCarrierName();
121
            $row[2] = 'valid';
122
        }
123
124
        return $row;
125
    }
126
127
    /**
128
     * Set the source.
129
     */
130
    protected function setSource(): void
131
    {
132
        $this->source = $this->option('file')
133
            ? $this->getSourceFromFile($this->argument('source'))
134
            : array_wrap($this->argument('source'));
135
136
        $this->info('Source valid: '.($this->option('file') ? 'File' : 'List'));
137
    }
138
139
    /**
140
     * Return the contents of the source file.
141
     *
142
     * @return array
143
     */
144
    protected function getSourceFromFile($file): array
145
    {
146
        $file = head(array_wrap($file));
147
148
        throw_unless(
149
            File::exists($file),
150
            RuntimeException::class,
151
            "Source does not exist [{$file}]"
0 ignored issues
show
Bug introduced by
EncapsedNode of type string is incompatible with the type array expected by parameter $parameters of throw_unless(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

151
            /** @scrutinizer ignore-type */ "Source does not exist [{$file}]"
Loading history...
152
        );
153
154
        return array_wrap(explode("\n", File::get($file)));
155
    }
156
157
    /**
158
     * Set the output path.
159
     */
160
    protected function validateOutputPath(): void
161
    {
162
        if ($this->option('output')) {
163
            $this->outputPath = $this->option('output');
0 ignored issues
show
Bug Best Practice introduced by
The property outputPath does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
164
        }
165
166
        throw_unless(
167
            is_dir($this->outputPath),
168
            RuntimeException::class,
169
            "The output path does not exist [{$this->outputPath}]"
0 ignored issues
show
Bug introduced by
EncapsedNode of type string is incompatible with the type array expected by parameter $parameters of throw_unless(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

169
            /** @scrutinizer ignore-type */ "The output path does not exist [{$this->outputPath}]"
Loading history...
170
        );
171
    }
172
}
173