---
title: "本番環境"
description: "実際のニブルアプリケーションが実際の収益を生み出しています。マシン・ストッカーは、このフレームワークを利用して12カ国で産業機械を販売しています。"
---

フレームワークとして使用価値のあるものは、物を運びます。代表的なNibiruのデプロイメントは、**Maschinen Stockert**グループです——オーストリアで最大の産業機械Eコマースプラットフォームを支える一組のリポジトリです。

2つのリポジトリはモジュールとデータベースを共有し、対象ユーザーによって責任を分担しています。

---

<div class="showcase-plate">
  <img src="/img/showcase-tpms.png" alt="工場の金時で動作している産業用CNC機械。" />
  <div class="showcase-plate__body">
    <p class="showcase-plate__meta">10コントローラー · 18モジュール · 150テンプレート · 36,289行のPHP</p>
    <h3 class="showcase-plate__title">maschinen-stockert.de — パブリックカタログ</h3>
    <p class="showcase-plate__desc">購入者向けサイト。中古産業機械を閲覧・検索、SEOフレンドリーなスラッグで豊富な詳細ページを表示、年間のHausmesse取引会に登録、見積もりを依頼。</p>
  </div>
</div>

## maschinen-stockert.de — パブリックカタログ

パブリックフェイス：産業的な購入者が着陆し、検索し、変換する場所です。

### その上に搭載されているもの

- **多言語コンテンツ**、すべての表示文字列が `<controller>/<action>` + 言語でキー付けされた `cms_template_texts` データベースから取得されます。エディターは管理画面からコピーを更新し、デプロイなしで反映されます。
- **Elasticsearch 機械検索**、型別フィルタリングが有効 — `"2500 × 1200 mm"` 文字列から次元が数値範囲に解析され、購入者はサイズで検索できます。
- **SEO 友好的な URL** — `/maschine/drehmaschine-2500/42` — マシン名から生成され、ドイツ語のアクセント記号正規化 (`ä → ae`, `ß → ss`) が行われます。数値 ID は常に最後尾に位置するため、ルーターが古いスラッグを解決できます。
- **Yumpu PDF フリップブック** でダウンロード可能なカタログ。
- **Hausmesse モジュール** で取引会参加登録と役割別アクセス。

### 一つの代表的なアクション
```php
// application/controller/maschineController.php
public function detailAction()
{
    $machineId = $this->getRequest('id', true);
    if (!$machineId) {
        http_response_code(404);
        return;
    }

    $controllerPath = $this->getController() . '/detail';
    $cmsTemplateTexts = Cms::init($this->getController())
        ->loadCmsTemplateTextsByControllerPath($controllerPath, $this->language);

    foreach ($cmsTemplateTexts as $t) {
        View::assign([
            $t['cms_template_texts_text_identifier']
                => $t['cms_template_texts_text_content']
        ]);
    }

    try {
        $machine = Machine::init()->getMachine((int) $machineId);
    } catch (\Throwable $e) {
        $machine = null;   // DB blip → page still renders with fallback.
    }

    $machineName = $machine['ms_machines_name'] ?? "Maschine #$machineId";
    $protocol = (($_SERVER['HTTPS'] ?? '') === 'on') ? 'https' : 'http';

    View::assign([
        'machine'        => $machine,
        'pageTitle'      => "$machineName - Maschinen Stockert",
        'metaDescription'=> "Details und Spezifikationen für $machineName",
        'canonicalUrl'   => $protocol . '://' . $_SERVER['HTTP_HOST']
                          . self::generateMachineSeoUrl($machineId, $machineName),
    ]);
}
```
50行、DIコンテナ、バリデーションパイプライン、ミドルウェアスタックを使用していません。CMSで管理されたコピーを最初に読み込みます（マシンでのDBダウンタイムがページを停止しないように）、マシンを優雅なフォールバックで引き込みます、SEOメタデータは常に生成します。詳細ページ全体は2回のデータベースラウンドトリップでレンダリングされます。

---

