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

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

# 前提

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

# baserCMSとは
https://basercms.net/about/index.html

# AdminPageEditable プラグイン

## 概要

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

![スクリーンショット 2021-12-14 12.55.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131486/d989f7a9-2d0b-54b2-a907-fa609a959c82.png)

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

![スクリーンショット 2021-12-14 11.53.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131486/528c2393-bd99-4daf-289f-59d6be7c970a.png)

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

![スクリーンショット 2021-12-14 13.17.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131486/b5719d19-aeb7-a416-f68f-bc2afc43aa10.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;
	}
```


## 使用方法
https://github.com/a-killer-bee/AdminPageEditable

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

![スクリーンショット 2021-12-14 11.52.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131486/468e5aa0-f5c1-0ff9-8eec-0be5546ea7d3.png)

導入作業は以上です。

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

![スクリーンショット 2021-12-14 11.59.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131486/636236d2-03d3-0424-3e56-dd558ca586b9.png)

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

### 管理側表示
![スクリーンショット 2021-12-14 12.55.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131486/d989f7a9-2d0b-54b2-a907-fa609a959c82.png)

### 公開側表示

![スクリーンショット 2021-12-14 12.55.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131486/c363a38c-3e10-9477-6fd6-17da6544136e.png)


# 最後に

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