Controller
Schreiben von Nibiru-Controllern – der Aktion Lebenszyklus, View::assign und Muster aus Produktionscode.
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.
Anatomie eines Controllers
Abschnitt betitelt „Anatomie eines Controllers“<?phpnamespace 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 []; }}Der Lebenszyklus der Aktion
Abschnitt betitelt „Der Lebenszyklus der Aktion“Wenn der Dispatcher einen Controller aufruft, ruft er die Methoden in dieser festgelegten Reihenfolge auf:
navigationAction()— füllen Sie globale Menüs, Breadcrumbs und rollebasierte Navigation.<verb>Action()— nur wenn?_action=<verb>gesetzt ist oder die URL einen zweiten Abschnitt hat, der eine Aktion benennt.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.
Kommunikation mit der Ansicht
Abschnitt betitelt „Kommunikation mit der Ansicht“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 arrayHilfsfunktionen 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.
Weiterleitung
Abschnitt betitelt „Weiterleitung“Um innerhalb einer Aktion umzuleiten:
View::forwardTo('/login'); / 302 to the URL, exitsView::forwardToJsonHeader(); / sets Content-Type: application/jsonforwardToJsonHeader() 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.
Mehrere Aktionen pro Controller
Abschnitt betitelt „Mehrere Aktionen pro Controller“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]);}Arbeiten mit Modulen
Abschnitt betitelt „Arbeiten mit Modulen“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.
Mehrsprachige / CMS-gesteuerter Inhalt
Abschnitt betitelt „Mehrsprachige / CMS-gesteuerter Inhalt“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.
Controller generieren
Abschnitt betitelt „Controller generieren“Die CLI erstellt einen Controller und seine Vorlage in einem Schritt:
./nibiru -c products→ application/controller/productsController.php
→ application/view/templates/products.tpl
Beide sind mit dem kanonischen Gerüst bevölligt. Sie sind bereit zu schreiben.