These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | declare(strict_types=1); |
||
4 | |||
5 | namespace Shapin\Datagen\Bridge\Symfony\Console\Helper; |
||
6 | |||
7 | use Doctrine\DBAL\Schema\Column; |
||
8 | use Doctrine\DBAL\Schema\ColumnDiff; |
||
9 | use Doctrine\DBAL\Schema\SchemaDiff; |
||
10 | use Doctrine\DBAL\Schema\TableDiff; |
||
11 | use Doctrine\DBAL\Types\Type; |
||
12 | use Symfony\Component\Console\Output\OutputInterface; |
||
13 | |||
14 | class DoctrineSchemaDiffHelper |
||
15 | { |
||
16 | private $output; |
||
17 | private $diff; |
||
18 | |||
19 | 1 | public function __construct(OutputInterface $output, SchemaDiff $diff) |
|
20 | { |
||
21 | 1 | $this->output = $output; |
|
22 | 1 | $this->diff = $diff; |
|
23 | 1 | } |
|
24 | |||
25 | 1 | public function render(): void |
|
26 | { |
||
27 | 1 | $this->renderRemovedTables(); |
|
28 | 1 | $this->output->writeln(''); |
|
29 | 1 | $this->renderNewTables(); |
|
30 | 1 | $this->output->writeln(''); |
|
31 | 1 | $this->renderChangedTables(); |
|
32 | 1 | } |
|
33 | |||
34 | 1 | View Code Duplication | protected function renderRemovedTables(): void |
35 | { |
||
36 | 1 | if (0 === count($this->diff->removedTables)) { |
|
37 | return; |
||
38 | } |
||
39 | |||
40 | 1 | $this->title('Removed tables:'); |
|
41 | $this->listing(array_map(function ($table) { return $table->getName(); }, $this->diff->removedTables)); |
||
42 | 1 | } |
|
43 | |||
44 | 1 | View Code Duplication | protected function renderNewTables(): void |
45 | { |
||
46 | 1 | if (0 === count($this->diff->newTables)) { |
|
47 | return; |
||
48 | } |
||
49 | |||
50 | 1 | $this->title('New tables:'); |
|
51 | $this->listing(array_map(function ($table) { return $table->getName(); }, $this->diff->newTables)); |
||
52 | 1 | } |
|
53 | |||
54 | 1 | protected function renderChangedTables(): void |
|
55 | { |
||
56 | 1 | if (0 === count($this->diff->changedTables)) { |
|
57 | return; |
||
58 | } |
||
59 | |||
60 | 1 | foreach ($this->diff->changedTables as $table) { |
|
61 | 1 | $this->renderChangedTable($table); |
|
62 | } |
||
63 | 1 | } |
|
64 | |||
65 | 1 | protected function renderChangedTable(TableDiff $tableDiff): void |
|
66 | { |
||
67 | 1 | $addedColumns = $tableDiff->addedColumns; |
|
68 | 1 | $removedColumns = $tableDiff->removedColumns; |
|
69 | 1 | $changedColumns = $this->filterChangedColumns($tableDiff->changedColumns); |
|
70 | |||
71 | 1 | if (0 === count($addedColumns + $removedColumns + $changedColumns)) { |
|
72 | return; |
||
73 | } |
||
74 | |||
75 | 1 | $this->title("Table \"{$tableDiff->name}\" have been changed:"); |
|
76 | |||
77 | 1 | foreach ($addedColumns as $column) { |
|
78 | 1 | $this->renderAddedColumn($column); |
|
79 | } |
||
80 | 1 | foreach ($removedColumns as $column) { |
|
81 | 1 | $this->renderRemovedColumn($column); |
|
82 | } |
||
83 | |||
84 | 1 | foreach ($changedColumns as $column) { |
|
85 | 1 | $this->renderChangedColumn($column); |
|
86 | } |
||
87 | 1 | } |
|
88 | |||
89 | 1 | protected function renderAddedColumn(Column $column): void |
|
90 | { |
||
91 | 1 | $this->output->writeln('<fg=green> + '.$this->formatColumn($column).'</>'); |
|
92 | 1 | } |
|
93 | |||
94 | 1 | protected function renderRemovedColumn(Column $column): void |
|
95 | { |
||
96 | 1 | $this->output->writeln('<fg=red> - '.$this->formatColumn($column).'</>'); |
|
97 | 1 | } |
|
98 | |||
99 | 1 | protected function renderChangedColumn(ColumnDiff $columnDiff): void |
|
100 | { |
||
101 | 1 | $this->renderRemovedColumn($columnDiff->fromColumn); |
|
0 ignored issues
–
show
|
|||
102 | 1 | $this->renderAddedColumn($columnDiff->column); |
|
103 | 1 | } |
|
104 | |||
105 | 1 | protected function formatColumn(Column $column): string |
|
106 | { |
||
107 | 1 | $formattedColumn = $column->getName().', '.$column->getType()->getName(); |
|
108 | |||
109 | 1 | $options = $this->filterOptions($column); |
|
110 | |||
111 | 1 | if (0 < count($options)) { |
|
112 | 1 | $formattedOptions = []; |
|
113 | 1 | foreach ($options as $key => $value) { |
|
114 | 1 | $formattedValue = is_bool($value) ? $value ? 'true' : 'false' : $value; |
|
115 | 1 | $formattedOptions[] = "$key => $formattedValue"; |
|
116 | } |
||
117 | |||
118 | 1 | $formattedColumn .= ', ['.implode(', ', $formattedOptions).']'; |
|
119 | } |
||
120 | |||
121 | 1 | return $formattedColumn; |
|
122 | } |
||
123 | |||
124 | 1 | public function filterChangedColumns(array $changedColumns): array |
|
125 | { |
||
126 | 1 | $filteredChangeColumns = []; |
|
127 | 1 | foreach ($changedColumns as $columnDiff) { |
|
128 | 1 | if (['type'] === $columnDiff->changedProperties) { |
|
129 | // Sometimes it looks like type have been changed but it's not the case |
||
130 | if ($columnDiff->fromColumn->getType()->getName() === $columnDiff->column->getType()->getName()) { |
||
131 | continue; |
||
132 | } |
||
133 | } |
||
134 | |||
135 | 1 | $filteredChangeColumns[] = $columnDiff; |
|
136 | } |
||
137 | |||
138 | 1 | return $filteredChangeColumns; |
|
139 | } |
||
140 | |||
141 | 1 | protected function filterOptions(Column $column): array |
|
142 | { |
||
143 | 1 | $options = $column->toArray(); |
|
144 | 1 | unset($options['name'], $options['type']); |
|
145 | |||
146 | 1 | $referenceColumn = new Column('tmp', Type::getType($column->getType()->getName())); |
|
147 | |||
148 | $options = array_filter($options, function ($value, $key) use (&$referenceColumn) { |
||
149 | 1 | $method = 'get'.ucfirst($key); |
|
150 | // Keep unknown keys |
||
151 | 1 | if (!method_exists($referenceColumn, $method)) { |
|
152 | return true; |
||
153 | } |
||
154 | |||
155 | 1 | return $value !== $referenceColumn->$method(); // Ignore default values |
|
156 | 1 | }, ARRAY_FILTER_USE_BOTH); |
|
157 | |||
158 | 1 | return $options; |
|
159 | } |
||
160 | |||
161 | 1 | protected function title(string $title): void |
|
162 | { |
||
163 | 1 | $this->output->writeln("<comment>$title</comment>"); |
|
164 | 1 | } |
|
165 | |||
166 | 1 | protected function listing(array $elements): void |
|
167 | { |
||
168 | $elements = array_map(function ($element) { |
||
169 | 1 | return sprintf(' * %s', $element); |
|
170 | 1 | }, $elements); |
|
171 | |||
172 | 1 | $this->output->writeln($elements); |
|
173 | 1 | } |
|
174 | } |
||
175 |
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: