在 Craft CMS 迁移中更新 MatrixBlock "Field Layout Fields" 的句柄
Updating Handles for MatrixBlock "Field Layout Fields" in Craft CMS Migrations
看完this excellent Medium article, I've been stoked on Migrations in CraftCMS。他们在将相同的更改导入到我们网站上工作的 10 名左右的开发人员方面非常有用。
当尝试通过迁移更改矩阵块 (whew) 内块类型内各个字段的句柄时,我遇到了一个障碍。该字段本身可以很容易地更新其 "handle" 属性,但该矩阵块内容 (matrixcontent_xxxxx
) 的列 table 不会更新以反映任何更新的句柄。矩阵块与其关联的矩阵内容 table 之间的关联仅存在于该矩阵块的 field
记录的 info
列中。
如果 Matrix Block 的字段是通过 CMS 更新的,则更改会反映出来,因此它必须在 Craft 的源代码中的某个地方,但通过 Craft CMS Class Reference 并不明显。
有什么想法吗?
编辑以添加迁移片段:
public function safeUp()
{
// Strings for labels, etc.
$matrix_block_instructions = "instructions";
$block_label = "Video";
$block_handle = "video";
$field_handle = "video_url";
$field_label = "Video URL";
$field_instructions = "Add a YouTube or Facebook video URL.";
// Fetching the MatrixBlock fields used on the entries themselves
$video_gallery_1 = Craft::$app->fields->getFieldByHandle("handle_1");
$video_gallery_2 = Craft::$app->fields->getFieldByHandle("handle_2");
$video_gallery_3 = Craft::$app->fields->getFieldByHandle("handle_3");
$galleries = [$video_gallery_1, $video_gallery_2, $video_gallery_3];
foreach( $galleries as $gallery ) {
// Fetching the record for this specific MatrixBlock field.
$gallery_record = \craft\records\Field::find()->where(
['id' => $gallery->id]
)->one();
// Fetching the record for this specific MatrixBlockType
$gallery_block_id = $gallery->getBlockTypes()[0]->id;
$gallery_block = \craft\records\MatrixBlockType::find()->where(
['id' => $gallery_block_id]
)->one();
// Assigning standard labels for the MatrixBlockType
$gallery_block->name = $block_label;
$gallery_block->handle = $block_handle;
$gallery_block->update();
// Getting the specific ... 1 ... field to edit
$field_group = \craft\records\FieldLayout::find()->where(
['id' => $gallery_block->fieldLayoutId]
)->one();
$field_layout_field = $field_group->fields[0];
$field = $field_layout_field->field;
$field = \craft\records\Field::find()->where(
['id' => $field->id]
)->one();
// Assigning standard labels for the Label
$field->name = $field_label;
$field->handle = $field_handle;
$field->instructions = $field_instructions;
$field->update();
// Updating the MatrixBlock record with new instructions
$gallery_record->refresh();
$gallery_record->instructions = $matrix_block_instructions;
$gallery_record->update();
}
好的,如果有人想弄清楚这个问题,我深表歉意,但我上面的方法有点疯狂,但我已经找到了自己的解决方案。
这里的关键是我应该与 craft\fields\MatrixBlock
和 craft\fields\PlainText
对象交互,而不是 craft\records\Field
对象。 \craft\services\Fields
中有一种方法用于保存需要实现 FieldInterface 的字段。这实际上是返回的默认 类,我在代码中为自己做了更多的工作!
在那个 foreach
循环中,结果是:
// Fetching the record for this specific MatrixBlock field.
$gallery->instructions = $matrix_block_instructions;
// Update the MatrixBlockType
$gallery_block_id = $gallery->getBlockTypes()[0]->id;
$gallery_block = \craft\records\MatrixBlockType::find()->where(
['id' => $gallery_block_id]
)->one();
$gallery_block->name = $block_label;
$gallery_block->handle = $block_handle;
$gallery_block->update();
// Update the actual field.
$field = $gallery->blockTypeFields[0];
$field->name = $field_label;
$field->handle = $field_handle;
$field->instructions = $field_instructions;
Craft::$app->getFields()->saveField( $field );
Craft::$app->getFields()->saveField( $gallery );
感谢您看到这里,很抱歉您是个疯子。
看完this excellent Medium article, I've been stoked on Migrations in CraftCMS。他们在将相同的更改导入到我们网站上工作的 10 名左右的开发人员方面非常有用。
当尝试通过迁移更改矩阵块 (whew) 内块类型内各个字段的句柄时,我遇到了一个障碍。该字段本身可以很容易地更新其 "handle" 属性,但该矩阵块内容 (matrixcontent_xxxxx
) 的列 table 不会更新以反映任何更新的句柄。矩阵块与其关联的矩阵内容 table 之间的关联仅存在于该矩阵块的 field
记录的 info
列中。
如果 Matrix Block 的字段是通过 CMS 更新的,则更改会反映出来,因此它必须在 Craft 的源代码中的某个地方,但通过 Craft CMS Class Reference 并不明显。
有什么想法吗?
编辑以添加迁移片段:
public function safeUp()
{
// Strings for labels, etc.
$matrix_block_instructions = "instructions";
$block_label = "Video";
$block_handle = "video";
$field_handle = "video_url";
$field_label = "Video URL";
$field_instructions = "Add a YouTube or Facebook video URL.";
// Fetching the MatrixBlock fields used on the entries themselves
$video_gallery_1 = Craft::$app->fields->getFieldByHandle("handle_1");
$video_gallery_2 = Craft::$app->fields->getFieldByHandle("handle_2");
$video_gallery_3 = Craft::$app->fields->getFieldByHandle("handle_3");
$galleries = [$video_gallery_1, $video_gallery_2, $video_gallery_3];
foreach( $galleries as $gallery ) {
// Fetching the record for this specific MatrixBlock field.
$gallery_record = \craft\records\Field::find()->where(
['id' => $gallery->id]
)->one();
// Fetching the record for this specific MatrixBlockType
$gallery_block_id = $gallery->getBlockTypes()[0]->id;
$gallery_block = \craft\records\MatrixBlockType::find()->where(
['id' => $gallery_block_id]
)->one();
// Assigning standard labels for the MatrixBlockType
$gallery_block->name = $block_label;
$gallery_block->handle = $block_handle;
$gallery_block->update();
// Getting the specific ... 1 ... field to edit
$field_group = \craft\records\FieldLayout::find()->where(
['id' => $gallery_block->fieldLayoutId]
)->one();
$field_layout_field = $field_group->fields[0];
$field = $field_layout_field->field;
$field = \craft\records\Field::find()->where(
['id' => $field->id]
)->one();
// Assigning standard labels for the Label
$field->name = $field_label;
$field->handle = $field_handle;
$field->instructions = $field_instructions;
$field->update();
// Updating the MatrixBlock record with new instructions
$gallery_record->refresh();
$gallery_record->instructions = $matrix_block_instructions;
$gallery_record->update();
}
好的,如果有人想弄清楚这个问题,我深表歉意,但我上面的方法有点疯狂,但我已经找到了自己的解决方案。
这里的关键是我应该与 craft\fields\MatrixBlock
和 craft\fields\PlainText
对象交互,而不是 craft\records\Field
对象。 \craft\services\Fields
中有一种方法用于保存需要实现 FieldInterface 的字段。这实际上是返回的默认 类,我在代码中为自己做了更多的工作!
在那个 foreach
循环中,结果是:
// Fetching the record for this specific MatrixBlock field.
$gallery->instructions = $matrix_block_instructions;
// Update the MatrixBlockType
$gallery_block_id = $gallery->getBlockTypes()[0]->id;
$gallery_block = \craft\records\MatrixBlockType::find()->where(
['id' => $gallery_block_id]
)->one();
$gallery_block->name = $block_label;
$gallery_block->handle = $block_handle;
$gallery_block->update();
// Update the actual field.
$field = $gallery->blockTypeFields[0];
$field->name = $field_label;
$field->handle = $field_handle;
$field->instructions = $field_instructions;
Craft::$app->getFields()->saveField( $field );
Craft::$app->getFields()->saveField( $gallery );
感谢您看到这里,很抱歉您是个疯子。