diff --git a/CHANGELOG-v3.md b/CHANGELOG-v3.md index 8c16f51b588..ba6238c3ec1 100644 --- a/CHANGELOG-v3.md +++ b/CHANGELOG-v3.md @@ -14,6 +14,7 @@ - Fixed a bug where user email changes were going through email verification even if someone with permission to administrate users was making the change. ([#5088](https://github.com/craftcms/cms/issues/5088)) - Fixed a bug where it wasn’t possible to eager-load Matrix blocks that belong to a draft or revision. ([#5031](https://github.com/craftcms/cms/issues/5031)) - Fixed a bug where the `setup` command would think that Craft was installed when it wasn’t. ([#5093](https://github.com/craftcms/cms/issues/5093)) +- Fixed an error that could occur when syncing the project config, that could occur if a Matrix block had been changed to something else. ([#4015](https://github.com/craftcms/cms/issues/4015)) ## 3.3.9 - 2019-10-10 diff --git a/src/services/Matrix.php b/src/services/Matrix.php index f26d50d4da4..691cd4fea58 100644 --- a/src/services/Matrix.php +++ b/src/services/Matrix.php @@ -360,48 +360,53 @@ public function handleChangedBlockType(ConfigEvent $event) $contentService->fieldColumnPrefix = 'field_' . $blockTypeRecord->handle . '_'; /** @var MatrixField $matrixField */ $matrixField = $fieldsService->getFieldById($blockTypeRecord->fieldId); - $contentService->contentTable = $matrixField->contentTable; - $fieldsService->oldFieldColumnPrefix = 'field_' . ($blockTypeRecord->getOldAttribute('handle') ?? $data['handle']) . '_'; - $oldFields = $previousData['fields'] ?? []; - $newFields = $data['fields'] ?? []; + // Ignore it, if the parent field is not a Matrix field. + if ($matrixField instanceof MatrixField) { + $contentService->contentTable = $matrixField->contentTable; + $fieldsService->oldFieldColumnPrefix = 'field_' . ($blockTypeRecord->getOldAttribute('handle') ?? $data['handle']) . '_'; + + $oldFields = $previousData['fields'] ?? []; + $newFields = $data['fields'] ?? []; - // Remove fields that this block type no longer has - foreach ($oldFields as $fieldUid => $fieldData) { - if (!array_key_exists($fieldUid, $newFields)) { - $fieldsService->applyFieldDelete($fieldUid); + // Remove fields that this block type no longer has + foreach ($oldFields as $fieldUid => $fieldData) { + if (!array_key_exists($fieldUid, $newFields)) { + $fieldsService->applyFieldDelete($fieldUid); + } } - } - // (Re)save all the fields that now exist for this block. - foreach ($newFields as $fieldUid => $fieldData) { - $fieldsService->applyFieldSave($fieldUid, $fieldData, 'matrixBlockType:' . $blockTypeUid); - } + // (Re)save all the fields that now exist for this block. + foreach ($newFields as $fieldUid => $fieldData) { + $fieldsService->applyFieldSave($fieldUid, $fieldData, 'matrixBlockType:' . $blockTypeUid); + } - // Refresh the schema cache - Craft::$app->getDb()->getSchema()->refresh(); + // Refresh the schema cache + Craft::$app->getDb()->getSchema()->refresh(); + + $contentService->fieldContext = $originalFieldContext; + $contentService->fieldColumnPrefix = $originalFieldColumnPrefix; + $contentService->contentTable = $originalContentTable; + $fieldsService->oldFieldColumnPrefix = $originalOldFieldColumnPrefix; + + if (!empty($data['fieldLayouts'])) { + // Save the field layout + $layout = FieldLayout::createFromConfig(reset($data['fieldLayouts'])); + $layout->id = $blockTypeRecord->fieldLayoutId; + $layout->type = MatrixBlock::class; + $layout->uid = key($data['fieldLayouts']); + $fieldsService->saveLayout($layout); + $blockTypeRecord->fieldLayoutId = $layout->id; + } else if ($blockTypeRecord->fieldLayoutId) { + // Delete the field layout + $fieldsService->deleteLayoutById($blockTypeRecord->fieldLayoutId); + $blockTypeRecord->fieldLayoutId = null; + } - $contentService->fieldContext = $originalFieldContext; - $contentService->fieldColumnPrefix = $originalFieldColumnPrefix; - $contentService->contentTable = $originalContentTable; - $fieldsService->oldFieldColumnPrefix = $originalOldFieldColumnPrefix; - - if (!empty($data['fieldLayouts'])) { - // Save the field layout - $layout = FieldLayout::createFromConfig(reset($data['fieldLayouts'])); - $layout->id = $blockTypeRecord->fieldLayoutId; - $layout->type = MatrixBlock::class; - $layout->uid = key($data['fieldLayouts']); - $fieldsService->saveLayout($layout); - $blockTypeRecord->fieldLayoutId = $layout->id; - } else if ($blockTypeRecord->fieldLayoutId) { - // Delete the field layout - $fieldsService->deleteLayoutById($blockTypeRecord->fieldLayoutId); - $blockTypeRecord->fieldLayoutId = null; + // Save it + $blockTypeRecord->save(false); } - // Save it - $blockTypeRecord->save(false); $transaction->commit(); } catch (\Throwable $e) { $transaction->rollBack();