大量のオブジェクト(記事やページ等のデータ)を編集する際、PowerCMS Xに同梱のクラス「PADO」を用いてオブジェクトを操作すると作業がとても捗ります。先日、社内向けにPowerCMS Xのリリースノートを整理してモデルにインポートしたのですが、ルールに基づいて自動でタグを付ける作業があっという間にできました。
そこで本記事ではPHPを用いたリレーションの操作についてご紹介したいと思います。
基本操作
条件に基づいてオブジェクトを取得して表示したり、データを書き換えて保存する例はPowerCMS Xのドキュメント「PHPによるプログラミング・ガイド (データベース編)」に書かれていますが、基本は下記のようなコードです。
$entry = $app->db->model('entry')->load(1); // Id: 1の記事をロード
echo $entry->title; // titleカラムを表示
$entry->text('テスト記事です。文章が入ります。'); // textカラムに文章をセット
$entry->save(); // 記事を保存
新しく記事オブジェクトを作成する場合はnew
メソッドを利用します。引数にカラム名と値の配列を渡すと、オブジェクト作成と同時に値がセットされます。
$entry = $app->db->model('entry')->new([
'title' => 'テスト記事',
'text' => 'テスト記事です。文章が入ります。',
]);
この基本を覚えるだけでカラムタイプが「バイナリ」「リレーション」以外のカラムに対しては十分操作ができるようになります。
カテゴリやタグ等のリレーションの場合
カテゴリやタグ等、カラムタイプが「リレーション」の場合は$entry->tags('CMS');
のようにしても保存できません。タグを例に話を進めると、タグモデルにオブジェクトを作成し、リレーションの情報を保存するモデル(mt_relation)に記事とタグを紐付けるオブジェクト(データ)を作成しなければならないためです。
タグの作成
まずは記事と紐付けるタグを作成します。ただ、タグは既に存在している(登録されている)可能性があります。そのような場合はget_by_key
メソッドを利用します。指定の条件にマッチするオブジェクトがあればそれを返し、存在しない場合はオブジェクトを新規作成して値をセットして返してくれる便利なメソッドです。
下記のような関数を定義するとタグを新規作成・取得してそのIDを返すようになります。
function getTagId(string $tagName, int $workspaceId, string $model):int {
global $app;
$terms = [
'name' => $tagName, // タグ名
'workspace_id' => $workspaceId, // ワークスペースID
'class' => $model, // タグを利用するモデル名
];
$tag = $app->db->model('tag')->get_by_key($terms);
if (!$tag->id) {
// IDがない…つまり新規の場合はタグを保存する
$tag->save();
}
return $tag->id;
}
リレーションの保存
リレーションモデルも記事等と同様にnew
メソッドでオブジェクトを作成して値をセットし保存しても良いのですが、クラス「Prototype」にはリレーションをセットするset_relations
メソッドが用意されており、これを利用すると簡単です。ややこしく見えますが、リレーション元(記事モデル)の情報とリレーション先(タグモデル)の情報を指定して渡しているだけなので、注意深く見ていたければと思います。
$entry = $app->db->model('entry')->new();
// $entryに対する操作をする
$entry->save(); // 先に保存する
$tagIds = [];
$tagIds[] = getTagID('新製品', 1, 'entry'); // タグ「新製品」のIDを取得
$tagIds[] = getTagID('BtoC', 1, 'entry'); // タグ「BtoC」IDを取得
$args = [
'from_id' => $entry->id, // リレーション元ID(例では記事のID)
'from_obj' => 'entry', // リレーション元モデル名(例では記事)
'name' => 'tags', // リレーション元モデルのカラム名(例ではtagsカラム)
'to_obj' => 'tag', // リレーション先モデル名(今回はタグモデル)
];
$app->set_relations($args, $tagIds); // リレーションの条件とリレーション先IDを渡してセットしてもらう
これでリレーションデータの保存は完了です。記事とタグを紐付けるケースで説明いたしましたが、アセット・カテゴリ等も同様の記述です。なお、set_relations
メソッドの第2引数で渡さなかったIDのリレーションは自動で削除されます。(第3引数がtrue
の場合を除く)
予告
残るはアセット等のバイナリの操作です。またの機会にアセットの操作についてご紹介したいと思います。