<div class="showcase-plate">
  <img src="/img/showcase-thorax.png" alt="技術書の山、一つがぼんやりと開かれている。" />
  <div class="showcase-plate__body">
    <p class="showcase-plate__meta">36コントローラー · 18モジュール · 348テンプレート · 161SQLマイグレーション · 37,369行のPHP</p>
    <h3 class="showcase-plate__title">data.maschinen-stockert.de — 管理 & API</h3>
    <p class="showcase-plate__desc">内部コックピット。販売スタッフは在庫、コンテンツ、仕事、チームページ、トレードショウ登録を管理します。開発者と統合はREST APIを呼び出してマシンを検索し、メーカーを同期し、PDFを生成し、OllamaでAIによる機械説明を得ます。</p>
  </div>
</div>

## data.maschinen-stockert.de — 管理者とAPI

同じモジュール、コントローラーとテンプレートは3倍 — 管理者UIやAPIには多くのエンドポイントが必要です。

### 何をしますか

- **Page-tree CMS**: エディタは Smarty テンプレートからページを構築します。`Parser` プラグインはテンプレート内の `{$identifier}` プレースホルダーを探し、編集可能なフィールドの管理 UI を自動生成します。テンプレート *は* フォーム仕様です。
- **Role-based ACL**: すべての管理者コントローラーのコンストラクタは `$this->user = new User(); $this->acl = new Acl(); $this->acl->init(); $this->user->validate();` — 3 行で完了します。販売担当者は在庫のみを読み取り、管理者は編集できます。パートナーは割り当てられたリストのみを表示します。
- **Public-API whitelist**: `apiController` は機械検索、カテゴリ取得、チーム情報、Ollama AI 呼び出しを認証なしで許可し、それ以外のすべてには認証が必要です。ホワイトリストはコンストラクタ内にあります — ミドルウェアの順序バグはありません。
- **Machineryscout indexer**: 最も重いモジュール。2,200 行のトレイトで MySQL 経由でマシン + 属性 + 画像 + 文書を取得し、型を正規化 (`"2500 x 1200"` → `dimension_width: 2500.0, dimension_height: 1200.0`)、不足している画像のプレースホルダーを置き換え、行を Elasticsearch に送信します。

### パーサーパターン — テンプレートからエディタUIを自動生成する
```php
// application/controller/adminController.php
$parser = Parser::init();
$cmsEditable = $parser->parseSmartyTemplateByTemplateId($templateId);
View::assign([
    'cmsEditable'        => $cmsEditable,
    'cmsTemplateTextForm'=> Cms::textsEditingForm('/admin/texts/create/text/new'),
]);
```
システムに新しい Smarty テンプレートをドロップすると、エディタはすぐにどのプレースホルダーが編集可能であるかを知ります。「フォームフィールドを登録」のステップはありません。

---

## 実際には特別な点、まとめ

以下の5つの違いは、上記のコードベースから抽出されました。それぞれが[Why Nibiru](/en/why-nibiru/)ページで証拠を示しています。

| | Nibiruの機能 | Laravel/Symfonyの機能 |
|---|---|---|
| ページコピー | リクエストごとに `<controller>/<action>` からDBで読み込み、エディタ管理。 | Blade / 翻訳JSONにハードコーディング；変更するにはデプロイが必要。 |
| モジュール構成 | モジュールあたり13つのトレイト、DIなし。 | サービスプロバイダー + IoCコンテナ。 |
| ORM | 直接SQL、MySQL `JSON_ARRAYAGG`、`Pdo::fetchAll`。 | Eloquent / Doctrineエンティティ + 遅延読み込みプロキシ。 |
| 認証 | コントローラーのコンストラクタで3行。 | ミドルウェアスタック + ポリシークラス + ゲート。 |
| イベント | PHP標準ライブラリの `SplSubject` + `SplObserver`。 | カスタムイベントディスパッチャー + リスナー登録 + キュー。 |

[詳細な解説とコード参照 →](/ja/why-nibiru/)

---

## それが必要だったこと

マシンストッカーは、実際の収益を生むサイトで、12カ国で機械を販売しています。チームは小さなですが、**161個のタイムスタンプ付きSQLマイグレーション**をフレームワークなしで本番に移行し、**74,000行のPHPコードを2つのリポジトリで管理**しており、サービスコンテナも使用していません。また、**18モジュール**がトレイトを使用して継承せずに構成されています。

それが証拠です。

小さなチームで、限られた予算で、デプロイやダウンタイムが実際のコストを伴う生産環境に移行する場合 — それがNibiruの最適な場所です。[Quick Start](/en/start/quick-start/)を読んでから戻ってください。
