Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[4.x]: Bug saving a matrix block #12422

Closed
bob-pixeldeluxe opened this issue Dec 6, 2022 · 6 comments
Closed

[4.x]: Bug saving a matrix block #12422

bob-pixeldeluxe opened this issue Dec 6, 2022 · 6 comments
Assignees

Comments

@bob-pixeldeluxe
Copy link

What happened?

Description

I was building a large matrix however it seemed to save fields to the database but not fully so they did not show in the actual matrix or while editing the field.

Steps to reproduce

  1. Create a matrix block with some fields in it without saving.
  2. Then ad a block beneath those with a very long title (This resulted in an error for me)
  3. After reopening the edit screen all fields are gone. However if i try to add them again i get the error the handle is already taken. Also I can see they do exist in the database.

Expected behavior

I expect the fields got half saved however this results in a "broken" matrix field.

Actual behavior

Saved "shadow" fields in my matrix.

Craft CMS version

4.3.1

PHP version

8.1

Operating system and version

No response

Database type and version

No response

Image driver and version

No response

Installed plugins and versions

@brianjhanson
Copy link
Contributor

Is any information in the storage/logs files that might point toward the culprit?

I’m having trouble replicating on my end, but it’s likely because I do not entirely understand how to reproduce. Are you seeing this error when creating a matrix field? Or when editing a matrix field for an entry?

@brianjhanson brianjhanson self-assigned this Dec 6, 2022
@bob-pixeldeluxe
Copy link
Author

bob-pixeldeluxe commented Dec 7, 2022

Sure ill post it. When i tried to recreate the error today it just gave me an correct error below the input field:

