PowerCMS Xでモデルのpre_saveコールバックを試す

PowerCMS Xのpre_saveコールバックを使用して、カラムAとカラムBのデータを結合したデータをカラムCに保存するプラグインを作成してみました。pre_saveの話をしたいので、なぜデータを結合して保存するのかは省略します。

前提

モデル名 example_model
カラムAの名前 column_a
カラムBの名前 column_b
カラムCの名前 column_c

※つまりカラムA・カラムBはcolumn_a・column_bカラムのラベルです。

定義ファイル

定義ファイル(config.json)にプラグイン名等の基本情報とコールバックの指定を記述します。

{
    "label"       : "SamplePlugin",
    "id"          : "sampleplugin",
    "component"   : "SamplePlugin",
    "version"     : "1.0",
    "author"      : "Hideki Abe",
    "author_link" : "https://www.anothersky.pw/",
    "description" : "サンプルプラグインです。",
    "callbacks": {
        "pre_save_example_model": {
            "example_model" : {
                "pre_save" : {
                    "component" : "SamplePlugin",
                    "priority"  : 10,
                    "method" : "pre_save_example_model"
                }
            }
        }
    }
}

コールバックの設定では、モデル名の指定(example_model)とコールバックの指定(pre_save)以外は好きな名前を付けて良さそうです。

プラグイン・クラス

プラグイン・クラスファイル(SamplePlugin.php)にコードを記述します。関数名は定義ファイルのmethodで指定した名前にします。

<?php
require_once(LIB_DIR . 'Prototype' . DS . 'class.PTPlugin.php');

class SamplePlugin extends PTPlugin {

    function __construct () {
        parent::__construct();
    }

    function pre_save_example_model($cb, $app, &$obj, $original) {
        $params = $app->param();
        $column_c_value = $params['column_a'] . '-' . $params['column_b'];
        $obj->example_model_column_c = $column_c_value;

        return true;
    }
}

$app->param()で入力したデータの配列が取得できるので、それを利用してカラムAとカラムBのデータを結合し、example_modelのオブジェクト($obj)のプロパティとしてセットしてやれば良いようです。

ちなみに、カラムAがリレーションの場合はリレーション設定されているモデルのオブジェクトIDが入力値として取得できます。そのため、オブジェクトのラベルなどを取得したい場合はPADOでリレーション設定されているモデルを操作してラベルを取得する必要があります。

<?php
require_once(LIB_DIR . 'Prototype' . DS . 'class.PTPlugin.php');

class SamplePlugin extends PTPlugin {

    function __construct () {
        parent::__construct();
    }

    function pre_save_example_model($cb, $app, &$obj, $original) {
        $params = $app->param();
        $example_menu = $app->db->model('example_menu')->load($params['column_a'][0]);
        $example_menu_label = $menu->example_menu_label;
        $column_c_value = $example_menu_label . '-' . $params['column_b'];
        $obj->example_model_column_c = $column_c_value;

        return true;
    }
}

$app->db->model('example_menu')->load()で、example_menuモデルのオブジェクトを取得しています。あとはラベルがオブジェクトのプロパティにあるのでそれを使用してデータを組み立てれば良いことになります。入力値をdb->model()にそのまま入れていますが、サニタイズされるかバインドメカニズムが使用されるかだったはず。

値を確認したい

JavaScriptのconsole.log()感覚で値が見たくなる時があります。そのような時はvar_dump()するか(Xdebugをインストールしていると見やすい)、error_log( date( 'Y-m-d H:i:s T', time() ) . "\t" . $msg . "\n", 3, $app->log_dir . DS . 'debug.log' );のようなコードを差し込んでlogディレクトリにdebug.logを書き出すと良いのではないかと考えました。

JavaScriptやPHPが書けるUI開発者(フロントエンド・エンジニア)なら割と簡単にプラグインを作成することができました。

この記事のタグ