コンテンツにスキップ
Nibiru docsv0.9.2

モジュール

Nibiru モジュールの構築 — MMVC の 2 番目の M。特性、プラグイン、インターフェース、設定、オブザーバー。

Stable Reading time ~ 3 min Edit on GitHub

A モジュールは自己完結型のドメイン単位です。各モジュールは、設定、プラグイン(サービス)、トレイト(再利用可能なメソッド)、インターフェースを所有しており、必要に応じて独自のMVCスライスも持つことができます。Nibiruは、サービスコンテナなしで太いコントローラー問題を回避するために、モジュールを使用しています。

Nibiru モジュールの植物学的解剖、ローズの重ねられた花びらのように描かれており — 外側の花びら、中間の花びら、内側の花びら、萼層、受精器。
各層別にモジュール。
application/module/<name>/
├── <name>.php # main class (implements IModule, optionally SplSubject)
├── interfaces/ # contracts for plugins / external consumers
│ └── <name>.php
├── plugins/ # stateless services usable from controllers
│ ├── <thing>.php
│ └── <other>.php
├── settings/ # auto-discovered .ini files
│ ├── <name>.ini
│ └── <name>.production.ini
└── traits/ # reusable method groups
└── <name>.php

Registry は起動時に application/module/ を走査し、各モジュールの settings/*.ini を発見します。モジュール名(大文字)に一致するセクションを解析し、Registry::getInstance()->loadModuleConfigByName('users') 経由で検索するためにキャッシュします。

<?php
namespace Nibiru\Module\Users;
use Nibiru\Module as ModuleAdapter;
use Nibiru\Interfaces\IModule;
use Nibiru\Registry;
class Users extends ModuleAdapter implements IModule, \SplSubject
{
use Traits\Users;
const CONFIG_MODULE_NAME = 'users';
protected static \stdClass $usersRegistry;
protected \SplObjectStorage $observers;
public function __construct() {
$this->setUsersRegistry();
$this->observers = new \SplObjectStorage();
}
public function attach(\SplObserver $o): void { $this->observers->attach($o); }
public function detach(\SplObserver $o): void { $this->observers->detach($o); }
public function notify(): void {
foreach ($this->observers as $o) { $o->update($this); }
}
protected function setUsersRegistry(): void {
self::$usersRegistry = Registry::getInstance()
->loadModuleConfigByName(self::CONFIG_MODULE_NAME);
}
}

IModule インターフェースは意図的にマーカーです — 実際の動作はすべてトレイトとプラグインにあります。

プラグイン:ステートレスサービス

Section titled “プラグイン:ステートレスサービス”

プラグインは、モジュール機能にアクセスするためにコントローラーがインスタンス化できるクラスです:

application/module/users/plugins/user.php
<?php
namespace Nibiru\Module\Users\Plugin;
use Nibiru\Module\Users\Users;
use Nibiru\Pdo;
class User extends Users
{
public function isAuthorized(): bool {
return isset($_SESSION['auth']['user_id']);
}
public function checkForStandardUser(): bool {
return $this->isAuthorized()
&& ($_SESSION['auth']['role'] ?? '') === 'standard';
}
}

コントローラー内で:

$this->user = new \Nibiru\Module\Users\Plugin\User();
if (!$this->user->isAuthorized()) {
View::forwardTo('/login');
}

プラグインはモジュールクラスを継承するので、レジストリ、設定、およびオブザーバーの機能にアクセスできます。

トレイトは、モジュールクラスが必要な再利用可能なメソッド本体を保持します。一般的なパターン:フォームファクトリーです。

application/module/users/traits/users.php
<?php
namespace Nibiru\Module\Users\Traits;
use Nibiru\Form;
trait Users
{
public function loginForm(): string {
Form::create();
Form::addOpenDiv(['class' => 'form-group']);
Form::addInputTypeText([
'class' => 'form-control', 'name' => 'login',
'placeholder' => 'Username',
]);
Form::addCloseDiv();
Form::addOpenDiv(['class' => 'form-group']);
Form::addInputTypePassword([
'class' => 'form-control', 'name' => 'password',
'placeholder' => 'Password',
]);
Form::addCloseDiv();
return Form::addForm([
'method' => 'POST',
'action' => '/login',
'name' => 'loginForm',
]);
}
}

メインの Users クラスは、use Traits\Users; を通じて取り込みます。

各モジュールは独自の INI ファイルを持つことができます。Registry は settings/ 内のすべての *.ini を解析し、モジュール名(大文字)で命名されたセクションを探します。

; application/module/users/settings/users.ini
[USERS]
session.lifetime = 7200
password.min.length = 12
allowed.roles[] = "admin"
allowed.roles[] = "editor"
allowed.roles[] = "standard"

どこからでも読み返す:

$cfg = \Nibiru\Registry::getInstance()->loadModuleConfigByName('users');
$cfg->session_lifetime; / 7200
$cfg->password_min_length; / 12
$cfg->allowed_roles; / [admin, editor, standard]

環境オーバーレイ:APPLICATION_ENV=production の場合、users.production.iniusers.ini よりも優先されます。

SplSubject を実装するモジュールは、イベントをアタッチされたオブザーバーにブロードキャストすることができます。デモンストレーションでは、analytics モジュールは各ページビュー時にアタッチされたトラッカーに通知します。

// in a controller
$analytics = new \Nibiru\Module\Analytics\Analytics();
$analytics->attach(new \Nibiru\Module\Analytics\Plugin\Matomo());
$analytics->attach(new \Nibiru\Module\Analytics\Plugin\Plausible());
$analytics->trackPageView(); / internally calls notify()

各観察者の update($subject) は、分析インスタンスを受け取り、関心のあるイベントデータを取得します。

展示アプリケーションから:

  • auth (TPMS) — セッション管理、QRコードログイン、ロールベースのアクセス。SplSubject を実装してログイン/ログアウトイベントをログ記録や監査モジュールに拡散させます。
  • cms (prod.maschinen-stockert.de) — コントローラパス + 言語でキー付けされたコンテンツストア。非開発者がサイトのコピーを更新できるようにします。
  • graph_mail (TPMS) — トランザクションメール用の Microsoft Graph API ラッパー。
  • pdfgenerator (prod.maschinen-stockert.de) — DBドライブテンプレートから機械カタログを生成します。
  • machineryscout — インデックス管理トレイトを使用した Elasticsearch インデックス管理。
  • assetmanager — 中央の CSS/JS パイプライン、言語ごとにテーマをスワップするために使用されます。
  • analytics — オブザーバドライブトラッカー拡散(Matomo 等)。

モジュール登録: フレームワークがモジュールを見つける方法

Section titled “モジュール登録: フレームワークがモジュールを見つける方法”

ディスク上のモジュールフォルダは必要ですが、十分ではありません。フレームワークもそれを読み込むように知らなければなりません — これは、あなたの [AUTOLOADER] 設定で3つの位置配列で行われます:

; application/settings/config/settings.development.ini
[AUTOLOADER]
iface.pos[] = "users" ; load application/module/users/interfaces/
iface.pos[] = "billing" ; load application/module/billing/interfaces/
trait.pos[] = "users" ; load application/module/users/traits/
trait.pos[] = "billing"
class.pos[] = "users" ; load application/module/users/users.php
class.pos[] = "billing"
class.plugin.pos[] = "" ; reserved

名前は小文字のフォルダ名であり、application/module/の下に表示される完全に同じです。フレームワークのAuto::loader()Dispatcherから呼び出されます)は、各モジュールを順番に読み込みます。

プラグインクラスは、複数形の名前空間 Plugins の下にあります:

application/module/billing/plugins/invoice.php
namespace Nibiru\Module\Billing\Plugins; / plural
class Invoice extends \Nibiru\Module\Billing\Billing { /* ... */ }

