BaseValidatorCommand   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 149
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
dl 0
loc 149
ccs 54
cts 54
cp 1
rs 10
c 0
b 0
f 0
wmc 12

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 1
A compileRowsFromSource() 0 8 1
A setSource() 0 7 3
A getSourceFromFile() 0 11 1
A buildRowFromValidator() 0 10 2
A validateOutputPath() 0 10 2
A handle() 0 11 1
A buildCsvFromRows() 0 5 1
1
<?php
2
3
namespace App\Commands;
4
5
use Carbon\Carbon;
6
use App\PhoneNumberValidator;
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
abstract class BaseValidatorCommand extends Command
13
{
14
    /**
15
     * @var mixed
16
     */
17
    protected $source;
18
19
    /**
20
     * Make a validator for a given number.
21
     *
22
     * @param  mixed $number
23
     * @return App\PhoneNumberValidator
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...
24
     */
25
    abstract public function makeValidatorForNumer($number): PhoneNumberValidator;
26
27
    /**
28
     * Is the number valid?
29
     *
30
     * @param  App\PhoneNumberValidator $validator
31
     * @return bool
32
     */
33
    abstract public function isNumberValid(PhoneNumberValidator $validator): bool;
34
35
    /**
36
     * Create a new command instance.
37
     *
38
     * @return void
39
     */
40 21
    public function __construct()
41
    {
42 21
        parent::__construct();
43
44 21
        $date = Carbon::now()->format('Ymd_his');
45 21
        $rand = mb_strtolower(str_random(6));
46
47 21
        $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...
48 21
        $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...
49 21
    }
50
51
    /**
52
     * Execute the console command.
53
     *
54
     * @return mixed
55
     */
56 5
    public function handle(): void
57
    {
58 5
        $this->setSource();
59 5
        $this->validateOutputPath();
60
61 5
        $this->buildCsvFromRows(
62 5
            $this->compileRowsFromSource($this->source)
63
        );
64
65 5
        $this->info('Total: '.count($this->source));
66 5
        $this->info('Filename: '.$this->fileName);
67 5
    }
68
69
    /**
70
     * Build a CSV from the rows.
71
     *
72
     * @param  Collection $rows
73
     * @return void
74
     */
75 5
    protected function buildCsvFromRows(Collection $rows)
76
    {
77 5
        File::put(
78 5
            $this->outputPath.'/'.$this->fileName,
79 5
            implode("\n", $rows->toArray())
80
        );
81 5
    }
82
83
    /**
84
     * Process a list of numbers.
85
     *
86
     * @param array $source
87
     * @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...
88
     */
89 5
    protected function compileRowsFromSource(array $source): Collection
90
    {
91 5
        return collect($source)
92 5
            ->map([$this, 'makeValidatorForNumer'])
93 5
            ->map([$this, 'buildRowFromValidator'])
94 5
            ->prepend(['phone number', 'carrier', 'status'])
95 5
            ->map(function ($row) {
96 5
                return implode(',', $row);
97 5
            });
98
    }
99
100
    /**
101
     * Build a row.
102
     *
103
     * @param  App\PhoneNumberValidator $validator
104
     * @return array
105
     */
106 5
    public function buildRowFromValidator(PhoneNumberValidator $validator): array
107
    {
108 5
        $row = [$validator->getNumber(), '', 'not valid'];
109
110 5
        if ($this->isNumberValid($validator)) {
111 5
            $row[1] = $validator->getCarrierName();
112 5
            $row[2] = 'valid';
113
        }
114
115 5
        return $row;
116
    }
117
118
    /**
119
     * Set the source.
120
     */
121 5
    protected function setSource(): void
122
    {
123 5
        $this->source = $this->option('file')
124 3
            ? $this->getSourceFromFile($this->argument('source'))
125 2
            : array_wrap($this->argument('source'));
126
127 5
        $this->info('Source valid: '.($this->option('file') ? 'File' : 'List'));
128 5
    }
129
130
    /**
131
     * Return the contents of the source file.
132
     *
133
     * @return array
134
     */
135 3
    protected function getSourceFromFile($file): array
136
    {
137 3
        $file = head(array_wrap($file));
138
139 3
        throw_unless(
140 3
            File::exists($file),
141 3
            RuntimeException::class,
142 3
            "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

142
            /** @scrutinizer ignore-type */ "Source does not exist [{$file}]"
Loading history...
143
        );
144
145 3
        return array_wrap(explode("\n", File::get($file)));
146
    }
147
148
    /**
149
     * Set the output path.
150
     */
151 5
    protected function validateOutputPath(): void
152
    {
153 5
        if ($this->option('output')) {
154 1
            $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...
155
        }
156
157 5
        throw_unless(
158 5
            is_dir($this->outputPath),
0 ignored issues
show
Bug introduced by
It seems like $this->outputPath can also be of type array; however, parameter $filename of is_dir() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

158
            is_dir(/** @scrutinizer ignore-type */ $this->outputPath),
Loading history...
159 5
            RuntimeException::class,
160 5
            "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

160
            /** @scrutinizer ignore-type */ "The output path does not exist [{$this->outputPath}]"
Loading history...
161
        );
162 5
    }
163
}
164