1
Help us understand the problem. What are the problem?

posted at

updated at

【baserCMS】AdminPageEditable プラグインを作りました。

こんにちは!
私は普段CMSを使ってコーポレートサイトを構築しているWEB系のエンジニアです。
なかでもbaserCMSを使って構築することが多いでのすが、今回専用プラグインを作ったのでご紹介です。
baserCMS4.5.4で当該プラグインが動作することを確認しました。
※4系の最近のバージョンだと動きそうですが3系とかはまったく動作しないかと

前提

CMS、PHPフレームワーク、MVCモデルがわかる
イベント処理がわかると尚良いかも

baserCMSとは

AdminPageEditable プラグイン

概要

baserCMSでは管理画面で自由に固定ページを追加、編集することができます。
コンテンツ編集エリアにテキストや画像などのファイルを貼り付けたりできる高機能なwysiwygエディタを備えているのですが時々一部どうしてもcssやjs、phpを使用して動的表示したい場合があると思いますがそういうかゆいところに手が届く機能が固定ページ編集画面に「コード」欄としてデフォルトで存在します。

スクリーンショット 2021-12-14 12.55.08.png

しかしながらこの機能、管理画面にログインするユーザグループによって一部機能に制限が設けられています。
※通常baserCMSではユーザグループごとにアクセス権限を設定します。

スクリーンショット 2021-12-14 11.53.26.png

こちらのようにデフォルトでシステム管理グループとサイト運営グループが存在するのですが運営グループのユーザの場合、この「コード」欄が表示されず、使用できません。
運営ユーザのグループを変更してシステム管理グループに所属させれば、「コード」欄の入力が可能になるのですが他の機能も利用できるようになるため、セキュリティ的に問題になる場合があります。
通常パーミッション設定によってページごとにアクセスを制限可能ですが今回は固定ページ編集画面の一部になるのでこちらが使用できません。

スクリーンショット 2021-12-14 13.17.32.png

ビューファイル /lib/Baser/View/Pages/admin/form.php の
47行目付近の「BcUtil::isAdminUser()」システム管理者ユーザ(グループ)だったら該当部分を表示するみたいな条件分岐が記述されています。

<?php if (BcUtil::isAdminUser()): ?>
    <div class="section">
        <table cellpadding="0" cellspacing="0" class="form-table">
            <tr>
                <th class="col-head"><?php echo $this->BcForm->label('Page.page_template', __d('baser', '固定ページテンプレート')) ?></th>
                <td class="col-input">
                    <?php echo $this->BcForm->input('Page.page_template', ['type' => 'select', 'options' => $pageTemplateList]) ?>
                    <div class="helptext">
                        <?php echo __d('baser', 'テーマフォルダ内の、Pages/templates テンプレートを配置する事で、ここでテンプレートを選択できます。') ?>
                    </div>
                    <?php echo $this->BcForm->error('Page.page_template') ?>
                </td>
            </tr>
            <tr>
                <th class="col-head"><?php echo $this->BcForm->label('Page.code', __d('baser', 'コード')) ?></th>
                <td class="col-input">
                    <?php echo $this->BcForm->input('Page.code', [
                        'type' => 'textarea',
                        'cols' => 36,
                        'rows' => 5,
                        'style' => 'font-size:14px;font-family:Verdana,Arial,sans-serif;'
                    ]); ?>
                    <?php echo $this->Html->image('admin/icn_help.png', ['class' => 'btn help', 'alt' => __d('baser', 'ヘルプ')]) ?>
                    <div class="helptext">
                        <?php echo __d('baser', '固定ページの本文には、ソースコードに切り替えてPHPやJavascriptのコードを埋め込む事ができますが、ユーザーが間違って削除してしまわないようにこちらに入力しておく事もできます。<br />入力したコードは、自動的にコンテンツ本体の上部に差し込みます。') ?>
                    </div>
                    <?php echo $this->BcForm->error('Page.code') ?>
                </td>
            </tr>
            <?php echo $this->BcForm->dispatchAfterForm() ?>
        </table>
    </div>
<?php else: ?>
    <?php echo $this->BcForm->input('Page.code', ['type' => 'hidden']) ?>
