Willkommen auf der privaten Homepage von Johannes Jarolim, Salzburg, Österreich. Welcome to the private homepage of Johannes Jarolim, Salzburg, Austria, Europe.

Lang gesucht und schließlich gefunden: Wie registriere ich eigene Viewhelper aus einem Pimcore-Plugin heraus.

Der Anwendungsfall

Wir erstellen ein Frontend-User-Authentifizierungs-Plugin, dass Pimcore nach Aktivierung (ganz vereinfacht) folgende Funktionalitäten zur Verfügung stellen soll:

  • Transparenter Schutz von Documents via Zend_Controller_Plugin
  • Ein Controller, mit dessen Hilfe der Login- und Logoutvorgang erfolgt
  • Ein ViewHelper, mit dessen Hilfe eine LoginBox dargestellt werden kann

Die ersten beiden Funktionalitäten stellen kein Problem dar – Doch wie bekomme ich den ViewHelper registriert?

Das Problem

Um eine abgeschlossene Funktionalität des Plugins zu gewährleisten, sollen die View Helper Klassen im Plugin-Verzeichnis liegen. Idealerweise sind die View Helper ohne weiteren Aufwand verwendbar, sobald das Plugin aktiviert wurde. Wir müssen daher mit Code, der ausschließlich im Plugin-Verzeichnis liegt, einen weiteren Helper-Path registrieren. Dazu müssen wir Zugriff auf die Pimcore_View-Instanz erhalten.

Da Pimcore im Grunde genommen aber keine Zend_Application, sondern eine Zend-Komponenten-nutzende Applikation ist, fallen Lösungswege wie zB. Konfigurations-Injection in die Bootstrap-Klasse flach.

Ein Lösungsweg via Controller Action Helper

Als Grundvoraussetzung haben wir das Plugin mit folgender Verzeichnisstruktur:

/plugins/FrontendUserAuth
/plugins/FrontendUserAuth/controllers
/plugins/FrontendUserAuth/install
/plugins/FrontendUserAuth/lib
/plugins/FrontendUserAuth/lib/Plugin.php
...

Die Plugin.php extended die Klassen Pimcore_API_Plugin_Abstract, welche selber ein Ancestor der Klasse Pimcore_API_Abstract ist. Wir finden hier die Methode preDispatch, welche von Pimcore vor dem Start des Display-Loops ausgeführt wird. Wir überschreiben die Methode in unserem Plugin und registrieren unseren Zend_Controller_Action_Helper, der den neuen ViewHelper-Pfad registrieren soll:

class FrontendUser_Plugin extends Pimcore_API_Plugin_Abstract implements Pimcore_API_Plugin_Interface {
  ...
  public function preDispatch() {
    Zend_Controller_Action_HelperBroker::addHelper(new FrontendUser_Controller_Action_Helper_ViewHelperInjector());
  }
  ..
}

Die neue Klasse erstellen wir hier:

/plugins/FrontendUserAuth/lib/FrontendUserAuth/Controller/Action/Helper/ViewHelperInjector.php

Zur Ausführungszeit des Controller Action Helpers bekommen wir dann mittels getActionController() den gerade ausgeführten Action Controller in die Hand: Voila, wir können global einen ViewHelperPfad registrieren, der in unserem Plugin-Directory Tree liegt:

<?php

  class FrontendUserAuth_Controller_Action_Helper_ViewHelperInjector extends Zend_Controller_Action_Helper_Abstract {

    public function preDispatch() {

      $controller = $this->getActionController();
      $view = $controller->view; /* @var $view Pimcore_View */
      $view->addHelperPath(PIMCORE_PLUGINS_PATH . '/FrontendUserAuth/lib/FrontendUserAuth/View/Helper', 'FrontendUserAuth_View_Helper_');

    }

  }

View Helper

Danach erstellen wir einen kleinen View Helper

/plugins/FrontendUserAuth/lib/FrontendUserAuth/View/Helper/LoginBox.php

welcher hier im Beispiel ganz einfach ein Loginform ausgibt:

<?php

  class FrontendUserAuth_View_Helper_LoginBox extends Zend_View_Helper_Abstract {

    public function loginBox() {
      return new FrontendUserAuth_Form_LoginForm();
    }

  }

Schlußendlich benutzen wir den ViewHelper in einem View Script der Website und freuen uns über eine neue, sauber abgekapselte, Funktionalität:

<div class="login-area">
  <?php echo $this->loginBox(); ?>
</div>

Zwei Antworten

  1. 17. February 2016, 14:03
    Comment by Thomas Keil
    Vielen Dank, hat mir sehr geholfen (wieder mal).

    Eine Anmerkung: wenn mehr als ein Plugin diese Methode verwenden, klappt das mit dem ViewHelperInjector so unter Umständen nicht, da diese mit seinem Namen auf dem Stack abgelegt wird und sich so überschreibt.

    Also entweder eindeutigen Namen vergeben oder noch zusätzlich die getName() implementieren:

    public function getName() {
    return "FrontendUserViewHelperInjector";
    }
    • 17. February 2016, 14:45
      Comment by Johannes
      Der Artikel ist ja schon so alt, dass es gar nicht mehr wahr ist ... Hat sich die Plugin-Infrastruktur nicht verbessert in der Zwischenzeit?

Hier können Sie eine Antwort hinterlassen

CAPTCHA Image
Reload Image