$_SESSION = [
    'bd62416aa8538ede709019a5e113eea5__flash' => []
    'bd62416aa8538ede709019a5e113eea5__auth_access' => [
        0 => 'seomaticPreviewAuthorizationKey10453'
        1 => 'previewElement:10453'
        2 => 'saveAssets:1'
        3 => 'seomaticPreviewAuthorizationKey10430'
        4 => 'previewElement:10430'
        5 => 'seomaticPreviewAuthorizationKey69270'
        6 => 'previewDraft:7925'
        7 => 'seomaticPreviewAuthorizationKey141'
        8 => 'previewElement:141'
    ]
    '1031b8c41dfff97a311a7ac99863bdc5__token' => '••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••'
    '1031b8c41dfff97a311a7ac99863bdc5__id' => 340
    '__authKey' => '••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••'
    '1031b8c41dfff97a311a7ac99863bdc5__expire' => 1670340622
    '__duration' => 3600
] {"userId":340,"sessionId":"6b4e49ed56ee9c60385690cbb279267f"} 
2022-12-06 14:30:23 [web.ERROR] [yii\db\Exception] PDOException: SQLSTATE[42000]: Syntax error or access violation: 1059 Identifier name 'field_combiTextAndImage_gutterExtraSpaceBetweenImageAndText_jnttwunq' is too long in /var/www/html/vendor/yiisoft/yii2/db/Command.php:1302
Stack trace:
#0 /var/www/html/vendor/yiisoft/yii2/db/Command.php(1302): PDOStatement->execute()
#1 /var/www/html/vendor/yiisoft/yii2/db/Command.php(1102): yii\db\Command->internalExecute('ALTER TABLE `ma...')
#2 /var/www/html/vendor/craftcms/cms/src/services/Fields.php(1775): yii\db\Command->execute()
#3 /var/www/html/vendor/craftcms/cms/src/services/Fields.php(1626): craft\services\Fields->updateColumn(Object(craft\db\Connection), Object(yii\db\Transaction), '{{%matrixconten...', NULL, 'field_combiText...', 'text')
#4 /var/www/html/vendor/craftcms/cms/src/services/Matrix.php(294): craft\services\Fields->applyFieldSave('2047586f-f5f4-4...', Array, 'matrixBlockType...')
#5 /var/www/html/vendor/craftcms/cms/src/base/ApplicationTrait.php(1678): craft\services\Matrix->handleChangedBlockType(Object(craft\events\ConfigEvent))
#6 /var/www/html/vendor/craftcms/cms/src/services/ProjectConfig.php(1125): craft\web\Application->craft\base\{closure}(Object(craft\events\ConfigEvent))
#7 [internal function]: craft\services\ProjectConfig->handleChangeEvent(Object(craft\events\ConfigEvent))
#8 /var/www/html/vendor/yiisoft/yii2/base/Component.php(633): call_user_func(Array, Object(craft\events\ConfigEvent))
#9 /var/www/html/vendor/craftcms/cms/src/models/ProjectConfigData.php(82): yii\base\Component->trigger('updateItem', Object(craft\events\ConfigEvent))
#10 /var/www/html/vendor/craftcms/cms/src/services/ProjectConfig.php(515): craft\models\ProjectConfigData->commitChanges(Array, Array, 'matrixBlockType...', true, 'Save matrix blo...', true)
#11 /var/www/html/vendor/craftcms/cms/src/services/ProjectConfig.php(475): craft\services\ProjectConfig->_setInternal('matrixBlockType...', Array, 'Save matrix blo...', true, false)
#12 /var/www/html/vendor/craftcms/cms/src/services/Matrix.php(222): craft\services\ProjectConfig->set('matrixBlockType...', Array, 'Save matrix blo...')
#13 /var/www/html/vendor/craftcms/cms/src/services/Matrix.php(565): craft\services\Matrix->saveBlockType(Object(craft\models\MatrixBlockType), false)
#14 /var/www/html/vendor/craftcms/cms/src/fields/Matrix.php(1016): craft\services\Matrix->saveSettings(Object(craft\fields\Matrix), false)
#15 /var/www/html/vendor/craftcms/cms/src/services/Fields.php(1695): craft\fields\Matrix->afterSave(false)
#16 /var/www/html/vendor/craftcms/cms/src/services/Fields.php(816): craft\services\Fields->applyFieldSave('7b3dfa99-e335-4...', Array, 'global')
#17 /var/www/html/vendor/craftcms/cms/src/controllers/FieldsController.php(341): craft\services\Fields->saveField(Object(craft\fields\Matrix))
#18 [internal function]: craft\controllers\FieldsController->actionSaveField()
#19 /var/www/html/vendor/yiisoft/yii2/base/InlineAction.php(57): call_user_func_array(Array, Array)
#20 /var/www/html/vendor/yiisoft/yii2/base/Controller.php(178): yii\base\InlineAction->runWithParams(Array)
#21 /var/www/html/vendor/yiisoft/yii2/base/Module.php(552): yii\base\Controller->runAction('save-field', Array)
#22 /var/www/html/vendor/craftcms/cms/src/web/Application.php(301): yii\base\Module->runAction('fields/save-fie...', Array)
#23 /var/www/html/vendor/craftcms/cms/src/web/Application.php(625): craft\web\Application->runAction('fields/save-fie...', Array)
#24 /var/www/html/vendor/craftcms/cms/src/web/Application.php(280): craft\web\Application->_processActionRequest(Object(craft\web\Request))
#25 /var/www/html/vendor/yiisoft/yii2/base/Application.php(384): craft\web\Application->handleRequest(Object(craft\web\Request))
#26 /var/www/html/public_html/index.php(12): yii\base\Application->run()
#27 {main}