名前空間が一致しないと、オートローダーのミスが発生します。CLI スキャフォールド (./nibiru -m billing) は正しい名前空間を生成してくれます。

モジュールの INI ファイルを 登録しないでくださいRegistry は、[AUTOLOADER] がモジュールクラスを読み込んだ後、application/module/<name>/settings/*.ini を走査して自動的に発見します。各 INI の [<MODULE>](大文字)セクションは次のようになります:

$cfg = \Nibiru\Registry::getInstance()->loadModuleConfigByName('billing');
$cfg->invoice_prefix; / [BILLING] invoice.prefix property

レジストリは、APPLICATION_ENV が一致する場合に <module>.<env>.ini(例:billing.production.ini)を優先します。

モジュールにデータベーステーブルがある場合、既存の範囲を超えて番号を付けたSQLファイルをapplication/settings/config/database/に配置してください。AIモジュールで使用されている規約です。

200-ai_rag_collection.sql
201-ai_rag_chunk.sql
202-ai_conversation.sql
203-ai_message.sql

./nibiru -mi localで実行します。フレームワークは、[GENERATOR] database = trueが設定されている場合、application/model/<table>.phpにモデルを自動生成し、\Nibiru\Pdo::fetchAll(…)で使用できるようにします。

Terminal window
./nibiru -m billing

スキャフォールド:

application/module/billing/
├── billing.php
├── interfaces/billing.php
├── plugins/
├── settings/billing.ini
└── traits/

Graylogのログフックをスキャフォールドに事前に組み込む場合は、-g スイッチ(./nibiru -m billing -g)を追加してください。

すべてのコントローラーをモジュールに昇格させないでください。閾値は次の通りです: 少なくとも1つのトレイト、1つのプラグイン、1つのINIキーを持っていますか? はいの場合、独自のモジュールフォルダを獲得します。そうでない場合は、共有トレイトファイルまたは小さなapplication/lib/ヘルパーが十分です。