0

在阅读了这篇出色的 Medium 文章后,我对CraftCMS 中的迁移很感兴趣。它们对于在我们网站上工作的 10 位左右的开发人员中导入相同的更改非常有用。

当试图通过迁移更改矩阵块(whew)中块类型内的各个字段的句柄时,我遇到了一个障碍。字段本身可以轻松更新其“句柄”属性,但该矩阵块内容 ( matrixcontent_xxxxx) 的列表不会更新以反映任何更新的句柄。矩阵块与其关联的矩阵内容表之间的关联仅存在于该矩阵块的记录中的info列中。field

如果 Matrix Block 的字段是通过 CMS 更新的,则更改会被反映,因此它必须在 Craft 的源中的某个位置,但通过Craft CMS 类参考并不明显。

有任何想法吗?


编辑添加迁移片段:

    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();
}
4

1 回答 1

1

好的,如果有人被激怒了,我很抱歉,但我上面的方法是一种疯狂的人的方法,但我找到了自己的解决方案。

这里的关键是我应该与对象交互,craft\fields\MatrixBlockcraft\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 );

感谢您看到这里,并为成为一个疯狂的人而感到抱歉。

于 2019-07-18T20:20:53.517 回答