Next yii\db\Exception: SQLSTATE[42000]: Syntax error or access violation: 1059 Identifier name 'field_combiTextAndImage_gutterExtraSpaceBetweenImageAndText_jnttwunq' is too long
The SQL being executed was: ALTER TABLE `matrixcontent_components` ADD `field_combiTextAndImage_gutterExtraSpaceBetweenImageAndText_jnttwunq` text in /var/www/html/vendor/yiisoft/yii2/db/Schema.php:676
Stack trace:
#0 /var/www/html/vendor/yiisoft/yii2/db/Command.php(1307): yii\db\Schema->convertException(Object(PDOException), 'ALTER TABLE `ma...')
#1 /var/www/html/vendor/yiisoft/yii2/db/Command.php(1102): yii\db\Command->internalExecute('ALTER TABLE `ma...')
#2 /var/www/html/vendor/craftcms/cms/src/services/Fields.php(1775): yii\db\Command->execute()
#3 /var/www/html/vendor/craftcms/cms/src/services/Fields.php(1626): craft\services\Fields->updateColumn(Object(craft\db\Connection), Object(yii\db\Transaction), '{{%matrixconten...', NULL, 'field_combiText...', 'text')
#4 /var/www/html/vendor/craftcms/cms/src/services/Matrix.php(294): craft\services\Fields->applyFieldSave('2047586f-f5f4-4...', Array, 'matrixBlockType...')
#5 /var/www/html/vendor/craftcms/cms/src/base/ApplicationTrait.php(1678): craft\services\Matrix->handleChangedBlockType(Object(craft\events\ConfigEvent))
#6 /var/www/html/vendor/craftcms/cms/src/services/ProjectConfig.php(1125): craft\web\Application->craft\base\{closure}(Object(craft\events\ConfigEvent))
#7 [internal function]: craft\services\ProjectConfig->handleChangeEvent(Object(craft\events\ConfigEvent))
#8 /var/www/html/vendor/yiisoft/yii2/base/Component.php(633): call_user_func(Array, Object(craft\events\ConfigEvent))
#9 /var/www/html/vendor/craftcms/cms/src/models/ProjectConfigData.php(82): yii\base\Component->trigger('updateItem', Object(craft\events\ConfigEvent))
#10 /var/www/html/vendor/craftcms/cms/src/services/ProjectConfig.php(515): craft\models\ProjectConfigData->commitChanges(Array, Array, 'matrixBlockType...', true, 'Save matrix blo...', true)
#11 /var/www/html/vendor/craftcms/cms/src/services/ProjectConfig.php(475): craft\services\ProjectConfig->_setInternal('matrixBlockType...', Array, 'Save matrix blo...', true, false)
#12 /var/www/html/vendor/craftcms/cms/src/services/Matrix.php(222): craft\services\ProjectConfig->set('matrixBlockType...', Array, 'Save matrix blo...')
#13 /var/www/html/vendor/craftcms/cms/src/services/Matrix.php(565): craft\services\Matrix->saveBlockType(Object(craft\models\MatrixBlockType), false)
#14 /var/www/html/vendor/craftcms/cms/src/fields/Matrix.php(1016): craft\services\Matrix->saveSettings(Object(craft\fields\Matrix), false)
#15 /var/www/html/vendor/craftcms/cms/src/services/Fields.php(1695): craft\fields\Matrix->afterSave(false)
#16 /var/www/html/vendor/craftcms/cms/src/services/Fields.php(816): craft\services\Fields->applyFieldSave('7b3dfa99-e335-4...', Array, 'global')
#17 /var/www/html/vendor/craftcms/cms/src/controllers/FieldsController.php(341): craft\services\Fields->saveField(Object(craft\fields\Matrix))
#18 [internal function]: craft\controllers\FieldsController->actionSaveField()
#19 /var/www/html/vendor/yiisoft/yii2/base/InlineAction.php(57): call_user_func_array(Array, Array)
#20 /var/www/html/vendor/yiisoft/yii2/base/Controller.php(178): yii\base\InlineAction->runWithParams(Array)
#21 /var/www/html/vendor/yiisoft/yii2/base/Module.php(552): yii\base\Controller->runAction('save-field', Array)
#22 /var/www/html/vendor/craftcms/cms/src/web/Application.php(301): yii\base\Module->runAction('fields/save-fie...', Array)
#23 /var/www/html/vendor/craftcms/cms/src/web/Application.php(625): craft\web\Application->runAction('fields/save-fie...', Array)
#24 /var/www/html/vendor/craftcms/cms/src/web/Application.php(280): craft\web\Application->_processActionRequest(Object(craft\web\Request))
#25 /var/www/html/vendor/yiisoft/yii2/base/Application.php(384): craft\web\Application->handleRequest(Object(craft\web\Request))
#26 /var/www/html/public_html/index.php(12): yii\base\Application->run()
#27 {main}
Additional Information:
Array
(
    [0] => 42000
    [1] => 1059
    [2] => Identifier name 'field_combiTextAndImage_gutterExtraSpaceBetweenImageAndText_jnttwunq' is too long
)
 {"memory":16688728,"exception":"[object] (yii\\db\\Exception(code: 42000): SQLSTATE[42000]: Syntax error or access violation: 1059 Identifier name 'field_combiTextAndImage_gutterExtraSpaceBetweenImageAndText_jnttwunq' is too long
The SQL being executed was: ALTER TABLE `matrixcontent_components` ADD `field_combiTextAndImage_gutterExtraSpaceBetweenImageAndText_jnttwunq` text at /var/www/html/vendor/yiisoft/yii2/db/Schema.php:676)
[previous exception] [object] (PDOException(code: 42000): SQLSTATE[42000]: Syntax error or access violation: 1059 Identifier name 'field_combiTextAndImage_gutterExtraSpaceBetweenImageAndText_jnttwunq' is too long at /var/www/html/vendor/yiisoft/yii2/db/Command.php:1302)"} 
2022-12-06 14:30:23 [web.INFO] [application] Request context:
$_GET = [
    'site' => 'en'
]