<?php endif ?>

そこで今回固定ページの「コード」欄を運営ユーザで利用できるようにする専用プラグインを作成しました。

仕様

当該プラグインを導入することで管理画面ログインユーザが固定ページ追加、編集画面を表示する際にアクセス権限設定をシステム管理者グループに差し替える処理を差し込むことで「コード」欄を表示させることを可能にします。
具体的にはプラグインのイベント処理を利用します。

AdminPageEditable/Event/AdminPageEditableControllerEventListener.php

public function pagesBeforeRender(CakeEvent $event) {
        $Controller = $event->subject();

        /**
         * 管理画面チェック
         */
        if (!BcUtil::isAdminSystem() ||
            !Hash::get($Controller->request->params, 'controller') == 'pages' ||
            !in_array(Hash::get($Controller->request->params, 'action'), ['admin_add', 'admin_edit']))
        {
            return true;
        }

        /**
         * 管理画面 対象ユーザチェック
         */
        //対象ユーザグループ
        $target_user_groups = Configure::read('AdminPageEditable.target_user_group');
        $user = $Controller->BcAuth->user();
        if (!$user || !in_array((int)Hash::get($user, 'user_group_id'), $target_user_groups)) {
            return true;
        }

        //一時的にユーザのグループ変更
        Configure::write('BcApp.adminGroupId', (int)Hash::get($user, 'user_group_id'));

    }

設定ファイル
AdminPageEditable/Config/setting.php
で設定されている該当グループに対してシステム管理グループに設定を差し替える処理を実装。
ユーザグループが増減した場合は、この設定ファイルを変更することで対応可能です。

/**
 * [Config] AdminPageEditable
 */
/**
 * システムナビ
 */
$config['AdminPageEditable'] = [
    //対象固定ページを管理者権限で編集可能にする
    'target_user_group' => [
        2, 3, //サイト運営、CMS運営: UserGroup.id
    ],
];

このままではフォーム保存時にModelのバリデーションで弾かれてしまうので
AdminPageEditable/Event/AdminPageEditableModelEventListener.php
にも処理を実装しています。

/**
     * pageBeforeValidate
     *
     * @param CakeEvent $event
     */
    public function pageBeforeValidate(CakeEvent $event) {
        $params = Router::getParams();

        /**
         * 管理画面チェック
         */
        if (!BcUtil::isAdminSystem() ||
            !Hash::get($params, 'controller') == 'pages' ||
            !in_array(Hash::get($params, 'action'), ['admin_add', 'admin_edit']))
        {
            return true;
        }

        /**
         * 管理画面 対象ユーザチェック
         */
        //対象ユーザグループ
        $target_user_groups = Configure::read('AdminPageEditable.target_user_group');
        $user = BcUtil::loginUser('admin');
        if (!$user || !in_array((int)Hash::get($user, 'user_group_id'), $target_user_groups)) {
            return true;
        }

        //一時的にユーザのグループ変更
        Configure::write('BcApp.adminGroupId', (int)Hash::get($user, 'user_group_id'));
        Configure::write('BcApp.allowedPhpOtherThanAdmins', true);

        return true;
    }

使用方法

1 こちらのソースをクローンするかダウンロード。
2 ソースを {プロジェクト}/app/Plugin/AdminPageEditable に配置。
3 ソースを配置すると管理画面のプラグイン管理で下記のように一覧に表示されるのでインストール。

スクリーンショット 2021-12-14 11.52.02.png

導入作業は以上です。

運営ユーザでログインした場合、プラグイン導入前は

スクリーンショット 2021-12-14 11.59.10.png

のように「コード」欄が表示されていなかったところ下記のように表示されるようになったと思います。

管理側表示

スクリーンショット 2021-12-14 12.55.08.png

公開側表示

スクリーンショット 2021-12-14 12.55.23.png

最後に

運営ユーザだけど固定ページで特殊なことをやりたいといった特定のシチュエーションに限定されるかもしれませんが機会があればご利用ください。
baserCMSは非常に拡張性の高い国産CMSです。
機会があれば自作プラグイン開発に挑戦してみるというのも良いかもしれません♪

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
1
Help us understand the problem. What are the problem?