Zum Inhalt springen
Nibiru docsv0.9.2

Controller

Schreiben von Nibiru-Controllern – der Aktion Lebenszyklus, View::assign und Muster aus Produktionscode.

Stable Reading time ~ 3 min Edit on GitHub

Ein Nibiru-Controller ist eine Klasse, die von Nibiru\Adapter\Controller erbt, sich in application/controller/<name>Controller.php befindet und automatisch vom Dispatcher geladen wird, wenn eine URL wie /<name>/... ankommt.

<?php
namespace Nibiru;
use Nibiru\Adapter\Controller;
class productsController extends Controller
{
public function pageAction() {
View::assign([
'title' => 'Products',
'products' => $this->loadProducts(),
]);
}
public function navigationAction() {
JsonNavigation::getInstance()->loadJsonNavigationArray();
}
public function detailAction() {
$id = (int) ($_REQUEST['id'] ?? 0);
View::assign(['product' => $this->loadProduct($id)]);
}
private function loadProducts(): array { /* ... */ return []; }
private function loadProduct(int $id): array { /* ... */ return []; }
}

Wenn der Dispatcher einen Controller aufruft, ruft er die Methoden in dieser festgelegten Reihenfolge auf:

  1. navigationAction() — füllen Sie globale Menüs, Breadcrumbs und rollebasierte Navigation.
  2. <verb>Action() — nur wenn ?_action=<verb> gesetzt ist oder die URL einen zweiten Abschnitt hat, der eine Aktion benennt.
  3. pageAction() — letzter Aufruf vor dem Rendern.

Sowohl navigationAction() als auch pageAction() werden immer aufgerufen, selbst für unbekannte Aktionen. Dies ist praktisch (Sie müssen nie überprüfen), kann aber überraschen, wenn Sie annehmen, dass Aktionen exklusiv sind.

View::assign(['key' => $value, ...]) ist die Art und Weise, wie Daten an Templates gelangen. Es ist statisch und kann so oft aufgerufen werden, wie Sie möchten – später Aufrufe überschreiben frühere Aufrufe.

View::assign(['title' => 'Products']);
View::assign(['products' => $list]);
// In templates/products.tpl:
// {$title} → "Products"
// {$products} → the array

Hilfsfunktionen aus dem Basiscontroller:

$this->getRequest('id', false); / $_REQUEST['id'] ?? false
$this->getPost('email', ''); / $_POST['email'] ?? ''
$this->getGet('page', 1); / $_GET['page'] ?? 1
$this->getServer('REQUEST_URI'); / $_SERVER['REQUEST_URI']
$this->getFiles('upload'); / $_FILES['upload']
$this->getSession('auth'); / $_SESSION['auth']

Diese bestehen, weil Controller final-freundlich ist: Sie können sie in Tests durch eine untergeordnete Klasse ersetzen.

Um innerhalb einer Aktion umzuleiten:

View::forwardTo('/login'); / 302 to the URL, exits
View::forwardToJsonHeader(); / sets Content-Type: application/json

forwardToJsonHeader() ist das kanonische Muster für JSON-Endpunkte – setzen Sie den Header, weisen Sie data zu und geben Sie zurück. Der Anzeigebereich kümmert sich danach um die Reste.

Nibiru freut sich, eine beliebige Anzahl von Aktionen pro Controller zu hosten. Der TPMS-Controller erpController aus der Produktion hat pageAction, navigationAction, sowie syncAction, statusAction, dryRunAction, cancelAction usw. — jeweils über ?_action=sync oder /erp/sync aufgerufen.

// /erp/sync → $_REQUEST['_action'] = 'sync'
public function syncAction(): void
{
View::forwardToJsonHeader();
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
View::assign(['data' => ['success' => false, 'error' => 'POST method required']]);
return;
}
$result = AlphaplanSyncService::getInstance()->syncAbDocuments();
View::assign(['data' => $result]);
}

Controller sind dünn. Die meisten Logiken sollten in Modulen und deren Plugins leben:

namespace Nibiru;
use Nibiru\Adapter\Controller;
use Nibiru\Module\Users\Plugin\User;
class loginController extends Controller
{
private User $user;
public function __construct() {
parent::__construct();
$this->user = new User();
}
public function authAction() {
if (!$this->user->isAuthorized()) {
View::assign(['loginForm' => $this->user->loginForm()]);
} else {
View::forwardTo('/index');
}
}
}

Dieser Delegierungs-Muster ist konsistent in den Showcase-Anwendungen: Controller orchestrieren, Module führen die Arbeit aus.

Ein Muster von prod.maschinen-stockert.de — Laden Sie alle auf der Seite befindlichen Texte aus einer CMS-Tabelle, die nach dem Controller-Pfad indiziert ist:

public function pageAction() {
$controllerPath = $this->getController()
. '/' . $this->getRequest('_action', 'page');
$texts = Cms::init($this->getController())
->loadCmsTemplateTextsByControllerPath($controllerPath, $this->language);
foreach ($texts as $t) {
View::assign([
$t['cms_template_texts_text_identifier'] =>
$t['cms_template_texts_text_content']
]);
}
}

Ergebnis: Nicht-Entwickler können den Text ändern, ohne den Code zu berühren. Das CMS-Modul besitzt die Tabelle und die Editor-Benutzeroberfläche; der Controller lädt einfach nur Zeichenfolgen.

Die CLI erstellt einen Controller und seine Vorlage in einem Schritt:

Terminal-Fenster
./nibiru -c products

application/controller/productsController.phpapplication/view/templates/products.tpl

Beide sind mit dem kanonischen Gerüst bevölligt. Sie sind bereit zu schreiben.