@brianjhanson
Copy link
Contributor

Yeah, it looks like the name of your fields just got too long.

2022-12-06 14:30:23 [web.ERROR] [yii\db\Exception] PDOException: SQLSTATE[42000]: Syntax error or access violation: 1059 Identifier name 'field_combiTextAndImage_gutterExtraSpaceBetweenImageAndText_jnttwunq' is too long in /var/www/html/vendor/yiisoft/yii2/db/Command.php:1302

Can you try a shorter name (or just the handle) and see if that works for you?

@bob-pixeldeluxe
Copy link
Author

I have solved the issue but I thought I should report this. Somehow it half saved my matrix fields. So they did not appear in the back end but if I tried to add them it would give the error "a field with this handle already exists". They also existed in the database but where not visible in the field edit page. I cant reproduce the error this time if it it happens again ill report it here.

@brianjhanson
Copy link
Contributor

brianjhanson commented Dec 7, 2022

Ah, sorry, I missed that initially. Appreciate you reporting! I dug a little deeper and could reproduce and see what was going on.

In the process of saving a matrix field, when one of the handles is too long, the craft\services\Fields::applyFieldSave() method will throw an exception when it tries to update the column. The result of that exception is that the block record transaction is rolled back. At this point, previous fields in the block have already been saved to the fields table, but the exception means they don’t get added to the block’s field layout. That leaves them floating off on their own in the DB, existing enough to disallow the use of their handle but not enough to show in the UI.

I’m still working out how best to fix this at the moment. We’ll update here when we have a fix ready.

brianjhanson added a commit that referenced this issue Jan 4, 2023
Currently, matrix handle length validation doesn't include the block
type handle in the length, this makes it possible for you to create an
overall field handle that's longer than the DB will allow. When this
occurs things get left in a bad state, where some fields are saved and
others fail.

This fixes that issue by adding validation to matrix field handles to
make sure they're not too long when including the block type handle in
the field name.

Fixes #12422
@brandonkelly
Copy link
Member

Craft 3.7.63 and 4.3.6 are out with a fix for this, via #12501.

brianjhanson added a commit that referenced this issue Jan 9, 2023
Currently, matrix handle length validation doesn't include the block
type handle in the length, this makes it possible for you to create an
overall field handle that's longer than the DB will allow. When this
occurs things get left in a bad state, where some fields are saved and
others fail.

This fixes that issue by adding validation to matrix field handles to
make sure they're not too long when including the block type handle in
the field name.

Fixes #12422
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants