Skip to content

Commit 4f6c82a

Browse files
authored
Merge pull request #201 from Ibochkarev/fix/repair-order-model-fields-migration
fix(migrations): восстановление полей заказа/адреса при неполных seed-данных
2 parents db79290 + 630e181 commit 4f6c82a

1 file changed

Lines changed: 298 additions & 0 deletions

File tree

Lines changed: 298 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,298 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Phinx\Migration\AbstractMigration;
6+
7+
/**
8+
* Self-heal: re-seed msOrder / msOrderAddress model fields and sections when the initial
9+
* seed migrations did not run fully or the schema was partially emptied (manager shows ms3_model_fields_empty).
10+
*/
11+
final class RepairOrderModelFieldsIfMissing extends AbstractMigration
12+
{
13+
private string $prefix = '';
14+
15+
public function up(): void
16+
{
17+
if (!$this->hasTable('ms3_model_fields') || !$this->hasTable('ms3_model_field_sections')) {
18+
return;
19+
}
20+
21+
$this->prefix = (string) ($this->adapter->getOption('table_prefix') ?? '');
22+
23+
$needOrder = $this->needsOrderRepair();
24+
$needAddress = $this->needsAddressRepair();
25+
26+
if (!$needOrder && !$needAddress) {
27+
return;
28+
}
29+
30+
if ($needOrder) {
31+
$this->insertOrderSectionsIfMissing();
32+
$this->insertOrderFieldsIfMissing();
33+
$this->updateOrderFieldSections();
34+
}
35+
36+
if ($needAddress) {
37+
$this->insertAddressSectionsIfMissing();
38+
$this->insertAddressFieldsIfMissing();
39+
$this->updateAddressFieldSections();
40+
}
41+
}
42+
43+
public function down(): void
44+
{
45+
// Intentionally empty: repair is data correction; rolling back would remove restored defaults.
46+
}
47+
48+
private function needsOrderRepair(): bool
49+
{
50+
foreach ($this->orderSeedFieldNames() as $name) {
51+
if (!$this->fieldExists('msOrder', $name)) {
52+
return true;
53+
}
54+
}
55+
56+
return false;
57+
}
58+
59+
private function needsAddressRepair(): bool
60+
{
61+
foreach ($this->addressSeedFieldNames() as $name) {
62+
if (!$this->fieldExists('msOrderAddress', $name)) {
63+
return true;
64+
}
65+
}
66+
67+
return false;
68+
}
69+
70+
/** @return list<string> */
71+
private function orderSeedFieldNames(): array
72+
{
73+
return ['status_id', 'delivery_id', 'payment_id', 'customer_id', 'order_comment'];
74+
}
75+
76+
/** @return list<string> */
77+
private function addressSeedFieldNames(): array
78+
{
79+
return [
80+
'first_name', 'last_name', 'phone', 'email', 'country', 'index', 'region', 'city',
81+
'metro', 'street', 'building', 'entrance', 'floor', 'room', 'comment', 'text_address',
82+
];
83+
}
84+
85+
private function fieldExists(string $model, string $name): bool
86+
{
87+
$rows = $this->fetchAll(
88+
"SELECT id FROM {$this->prefix}ms3_model_fields WHERE model = '{$model}' AND name = '{$name}' LIMIT 1"
89+
);
90+
91+
return $rows !== [];
92+
}
93+
94+
private function insertOrderSectionsIfMissing(): void
95+
{
96+
$rows = [
97+
[
98+
'model' => 'msOrder',
99+
'section_key' => 'main',
100+
'label' => null,
101+
'lexicon_key' => 'ms3_section_order_main',
102+
'hidden' => false,
103+
'sort_order' => 10,
104+
'is_default' => true,
105+
],
106+
[
107+
'model' => 'msOrder',
108+
'section_key' => 'other',
109+
'label' => null,
110+
'lexicon_key' => 'ms3_section_order_other',
111+
'hidden' => false,
112+
'sort_order' => 100,
113+
'is_default' => true,
114+
],
115+
];
116+
foreach ($rows as $row) {
117+
$key = $row['section_key'];
118+
$exists = $this->fetchAll(
119+
"SELECT id FROM {$this->prefix}ms3_model_field_sections WHERE model = 'msOrder' AND section_key = '{$key}' LIMIT 1"
120+
);
121+
if ($exists !== []) {
122+
continue;
123+
}
124+
$this->table('ms3_model_field_sections')->insert([$row])->saveData();
125+
}
126+
}
127+
128+
private function insertAddressSectionsIfMissing(): void
129+
{
130+
$rows = [
131+
[
132+
'model' => 'msOrderAddress',
133+
'section_key' => 'contact',
134+
'label' => null,
135+
'lexicon_key' => 'ms3_section_address_contact',
136+
'hidden' => false,
137+
'sort_order' => 10,
138+
'is_default' => true,
139+
],
140+
[
141+
'model' => 'msOrderAddress',
142+
'section_key' => 'location',
143+
'label' => null,
144+
'lexicon_key' => 'ms3_section_address_location',
145+
'hidden' => false,
146+
'sort_order' => 20,
147+
'is_default' => true,
148+
],
149+
[
150+
'model' => 'msOrderAddress',
151+
'section_key' => 'building',
152+
'label' => null,
153+
'lexicon_key' => 'ms3_section_address_building',
154+
'hidden' => false,
155+
'sort_order' => 30,
156+
'is_default' => true,
157+
],
158+
[
159+
'model' => 'msOrderAddress',
160+
'section_key' => 'other',
161+
'label' => null,
162+
'lexicon_key' => 'ms3_section_address_other',
163+
'hidden' => false,
164+
'sort_order' => 100,
165+
'is_default' => true,
166+
],
167+
];
168+
foreach ($rows as $row) {
169+
$key = $row['section_key'];
170+
$exists = $this->fetchAll(
171+
"SELECT id FROM {$this->prefix}ms3_model_field_sections WHERE model = 'msOrderAddress' AND section_key = '{$key}' LIMIT 1"
172+
);
173+
if ($exists !== []) {
174+
continue;
175+
}
176+
$this->table('ms3_model_field_sections')->insert([$row])->saveData();
177+
}
178+
}
179+
180+
private function insertOrderFieldsIfMissing(): void
181+
{
182+
$orderFields = [
183+
['model' => 'msOrder', 'name' => 'status_id', 'label' => 'ms3_order_status', 'xtype' => 'combo', 'visible' => true, 'required' => true, 'sort_order' => 30],
184+
['model' => 'msOrder', 'name' => 'delivery_id', 'label' => 'ms3_order_delivery', 'xtype' => 'combo', 'visible' => true, 'required' => false, 'sort_order' => 40],
185+
['model' => 'msOrder', 'name' => 'payment_id', 'label' => 'ms3_order_payment', 'xtype' => 'combo', 'visible' => true, 'required' => false, 'sort_order' => 50],
186+
['model' => 'msOrder', 'name' => 'customer_id', 'label' => 'ms3_order_customer', 'xtype' => 'combo', 'visible' => true, 'required' => false, 'sort_order' => 60],
187+
['model' => 'msOrder', 'name' => 'order_comment', 'label' => 'ms3_order_comment', 'xtype' => 'textarea', 'visible' => true, 'required' => false, 'sort_order' => 100],
188+
];
189+
foreach ($orderFields as $row) {
190+
$n = $row['name'];
191+
$exists = $this->fetchAll(
192+
"SELECT id FROM {$this->prefix}ms3_model_fields WHERE model = 'msOrder' AND name = '{$n}' LIMIT 1"
193+
);
194+
if ($exists !== []) {
195+
continue;
196+
}
197+
$this->table('ms3_model_fields')->insert([$row])->saveData();
198+
}
199+
}
200+
201+
private function insertAddressFieldsIfMissing(): void
202+
{
203+
$addressFields = [
204+
['model' => 'msOrderAddress', 'name' => 'first_name', 'label' => 'ms3_address_first_name', 'xtype' => 'textfield', 'visible' => true, 'required' => false, 'sort_order' => 10],
205+
['model' => 'msOrderAddress', 'name' => 'last_name', 'label' => 'ms3_address_last_name', 'xtype' => 'textfield', 'visible' => true, 'required' => false, 'sort_order' => 20],
206+
['model' => 'msOrderAddress', 'name' => 'phone', 'label' => 'ms3_address_phone', 'xtype' => 'textfield', 'visible' => true, 'required' => false, 'sort_order' => 30],
207+
['model' => 'msOrderAddress', 'name' => 'email', 'label' => 'ms3_address_email', 'xtype' => 'textfield', 'visible' => true, 'required' => false, 'sort_order' => 40],
208+
['model' => 'msOrderAddress', 'name' => 'country', 'label' => 'ms3_address_country', 'xtype' => 'textfield', 'visible' => true, 'required' => false, 'sort_order' => 50],
209+
['model' => 'msOrderAddress', 'name' => 'index', 'label' => 'ms3_address_index', 'xtype' => 'textfield', 'visible' => true, 'required' => false, 'sort_order' => 60],
210+
['model' => 'msOrderAddress', 'name' => 'region', 'label' => 'ms3_address_region', 'xtype' => 'textfield', 'visible' => true, 'required' => false, 'sort_order' => 70],
211+
['model' => 'msOrderAddress', 'name' => 'city', 'label' => 'ms3_address_city', 'xtype' => 'textfield', 'visible' => true, 'required' => false, 'sort_order' => 80],
212+
['model' => 'msOrderAddress', 'name' => 'metro', 'label' => 'ms3_address_metro', 'xtype' => 'textfield', 'visible' => false, 'required' => false, 'sort_order' => 90],
213+
['model' => 'msOrderAddress', 'name' => 'street', 'label' => 'ms3_address_street', 'xtype' => 'textfield', 'visible' => true, 'required' => false, 'sort_order' => 100],
214+
['model' => 'msOrderAddress', 'name' => 'building', 'label' => 'ms3_address_building', 'xtype' => 'textfield', 'visible' => true, 'required' => false, 'sort_order' => 110],
215+
['model' => 'msOrderAddress', 'name' => 'entrance', 'label' => 'ms3_address_entrance', 'xtype' => 'textfield', 'visible' => false, 'required' => false, 'sort_order' => 120],
216+
['model' => 'msOrderAddress', 'name' => 'floor', 'label' => 'ms3_address_floor', 'xtype' => 'textfield', 'visible' => false, 'required' => false, 'sort_order' => 130],
217+
['model' => 'msOrderAddress', 'name' => 'room', 'label' => 'ms3_address_room', 'xtype' => 'textfield', 'visible' => true, 'required' => false, 'sort_order' => 140],
218+
['model' => 'msOrderAddress', 'name' => 'comment', 'label' => 'ms3_address_comment', 'xtype' => 'textarea', 'visible' => true, 'required' => false, 'sort_order' => 150],
219+
['model' => 'msOrderAddress', 'name' => 'text_address', 'label' => 'ms3_address_text', 'xtype' => 'textarea', 'visible' => false, 'required' => false, 'sort_order' => 160],
220+
];
221+
foreach ($addressFields as $row) {
222+
$n = $row['name'];
223+
$exists = $this->fetchAll(
224+
"SELECT id FROM {$this->prefix}ms3_model_fields WHERE model = 'msOrderAddress' AND name = '{$n}' LIMIT 1"
225+
);
226+
if ($exists !== []) {
227+
continue;
228+
}
229+
$this->table('ms3_model_fields')->insert([$row])->saveData();
230+
}
231+
}
232+
233+
private function updateOrderFieldSections(): void
234+
{
235+
$sections = $this->fetchAll("SELECT id, section_key FROM {$this->prefix}ms3_model_field_sections WHERE model = 'msOrder'");
236+
$sectionMap = [];
237+
foreach ($sections as $section) {
238+
$sectionMap[$section['section_key']] = $section['id'];
239+
}
240+
241+
$fieldUpdates = [
242+
['name' => 'status_id', 'section' => 'main', 'width' => 6],
243+
['name' => 'delivery_id', 'section' => 'main', 'width' => 6],
244+
['name' => 'payment_id', 'section' => 'main', 'width' => 6],
245+
['name' => 'order_comment', 'section' => 'other', 'width' => 12],
246+
];
247+
248+
foreach ($fieldUpdates as $update) {
249+
$sectionId = $sectionMap[$update['section']] ?? null;
250+
if ($sectionId) {
251+
$n = $update['name'];
252+
$this->execute(
253+
"UPDATE {$this->prefix}ms3_model_fields SET section_id = {$sectionId}, width = {$update['width']} " .
254+
"WHERE model = 'msOrder' AND name = '{$n}' AND section_id IS NULL"
255+
);
256+
}
257+
}
258+
}
259+
260+
private function updateAddressFieldSections(): void
261+
{
262+
$sections = $this->fetchAll("SELECT id, section_key FROM {$this->prefix}ms3_model_field_sections WHERE model = 'msOrderAddress'");
263+
$sectionMap = [];
264+
foreach ($sections as $section) {
265+
$sectionMap[$section['section_key']] = $section['id'];
266+
}
267+
268+
$fieldUpdates = [
269+
['name' => 'first_name', 'section' => 'contact', 'width' => 6],
270+
['name' => 'last_name', 'section' => 'contact', 'width' => 6],
271+
['name' => 'phone', 'section' => 'contact', 'width' => 6],
272+
['name' => 'email', 'section' => 'contact', 'width' => 6],
273+
['name' => 'country', 'section' => 'location', 'width' => 4],
274+
['name' => 'index', 'section' => 'location', 'width' => 4],
275+
['name' => 'region', 'section' => 'location', 'width' => 4],
276+
['name' => 'city', 'section' => 'location', 'width' => 6],
277+
['name' => 'metro', 'section' => 'location', 'width' => 6],
278+
['name' => 'street', 'section' => 'location', 'width' => 12],
279+
['name' => 'building', 'section' => 'building', 'width' => 4],
280+
['name' => 'entrance', 'section' => 'building', 'width' => 2],
281+
['name' => 'floor', 'section' => 'building', 'width' => 2],
282+
['name' => 'room', 'section' => 'building', 'width' => 4],
283+
['name' => 'comment', 'section' => 'other', 'width' => 12],
284+
['name' => 'text_address', 'section' => 'other', 'width' => 12],
285+
];
286+
287+
foreach ($fieldUpdates as $update) {
288+
$sectionId = $sectionMap[$update['section']] ?? null;
289+
if ($sectionId) {
290+
$n = $update['name'];
291+
$this->execute(
292+
"UPDATE {$this->prefix}ms3_model_fields SET section_id = {$sectionId}, width = {$update['width']} " .
293+
"WHERE model = 'msOrderAddress' AND name = '{$n}' AND section_id IS NULL"
294+
);
295+
}
296+
}
297+
}
298+
}

0 commit comments

Comments
 (0)