baserCMSのパッケージのうち、BaserCore について「コア」と呼びます。また、それ以外について、テーマ機能を持つものをコアテーマ、さらにそれ以外をコアプラグイン呼びます。
コアテーマには、フロントテーマと管理画面テーマが存在します。
ここでは、上記全てを含めたものについて基本的な開発方法を説明します。
絶対パスの情報のように環境に依存し、処理中に変更の必要のない値は、定数で宣言します。
特に全体を通して参照する定数は、次のファイルに宣言します。bootstrap.php
は、プラグインごとに配置することができます。
/plugins/baser-core/config/bootstrap.php
アプリケーションの設定値は、Configureクラスで管理します。
次のファイルに配列で設定情報を記述すると、起動時に自動で読み込まれ、Configure::read()
を利用する事で、どこからでも参照する事ができます。setting.php
は、プラグインごとに配置することができます。
/plugins/baser-core/config/setting.php
ルーティングを定義するには、各プラグインの {PluginName}\Plugin::routes()
もしくは、config/routes.php
に定義してください。
テーブルを作成する際は、AppTable クラスを継承します。
AppTable クラスは、バリデーション機能の拡張等 baserCMSのコアの機能を提供しています。
class Dummy extends AppTable {}
テーブルに作成するメソッドは、基本的に対象テーブルに対する入出力に関するものだけに止め、ファットモデル化を防止します。
複数のテーブルにまたがる処理など、そのほかの処理は、サービスクラスに実装するようにしてください。
アプリケーションにおけるビジネスロジックはサービスクラスに実装します。
サービスクラスは、Service
ディレクトリに配置します。
エンティティの操作を前提とする場合、エンティティの複数形を前提とした名称とします。
# User エンティティの場合のサービス名
UsersService
# インターフェイス名
UsersServiceInterface
サービスクラスを作成する前に、DIコンテナにおける注入に対応するため、インタフェースを作成します。
エンティティのCRUDに対応する場合、次のメソッド名を参考に必要なものだけ定義してください。
\BaserCore\ServiceProvider\BcServiceProvider
にて利用するサービスの定義を追加します。
class BcServiceProvider extends ServiceProvider
{
// インターフェイスの定義
protected $provides = [
UsersServiceInterface::class,
];
public function services($container): void
{
// インターフェイスとサービスクラスの紐づけを定義
$container->add(UsersServiceInterface::class, UsersService::class);
}
}
プラグインの場合は、{PluginName}\ServiceProvider\{PluginName}ServiceProvider
を作成し、
{PluginName}\Plugin
にてサービスプロバイダの追加を行います。
namespace BcSearchIndex\Plugin;
public function services(ContainerInterface $container): void
{
$container->addServiceProvider(new BcSearchIndexServiceProvider());
}
新しく物理テーブルを作成し、インストール時に自動生成したい場合には、マイグレーションファイルの作成が必要です。
手動で作成 してもよいですが、migration_diff
コマンドを使うと既存のデータベースより自動生成することができます。
先にデータベースに新しいテーブルを作成した上で、コンテナにログインし、次のコマンドを実行します。
# マイグレーションファイル作成(事前に dump コマンドの実行が必要)
bin/cake migrations dump
bin/cake bake migration_diff CreateTableName -p PluginName
# シードファイル作成
bin/cake bake seed --data TableName -p PluginName
※ TableName、PluginName は任意の名称にします。
なお、複数のテーブルを追加した場合、migration_diff
コマンドを実行すると、1つのファイルに2つ分の定義が生成されますが、命名規則 に従い、手動で変更してください。
誰かがテータベース構造を変更した場合は、反映するために、コンテナにログインし、migrationの実行を行う必要があります。
# マイグレーションファイルを反映
bin/cake migrations migrate -p PluginName
# シードファイルを反映
bin/cake migrations seed -p PluginName
# 特定のシードファイルを指定する場合
bin/cake migrations seed --seed SamplesSeed -p PluginName
コントローラーを作成する際は、各役割ごとのスーパークラスを継承します。
フロント認証、ショートコード、言語設定など baserCMS独自のフロント実装を利用するには、
BcFrontAppController
クラスを継承し、Controller
直下に保存します。
namespace BaserCore\Controller;
class DummyController extends BcFrontAppController {}
管理システムのテーマ利用や認証機能を利用するには、
BcAdminAppController
クラスを継承し、Controller/Admin/
に保存します。
namespace BaserCore\Controller\Admin;
class DummyController extends BcAdminAppController {}
認証を必要としないアクションを作成する場合には、AuthenticationComponent::allowUnauthenticated()
を呼び出します。
public function initialize(): void
{
parent::initialize();
$this->Authentication->allowUnauthenticated(['actionA', 'actionB']);
}
認証済のユーザー情報を取得したい場合は次のコードで取得できます。
$result = $this->Authentication->getResult();
$user = $result->getData();
エンティティを操作するためのCRUDの名称は次のメソッド名としてください。
コントローラーアクションの引数にてサービスクラスのインターフェイスの型を定義すると、DIコンテナがインターフェイスに紐づくサービスクラスをインスタンス化して引数として引き渡してくれます。
public function add(UsersServiceInterface $service)
{
// メソッドを実行する
}
コントローラーの対象となるエンティティに対するサービスは $service
として定義します。その他の場合は $sitesService
ようにサービスが特定できる名称とします。
管理システム用のアクション等、プレフィックス付のアクションのテンプレートを作成する場合、
プレフィックス名をサブフォルダとし、その配下に配置します。
(例)ユーザー管理の index アクションの場合
templates/Admin/Users/index.php
同様の機能を持つエレメントが複数存在する場合はディレクトリで整理し、ディレクトリ名は単数形とします。また、エンティティに関連するエレメントの場合はエンティティの複数形とします。
(例)ヘルプファイルの場合
templates/Admin/element/help/contents_index.php
templates/Admin/element/help/dashboard_index.php
(例)User エンティティの場合
templates/Admin/element/Users/index_list.php
templates/Admin/element/Users/index_row.php
ビューファイルを記述する際、リンクを作成する場合、また、画像、CSS、Javascriptファイルを参照する場合には、BcBaserHelperを利用します。
これは、baserCMSが配布する前提のパッケージの為、サブディレクトリに設置した場合等、設置箇所の階層によりリンク切れが発生してしまうのを防ぐ為です。
// リンク
$this->BcBaser->link('title', '/path/to/link');
// 画像
$this->BcBaser->img('/path/to/image', ['alt' => 'title']);
// CSS
$this->BcBaser->css('/path/to/css');
// Javascript
$this->BcBaser->js('/path/to/javascript');
フォームコントロールのテンプレートを変更したい場合は、baser-core/config/bc_form.php
で定義していますのでそちらを変更します。
ブラウザバリデーションを無効にするためには、BcAdminForm::create() の 第2引数に ['novalidate' => true]
を追加します。
$this->BcAdminForm->control($entity, ['novalidate' => true]);
フォーム送信時にはセキュリティ対策としてバリデートポストが実行されますが次の方法により調整が可能です。
// ビューにて
$this->BcAdminForm->unlockField('field_name')
// Controller::beforeFilter()にて
$this->Security->config('unlockedActions');
postLink メソッドにより、フォームを作成せずとも簡単にPOST送信ができます。
echo $this->BcAdminForm->postLink(
__d('baser', 'ツリー構造をチェックする'),
['controller' => 'utilities', 'action' => 'verity_contents_tree'], [
'confirm' => __d('baser', 'ツリー構造をチェックします。よろしいですか?')
'class' => 'bca-btn'
]);
CSRFトークンを取得してフォーム送信する方法です。ただし、バリデートポストに必要なトークンは取得できないので、バリデートポストよりアクションを除外する必要があります。
// CSRFトークン取得
$.bcToken.check(function () {
form.append($.bcToken.getHiddenToken());
form.submit();
});
ヘルパを読み込むには次のメソッドにて実装します。
// アプリケーション全体の共通ヘルパの定義先
BaserCore\View\Helper\BcAppView::beforeRender()
// 管理画面の共通ヘルパ
BaserCore\View\Helper\BcAdminAppView::beforeRender()
// フロントページの共通ヘルパ
BaserCore\View\Helper\BcFrontAppView::beforeRender()
管理画面のメニューを表示するには、各パッケージの config/setting.php
の BcApp.adminNavigation
を編集します。
新しいテーブルを作成した場合、APIにて、CRUDも提供することを前提とします。
コントローラーを作成する際は、各役割ごとのスーパークラスを継承します。
認証なしの API を実装するには、BcApiController
クラスを継承し、Controller/Api/
に保存します。
namespace BaserCore\Controller\Api;
class DummyController extends BcApiController {}
認証付きの API を実装するには、BcAdminApiController
クラスを継承し、Controller/Api/Admin/
に保存します。
namespace BaserCore\Controller\Api\Admin;
class DummyController extends BcAdminApiController {}
エンティティを操作するためのCRUDの名称は次のメソッド名としてください。
baserCMSのユニットテストは、PHPUnitを利用しています。詳細については次のページを御覧ください。
基本的に、CakePHPが提供するコードは修正してはいけません。変更したい場合はCakePHPの本家にプルリクを送信しましょう。
ただし、baserCMSの仕様を作り上げる為にどうしても変更が必要な場合があります。その場合は composer.json に autoload を定義することで、名前空間を変更することができます。
# Cake\Routing の名前空間を BaserCore\Routing に変更する
{
"autoload": {
"psr-4": {
"Cake\\Routing\\": "plugins/baser-core/src/Routing"
}
}
}
その際、autoload を有効にするために、Dockerのコンテナにログインし、次のコマンドを実行します。
composer dump-autoload
なお、CakePHPのソースコードを変更する場合は、CakePHPのコード修正時のコメント に従って、必ずコメントを記述しておきます。