Skip to content

Commit 520b769

Browse files
committed
Fix content tables updating (and potentially removing data) when fields are missing in Craft
1 parent 5d3f472 commit 520b769

File tree

2 files changed

+54
-12
lines changed

2 files changed

+54
-12
lines changed

src/controllers/PluginController.php

+21-3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use craft\db\Query;
1111
use craft\db\Table;
1212
use craft\fields\MatrixField;
13+
use craft\fields\MissingField;
1314
use craft\helpers\Db;
1415
use craft\helpers\Json;
1516
use craft\helpers\MigrationHelper;
@@ -175,7 +176,9 @@ public function actionCheckContentTables()
175176
foreach ($superTableBlockTypes as $superTableBlockType) {
176177
$correctFieldColumns = [];
177178
$dbFieldColumns = [];
179+
$missingFields = false;
178180

181+
$superTableField = $fieldsService->getFieldById($superTableBlockType['fieldId']);
179182
$fieldLayout = $fieldsService->getLayoutById($superTableBlockType['fieldLayoutId']);
180183

181184
// Find what the columns should be according to the block type fields
@@ -184,13 +187,24 @@ public function actionCheckContentTables()
184187
if ($field::hasContentColumn()) {
185188
$correctFieldColumns[] = 'field_' . $field->handle;
186189
}
190+
191+
if (get_class($field) == MissingField::class) {
192+
$missingFields = true;
193+
echo " > ERROR: Unable to update {$superTableField->contentTable} as it contains missing fields. Please fix your missing fields first ...\n";
194+
break;
195+
}
187196
}
188197
}
189198

190-
$field = $fieldsService->getFieldById($superTableBlockType['fieldId']);
199+
// If there are any missing fields, we have to quit right now, otherwise we'll mess up
200+
// the content table, as we just don't know enough about the content table structure
201+
// to reliably update it properly.
202+
if ($missingFields) {
203+
continue;
204+
}
191205

192-
if ($field) {
193-
$contentTable = $field->contentTable;
206+
if ($superTableField) {
207+
$contentTable = $superTableField->contentTable;
194208

195209
if ($contentTable) {
196210
$columns = Craft::$app->getDb()->getTableSchema($contentTable)->columns;
@@ -201,6 +215,10 @@ public function actionCheckContentTables()
201215
}
202216
}
203217

218+
// Sort items the same - just in case they're in a slightly different order, but all there
219+
sort($correctFieldColumns);
220+
sort($dbFieldColumns);
221+
204222
if ($correctFieldColumns != $dbFieldColumns) {
205223
$errors = true;
206224
echo " > ERROR: {$contentTable} has missing field columns ...\n";

src/migrations/m190120_000000_fix_supertablecontent_tables.php

+33-9
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use craft\db\Query;
1010
use craft\db\Table;
1111
use craft\fields\MatrixField;
12+
use craft\fields\MissingField;
1213
use craft\helpers\Db;
1314
use craft\helpers\Json;
1415
use craft\helpers\MigrationHelper;
@@ -62,8 +63,9 @@ public function safeUp()
6263

6364
if ($contentTable) {
6465
if (!$this->db->tableExists($contentTable)) {
66+
$this->_createContentTable($settings, $field);
6567
// Re-save field
66-
$superTableService->saveSettings($fieldsService->getFieldById($field['id']));
68+
// $superTableService->saveSettings($fieldsService->getFieldById($field['id']));
6769
}
6870
} else {
6971
$this->_createContentTable($settings, $field);
@@ -186,7 +188,9 @@ public function safeUp()
186188
foreach ($superTableBlockTypes as $superTableBlockType) {
187189
$correctFieldColumns = [];
188190
$dbFieldColumns = [];
191+
$missingFields = false;
189192

193+
$superTableField = $fieldsService->getFieldById($superTableBlockType['fieldId']);
190194
$fieldLayout = $fieldsService->getLayoutById($superTableBlockType['fieldLayoutId']);
191195

192196
// Find what the columns should be according to the block type fields
@@ -195,12 +199,23 @@ public function safeUp()
195199
if ($field::hasContentColumn()) {
196200
$correctFieldColumns[] = 'field_' . $field->handle;
197201
}
202+
203+
if (get_class($field) == MissingField::class) {
204+
$missingFields = true;
205+
echo " > Unable to update {$superTableField->contentTable} as it contains missing fields. Please fix your missing fields first ...\n";
206+
break;
207+
}
198208
}
199209
}
200210

201-
$superTableField = $fieldsService->getFieldById($superTableBlockType['fieldId']);
211+
// If there are any missing fields, we have to quit right now, otherwise we'll mess up
212+
// the content table, as we just don't know enough about the content table structure
213+
// to reliably update it properly.
214+
if ($missingFields) {
215+
continue;
216+
}
202217

203-
if ($superTableField && get_class($superTableField) === SuperTableField::class) {
218+
if ($superTableField) {
204219
$contentTable = $superTableField->contentTable;
205220

206221
if ($contentTable) {
@@ -212,6 +227,10 @@ public function safeUp()
212227
}
213228
}
214229

230+
// Sort items the same - just in case they're in a slightly different order, but all there
231+
sort($correctFieldColumns);
232+
sort($dbFieldColumns);
233+
215234
if ($correctFieldColumns != $dbFieldColumns) {
216235
$fieldsService->saveField($superTableField);
217236

@@ -277,15 +296,20 @@ private function _createContentTable($settings, $field)
277296
$settings['contentTable'] = $contentTable;
278297
$this->update(Table::FIELDS, ['settings' => Json::encode($settings)], ['id' => $field['id']]);
279298

280-
// Also update our local copy of the field so we can save it
281-
$newField->contentTable = $contentTable;
299+
// Create the actual content table
300+
if (!$this->db->tableExists($contentTable)) {
301+
$migration = new CreateSuperTableContentTable([
302+
'tableName' => $contentTable,
303+
]);
282304

283-
echo " > Local field table name {$newField->contentTable} ...\n";
305+
$migration->up();
284306

285-
// Re-save field - for good measure
286-
$superTableService->saveSettings($newField);
307+
echo " > Created table {$contentTable} ...\n\n";
308+
} else {
309+
echo " > Content table {$contentTable} already exists, skipping ...\n\n";
287310

288-
echo " > Updated Super Table field after content table creation ...\n\n";
311+
return;
312+
}
289313
}
290314

291315
private function _getContentTableName(SuperTableField $field): string

0 commit comments

Comments
 (0)