SpreadsheetCommand::migrate()   A
last analyzed

Complexity

Conditions 2
Paths 3

Size

Total Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 22
ccs 15
cts 15
cp 1
rs 9.568
c 0
b 0
f 0
cc 2
nc 3
nop 0
crap 2
1
<?php
2
/**
3
 * @link https://github.com/vuongxuongminh/migrate-phone-number
4
 * @copyright Copyright (c) 2018 Vuong Xuong Minh
5
 * @license [New BSD License](http://www.opensource.org/licenses/bsd-license.php)
6
 */
7
8
namespace VXM\MPN;
9
10
use PhpOffice\PhpSpreadsheet\IOFactory;
11
use PhpOffice\PhpSpreadsheet\Spreadsheet;
12
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
13
14
use Symfony\Component\Console\Helper\ProgressBar;
15
use Symfony\Component\Console\Question\Question;
16
17
18
/**
19
 * Lớp SpreadsheetCommand hổ trợ chuyển đổi dữ liệu các cột trên Spreadsheet chứa số điện thoại 11 số sang 10 số.
20
 *
21
 * @author Vuong Minh <[email protected]>
22
 * @since 1.0
23
 */
24
class SpreadsheetCommand extends MigrateCommand
25
{
26
27
    /**
28
     * @var Spreadsheet Đối tượng spreadsheet chứa các cột trong các sheet cần chuyển đổi số điện thoại 11 số sang 10 số.
29
     */
30
    protected $spreadsheet;
31
32
    /**
33
     * @inheritdoc
34
     */
35
    protected static $defaultName = 'migrate:ss';
36
37
    /**
38
     * @inheritdoc
39
     */
40 3
    protected function configure(): void
41
    {
42 3
        parent::configure();
43
44 3
        $this->setDescription('Lệnh hổ trợ chuyển đổi dữ liệu các cột trên bảng Spreadsheet chứa số điện thoại 11 số sang 10 số.');
45 3
    }
46
47
    /**
48
     * @inheritdoc
49
     * @throws \PhpOffice\PhpSpreadsheet\Exception
50
     */
51 3
    protected function migrate(): void
52
    {
53 3
        $this->outputted->writeln('<info>Thông tin file spreadsheet</info>');
54
55
        /** @var \Symfony\Component\Console\Helper\QuestionHelper $question */
56 3
        $question = $this->getHelper('question');
57 3
        $file = $question->ask($this->inputted, $this->outputted, new Question('<info>Hãy nhập đường dẫn file csv, xls, xlsx (ví dụ: C:\folder\a.csv): </info>'));
0 ignored issues
show
Bug introduced by
It seems like $this->inputted can be null; however, ask() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
Bug introduced by
It seems like $this->outputted can be null; however, ask() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
58
59
        try {
60 3
            $reader = IOFactory::createReaderForFile($file);
61 2
            $spreadsheet = $this->spreadsheet = $reader->load($file);
62 1
        } catch (\Throwable $e) {
63 1
            $this->outputted->writeln('<error>Đường dẫn thư mục không hợp lệ hoặc file không đúng định dạng!</error>');
64 1
            return;
65
        }
66
67 2
        $this->outputted->writeln('<info>Handled spreadsheet</info>');
68 2
        $this->migrateSpreadsheet();
69 2
        $writerClass = str_replace('PhpOffice\PhpSpreadsheet\Reader', 'PhpOffice\PhpSpreadsheet\Writer', get_class($reader));
70 2
        (new $writerClass($spreadsheet))->save($file);
71 2
        $this->outputted->writeln('<info>Hoàn tất</info>');
72 2
    }
73
74
    /**
75
     * Phương thức hổ trợ migrate spreadsheet theo dữ liệu yêu cầu của end-user.
76
     *
77
     * @throws \PhpOffice\PhpSpreadsheet\Exception
78
     */
79 2
    protected function migrateSpreadsheet(): void
80
    {
81
        /** @var \Symfony\Component\Console\Helper\QuestionHelper $question */
82 2
        $question = $this->getHelper('question');
83 2
        $sheetColumns = $question->ask($this->inputted, $this->outputted, new Question('<info>Danh sách sheet và cột (ví dụ: 0:A, 0:B, 1:C ...): </info>'));
0 ignored issues
show
Bug introduced by
It seems like $this->inputted can be null; however, ask() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
Bug introduced by
It seems like $this->outputted can be null; however, ask() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
84
85 2
        foreach ($this->normalizeSheetColumns($sheetColumns) as $sheet => $columns) {
86 2
            $worksheet = $this->spreadsheet->getSheet($sheet);
87 2
            $this->migrateWorksheet($worksheet, $columns);
88
        }
89 2
    }
90
91
    /**
92
     * Phương thức hổ trợ migrate theo các cột trong worksheet chỉ định.
93
     *
94
     * @param Worksheet $worksheet Đối tượng worksheet chứa các cột.
95
     * @param array $columns Mảng các cốt chứa số điện thoại 11 số.
96
     * @throws \PhpOffice\PhpSpreadsheet\Exception
97
     */
98 2
    protected function migrateWorksheet(Worksheet $worksheet, array $columns): void
99
    {
100 2
        $this->outputted->writeln("<info>Thực thi chuyển đổi dữ liệu trên sheet: `{$worksheet->getTitle()}`...</info>");
101
102 2
        $migrated = false;
103 2
        $progressBar = new ProgressBar($this->outputted);
0 ignored issues
show
Bug introduced by
It seems like $this->outputted can be null; however, __construct() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
104 2
        $progressBar->setFormat('[%bar%] %percent:3s%% (%elapsed:6s%)');
105 2
        $progressBar->start();
106
107 2
        foreach ($columns as $column) {
108 2
            $highestRow = $worksheet->getHighestRow($column);
109 2
            $progressBar->setMaxSteps($progressBar->getMaxSteps() + $highestRow);
110
111 2
            for ($i = 1; $i <= $highestRow; $i++) {
112 1
                $migrated = true;
113 1
                $cell = $worksheet->getCell("$column$i", false);
114 1
                $phoneNumber = $this->convert($cell->getValue());
115 1
                $cell->setValue($phoneNumber);
116 1
                $progressBar->advance();
117
            }
118
        }
119
120 2
        if ($migrated) {
121 1
            $progressBar->finish();
122 1
            $this->outputted->writeln("\n<info>Hoàn tất chuyển đổi dữ liệu trên sheet: `{$worksheet->getTitle()}`</info>");
123
        } else {
124 1
            $this->outputted->writeln("<comment>Bỏ qua sheet: `{$worksheet->getTitle()}` vì sheet không có dữ liệu.</comment>");
125
        }
126 2
    }
127
128
    /**
129
     * Phương thức hổ trợ chuyển đổi cấu trúc bảng cột sang mảng PHP.
130
     *
131
     * @param string $sheetColumns Chuỗi sheet và cột do end-user nhập.
132
     * @return array Mảng gồm có các khóa là id các sheet và giá trị là mảng danh sách cột cần chuyển đổi số điện thoại.
133
     */
134 2 View Code Duplication
    protected function normalizeSheetColumns(string $sheetColumns): array
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
135
    {
136 2
        $result = [];
137 2
        $sheetColumns = array_map('trim', explode(',', $sheetColumns));
138
139 2
        foreach ($sheetColumns as $sheetColumn) {
140 2
            list($sheet, $column) = explode(':', $sheetColumn);
141 2
            $result[$sheet][] = $column;
142
        }
143
144 2
        return $result;
145
    }
146
147
}
148