一覧画面で選択したオブジェクトに対して一括で何らかの処理を行う機能のことを「アクション」といいます。
一覧画面で「アクション...」というドロップダウンメニューで選択して実行するものです(「モデル」「フィールド」など、アクションの存在しないモデルもあります)。この、アクションをプラグインによって追加することができます。
一覧画面からURLマップに対して、個別のモデルごとに再構築トリガーを一括設定(追加・削除)できるようにします。
PluginStarterでプラグインひな形を作成する 以下の内容を入力してプラグインひな形を作成します。
項目名 | 内容 |
---|---|
名前 | BatchTriggerControl |
バージョン | 1.0 |
作成者 | Alfasado Inc. |
作成者URL | https://alfasado.net/ |
説明 | Collectively set URL Map's rebuild triggers from the Listing Screen. |
説明(日本語) | 一覧画面からURLマップの再構築トリガーを一括設定します。 |
続いて「アクション」の左にある 追加 ボタンをクリックしてアクションを2つ追加します。
キー | モデル | ラベル | ラベル (日本語) | 入力 | 表示順 |
---|---|---|---|---|---|
remove_trigger | URLマップ | Delete Model's Triggers | モデルのトリガー削除 | 指定あり | 100 |
add_trigger | URLマップ | Add Model's Triggers | モデルのトリガー追加 | 指定あり | 101 |
プラグインひな形の入力項目は以上です。保存したら、エクスポートして、プラグインの ZIP ファイルをダウンロードしてください。
plugins/
└ BatchTriggerControl/ (root)
├ config.json (定義ファイル)
├ BatchTriggerControl.php (プラグイン・クラス)
├ locale/
│ └ ja.json (翻訳ファイル)
└ docs/
└ README.ja.md (ドキュメント)
ファイルを解凍したらプラグインディレクトリに設置します。開発中のものについては別途環境変数で「plugin_paths」を指定して、別のディレクトリに設置することをお勧めします。
何もコードを書かない状態でも、URLマップの一覧画面にアクションが2つ追加され、選択すると入力欄が出て、実行すると一覧画面に戻ってくることが確認できると思います(この段階では、オブジェクトに対する何の処理も行いません)。
まずはじめに、ドロップダウン選択時に表示される入力フィールドに何を入れたら良いのかがわかりませんので、メッセージを表示してから入力欄を出すようにします。
config.json の各アクションのところに「"hint": "Enter the model names separated by commas.",」を追加して保存します。
"list_actions": {
"action_urlmapping_remove_trigger": {
"urlmapping": {
"action_urlmapping_remove_trigger": {
"name": "action_urlmapping_remove_trigger",
"label": "Delete Model's Triggers",
"hint": "Enter the model names separated by commas.",
これで、ドロップダウンを選択した際に JavaScriptによる alert でメッセージが表示され、その後入力が表示されてフォーカスがあたるようになりました。
このままでは表示されるメッセージが英語のままです。ユーザーの選択言語が日本語のときは日本語で表示させたいというときは、localeディレクトリに ja.csv を追加します。CSVを作成して保存したら、このフレーズをシステムに認識させるために、BatchTriggerControlプラグインを一旦無効化して、再度有効化してください。システムの「システムオブジェクト」「フレーズ」にこのレコードが追加され、メッセージが日本語化されます。
Enter the model names separated by commas.,モデル名をカンマ区切りで入力してください。
続いて、BatchTriggerControl.php 内に実行させたい処理を追加します。「action_urlmapping_remove_trigger」「action_urlmapping_add_trigger」の2つのメソッドが追加されています。概要をコメントに追加しました。
function action_urlmapping_remove_trigger ( $app, $objects, $action ) {
// $app は クラスPrototype
// $objects は選択されたオブジェクト
// $actionは config.jsonに指定したアクション設定の配列
$class = new PTListActions(); // class.PTActions.php クラス
$input = $app->param( 'itemset_action_input' ); // 入力された値 ( 例 : page,folder )
$model = $app->param( '_model' ); // モデル(この場合は urlmapping )
$counter = 0;
foreach ( $objects as $obj ) {
// Some action to $obj. // ここにオブジェクトに対する処理を書く
$counter++;
}
if ( $counter ) {
$action = $action['label'];
$class->log( $action, $model, $counter ); // ログを保存する
}
$return_args = "does_act=1&__mode=view&_type=list&_model={$model}"
. "&apply_actions={$counter}" . $app->workspace_param;
if ( $add_params = $class->add_return_params( $app ) ) {
$return_args .= "&{$add_params}";
}
$app->redirect( $app->admin_url . '?' . $return_args ); // 元の画面にパラメタを追加してリダイレクト
}
実際のオブジェクトに対する処理は、foreach ( $objects as $obj ) { のループの中に記述します。
function action_urlmapping_remove_trigger ( $app, $objects, $action ) {
$class = new PTListActions();
$input = $app->param( 'itemset_action_input' );
$triggers = preg_split( '/\s*,\s*/', $input ); // カンマ区切りで渡されたモデルを配列化
$model = $app->param( '_model' );
$counter = 0;
foreach ( $objects as $obj ) {
$done = false;
foreach ( $triggers as $trigger ) {
$table = $app->get_table( $trigger ); // page
if (! $table ) { // 渡されたモデルがない
continue;
}
// 再構築トリガーは、mt_relation テーブルに relation_name='triggers' で保存されている
// mt_relationは、 from_obj, from_id, to_obj, to_id で何から何に対するリレーションかを idで関連付けているレコード
// SELECT * FROM mt_relation WHERE relation_name='triggers' AND relation_from_obj='urlmapping' AND
// relation_from_id=URLマップのID AND relation_to_obj='table' AND relation_to_id=モデル(mt_table)のID
$relation = $app->db->model( 'relation' )->get_by_key(
['name' => 'triggers',
'from_obj' => 'urlmapping',
'from_id' => $obj->id,
'to_obj' => 'table',
'to_id' => $table->id ]
);
if ( $relation->id ) {
// get_by_key は存在しない場合は新規オブジェクトを生成するので
// idに値があるかで存在チェック
$relation->remove();
$done = true;
}
}
if ( $done ) {
$counter++;
}
}
if ( $counter ) {
$action = $action['label'];
$class->log( $action, $model, $counter );
}
$return_args = "does_act=1&__mode=view&_type=list&_model={$model}"
. "&apply_actions={$counter}" . $app->workspace_param;
if ( $add_params = $class->add_return_params( $app ) ) {
$return_args .= "&{$add_params}";
}
$app->redirect( $app->admin_url . '?' . $return_args );
}
function action_urlmapping_add_trigger ( $app, $objects, $action ) {
$class = new PTListActions();
$input = $app->param( 'itemset_action_input' );
$triggers = preg_split( '/\s*,\s*/', $input ); // カンマ区切りで渡されたモデルを配列化
$model = $app->param( '_model' );
$counter = 0;
foreach ( $objects as $obj ) {
$done = false;
foreach ( $triggers as $trigger ) {
$table = $app->get_table( $trigger ); // page
if (! $table ) { // 渡されたモデルがない
continue;
}
// 再構築トリガーは、mt_relation テーブルに relation_name='triggers' で保存されている
// mt_relationは、 from_obj, from_id, to_obj, to_id で何から何に対するリレーションかを idで関連付けているレコード
// SELECT * FROM mt_relation WHERE relation_name='triggers' AND relation_from_obj='urlmapping' AND
// relation_from_id=URLマップのID AND relation_to_obj='table' AND relation_to_id=モデル(mt_table)のID
$relation = $app->db->model( 'relation' )->get_by_key(
['name' => 'triggers',
'from_obj' => 'urlmapping',
'from_id' => $obj->id,
'to_obj' => 'table',
'to_id' => $table->id ]
);
// $relation->idに値があれば既にトリガーの設定があるので、何もしない
// 存在しないときは指定したキー・バリューで新規オブジェクトを生成(この段階では未保存)
if (! $relation->id ) {
// relation_order に最大値+1をしていして保存するためにorderの一番値の大きなオブジェクトを取得
// SELECT * FROM mt_relation WHERE relation_name='triggers' AND relation_from_obj='urlmapping' AND
// relation_from_id=URLマップのID AND relation_to_obj='table' ORDER BY relation_order DESC LIMIT 1;
$last = $app->db->model( 'relation' )->get_by_key(
['name' => 'triggers',
'from_obj' => 'urlmapping',
'from_id' => $obj->id,
'to_obj' => 'table'],
['sort_by' => 'order',
'direction' => 'descend'] );
$order = 0;
if ( $last->id ) {
$order = $last->order;
}
$order++;
$relation->order( $order );
$relation->save(); // 新規保存
$done = true;
}
}
if ( $done ) {
$counter++;
}
}
if ( $counter ) {
$action = $action['label'];
$class->log( $action, $model, $counter );
}
$return_args = "does_act=1&__mode=view&_type=list&_model={$model}"
. "&apply_actions={$counter}" . $app->workspace_param;
if ( $add_params = $class->add_return_params( $app ) ) {
$return_args .= "&{$add_params}";
}
$app->redirect( $app->admin_url . '?' . $return_args );
}