blogスタッフブログ
HOME > スタッフブログ > CMS >PowerCMS Xで自分のオブジェクトではない特定のオブジェクトを特定の人が編集できるようにしたい

PowerCMS Xで自分のオブジェクトではない特定のオブジェクトを特定の人が編集できるようにしたい

社内でタイトルのような相談を受け、調査を行いました。PowerCMS Xで以下のようにロールを設定してAさん(ユーザーID: 3)に権限設定しているとします。

  • 記事の全てのリスト
  • 記事のリビジョン管理
  • 記事の有効化(公開)

この状況で、管理者の記事(ID: 4308)だけをAさんに編集させたい、という特殊な要望です。これはcan_doコールバックで操作すると実現できました。
画面キャプチャ:記事一覧で特定の記事だけ編集可能になっている様子

config.jsonでentryモデルの場合にcan_doコールバックの処理が実行されるようにします。

{
    "label": "CustomCanDo",
    "id": "customcando",
    "component": "CustomCanDo",
    "description": "",
    "version": "0.1",
    "author": "",
    "author_link": "",
    "callbacks": {
        "test_can_do": {
            "entry": {
                "can_do": {
                    "component": "CustomCanDo",
                    "priority": 10,
                    "method": "custom_can_do"
                }
            }
        }
    }
}

プラグインのPHPファイル(この例ではCustomCanDo.php)に以下のような記述をします。記事(ID: 4308)の時だけ$cb['can_do']trueにすると、記事の編集が可能となり、記事編集画面へのリンクも生きた状態になります。

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

class CustomCanDo extends PTPlugin {
    function custom_can_do( &$cb, $app, $obj ) {
        $user = $cb['user'];
        $model = $cb['model'];
        $object_id = $obj ? (int) $obj->id : (int) $app->param('id');

        if ($model === 'entry' && (int) $user->id === 3) {
            $target_object_id = 4308; // 記事IDを指定する
            if ($object_id === $target_object_id) {
                // 記事の編集
                $cb['can_do'] = true;
            } elseif (
                in_array($cb['action'], ['list', 'edit', 'duplicate', 'revision'])
                && (
                    (int) $app->param('rev_object_id') === $target_object_id
                    || (int) $obj->rev_object_id === $target_object_id
                )
            ) {
                // 記事編集ページでリビジョンの一覧表示
                $cb['can_do'] = true;
            } elseif ($cb['action'] === 'edit' && $app->param('edit_revision')) {
                $rev_object_id = (int) $obj->rev_object_id;
                if ($rev_object_id === $target_object_id) {
                    // リビジョンの編集
                    $cb['can_do'] = true;
                }
            }
        }
    }
}

この基本操作を踏まえてカスタマイズを実施すれば、特殊な権限の適用が可能になるかもしれません。(できると言い切れないのは、ワークフローとの併用は難しそうなど様々な条件が絡んでくるためです。)あらゆる場面でcan_doメソッドによる権限チェックが走るので、そこでtrue / falseを変更すれば規定の操作可否判定を上書きできるのが本記事の要点です。

豆知識

例えば記事に担当(in_charge)カラムを作成しユーザーIDを数値で保存できるようにしておけば、プラグインのPHPファイルでは$obj->in_chargeで担当カラムの値が取得できます。よって、以下のような記述をすると現在のユーザーが担当カラムに指定されている時のみ編集可能にすることが可能なようです。

if ($model === 'entry') {
    if ((int) $user->id === (int) $obj->in_charge) {
        $cb['can_do'] = true;
    }
}

最近の記事

カテゴリ

アーカイブ

スタッフ別