PowerCMS X ブログ

2024-01-25

フィールドブロックから ComponentBlocks へのデータ移行

PowerCMS から PowerCMS X への移行を検討する場合、PowerCMS 5 などで使われる「フィールドブロック」の入力データをどうするか?という問題が発生すると思います。本記事では、フィールドブロックの入力データを ComponentBlocks のデータに変換する PHP 製データ移行ツールの開発例をご紹介いたします。フィールドブロックは、FieldBlock-plugin.zip に含まれる sample-fieldblock.csv をインポートして使用したものと仮定します。

なお、本記事で紹介するフィールドブロックは PowerCMS 6 で追加されたフィールドブロックビルダーとは別の機能ですのでご注意ください。
PowerCMS 5の管理画面でフィールドブロックを利用して入力した画面のキャプチャ

サンプルコード

FieldBlock クラス

現在開発段階ですが、以下のような処理を実装しました。

  1. PowerCMS のデータベース(mt_entry_meta テーブルの entry_meta_vblob カラム)から指定の記事(ページ)のフィールドブロックデータを取り出す
  2. シリアライズを解除
  3. 管理画面上のフィールドの並び順に沿って入力データを配列に格納

その結果、以下のようなデータを得ることができます。

array(6) {
  ["smpltitle:1"]=>
  array(1) {
    ["title"]=>
    string(27) "見出しテキストです"
  }
  ["smplrt:1"]=>
  array(1) {
    ["text"]=>
    string(96) "<p>リッチテキストです。<strong>太字です。</strong></p>
<p>改行します。</p>"
  }
  ["smpltext:1"]=>
  array(1) {
    ["text"]=>
    string(45) "テキストエリアのテキストです。"
  }
  ["smpllink:1"]=>
  array(2) {
    ["text"]=>
    string(21) "アルファサード"
    ["url"]=>
    string(20) "https://alfasado.net"
  }
  ["smplmulti:1"]=>
  array(4) {
    ["image"]=>
    string(29) "__snippet_upload_asset__99088"
    ["select"]=>
    string(3) "猫"
    ["text1"]=>
    string(48) "複合型のテキストフィールドです。"
    ["text2"]=>
    string(42) "複合型のテキストエリアです。"
  }
  ["smplimg:1"]=>
  array(2) {
    ["image1"]=>
    string(29) "__snippet_upload_asset__99088"
    ["image2"]=>
    string(0) ""
  }
  ["フィールドブロックのベースネーム:順序"]=>
  array(1) {
    ["入力フィールドのkeyの値"]=>
    string(9) "入力値"
  }
}

データ変換スクリプト

FieldBlock クラスで処理したデータを基に、フィールドブロックの「[サンプル] 見出し」「[サンプル] リッチテキスト」を ComponentBlocks のデータに変換してみます。データの構造はComponentBlocksプラグインのドキュメントページでも解説しています。

  • ComponentBlocks のデータにある id は任意の文字列を生成してセットします
  • ComponentBlocks のデータにある type は、ブロック編集画面で入力したコンポーネント名をセットします
  • ComponentBlocks のデータにある id, type 以外のプロパティは、ブロック編集画面で設定したフィールド・繰り返しフィールドのキーです

事前に ComponentBlocks でデータ入力を行って「保存されるデータ」の内容を確認してから PHP を書くとゴールが見えやすいと思います。テキストデータ以外のアセット等は ID が変化するため、移行元と移行先での ID 対照表のようなものを作成する必要があります。フィールドブロックも ComponentBlocks も自在にフィールドが定義できるので、各プロジェクトの状況に応じたデータ移行ツールを頑張って作る必要があります。

<?php
function generateId()
{
    $str = 'abcdefghijklmnopqrstuvwxyz0123456789';
    return $rand_str = substr(str_shuffle(str_repeat($str, 10)), 0, 8);
}

// PowerCMSパスの設定 $powerCMSConfigFile = '/var/www/powercms5/app/mt-config.cgi'; $powerCMSPHPPath = '/var/www/powercms5/app/php';
// 記事(ページ)IDとカスタムフィールドのベースネームを設定 $entryId = 1707; $customFieldBaseName = 'e_fb_';
// データベースからフィールドブロックのデータを取得 require_once 'FieldBlock.php'; $fieldBlock = new PCMSXMigrator\FieldBlock($powerCMSConfigFile, $powerCMSPHPPath); $fieldData = $fieldBlock->get($customFieldBaseName, $entryId); // var_dump($fieldData); // NOTE: ここでフィールドブロックの保存データを確認できる
// 結果を格納する変数 $componentBlocksData = [];
// フィールドブロックをループして入力データを変換 // ここに変換ルールを書いていきます foreach ($fieldData as $fieldTypeWithOrder => $fieldValues) { $fieldType = preg_replace('/\:\d+$/', '', $fieldTypeWithOrder);
if (strpos($fieldType, 'smpltitle') === 0) { // フィールドブロックの「[サンプル] 見出し」をComponentBlocksの「Headingコンポーネント」のデータに変換 $componentBlocksData[] = [ 'id' => generateId(), 'type' => 'Heading', 'text' => $fieldValues['title'], 'level' => 2, ]; } elseif (strpos($fieldType, 'smplrt') === 0) { // フィールドブロックの「[サンプル] リッチテキスト」をComponentBlocksの「Textコンポーネント」のデータに変換 $componentBlocksData[] = [ 'id' => generateId(), 'type' => 'Text', 'text' => $fieldValues['text'], ]; } }
// JSONの出力 echo json_encode($componentBlocksData, JSON_UNESCAPED_UNICODE);

上記コードをコマンドラインで実行することにより、下記のような ComponentBlocks 向けのデータを得ることができます。

[{"id":"mw8wgul9","type":"Heading","text":"見出しテキストです","level":2},{"id":"1fvrbwcp","type":"Text","text":"<p>リッチテキストです。<strong>太字です。<\/strong><\/p>\r\n<p>改行します。<\/p>"}]

これを管理画面で表示すると以下のようになりました。
フィールドブロックから移行したデータを管理画面に表示した画面のキャプチャ

カテゴリー:技術情報

投稿者:安倍

ブログ内検索

アーカイブ