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>')); |
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>')); |
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); |
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 |
|
|
|
|
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
|
|
|
|
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.