Vom: 05.09.2013

Pimcore: Im Backend eingeloggten User herausfinden

Will man im Pimcore Backend herausfinden welcher User eingeloggt ist, ist dies einfach. Die statische Methode Pimcore_Tool_Admin::getCurrentUser() liefert ein Objekt der Klasse User. Im Frontend, also zum Beispiel in einem Controller, liefert diese Methode aber immer Null. Warum ist das so? Und wie findet man es trotzdem heraus?

Session Handling in Pimcore

Viele Daten, die User- und Sitzungsbezogen sind wie zum Beispiel der gegenwärtige User, werden in PHP in einer Session gespeichert. Diese Session wird serverseitig verwaltet und mit einem Token identifiziert, der in einem Cookie im Browser des Users abgelegt ist. Dieser Cookie heisst bei PHP per default PHPSESSID. Pimcore dagegen verwendet eine eigene Session, die gegenüber der normalen Session vollständig gekapselt ist. Dies ist realisiert durch einen eigenen Cookie pimcore_admin_sid. Session_Cookies Wird Code im Kontext des Backends ausgeführt öffnet dieses daher eine eigene Session. In PHP kann immer nur eine Session aktiv sein, im Frontend stehen daher nicht die Informationen zur Verfügung, wie dies im Backend der Fall ist - und umgekehrt.

Zugriff auf die Pimcore-Session

Will man im Frontend auf die Session-Daten des Backends zugreifen könnte man den eigenen Controller nicht von Website_Controller_Action ableiten sondern wie es Pimcore macht von Website_Controller_Action_Admin, dann ist die aktuelle Session automatisch die Admin-Session. Dies muss man allerdings konsequent für alle Controller machen, die mit Sessiondaten arbeiten, wir haben daher nach einer alternativen Lösung gesucht. Dabei machen wir uns den Umstand zunutze, dass per Default die Sessiondaten serialisiert als File im Dateisystem vorhanden sind, und verarbeiten den Inhalt dieser Datei mit einer kleinen Klasse um an die Daten heranzukommen. Der Pfad zu der Datei ist in der php.ini definiert und kann mit dem Befehl ini_get("session.save_path") abgefragt werden. Der Dateiname baut sich auf nach dem Muster sess_<Session-ID>. Diese Session-ID wiederum ist, wie oben bereits beschrieben, im Cookie pimcore_admin_sid gespeichert, an diese kommt man also heran über die Variable $_COOKIE["pimcore_admin_sid"] Nun muss man also nur noch die Inhalte dieser Datei de-serialisieren und dabei beachten, dass die gewünschten Daten im Namespace pimcore_admin einer Zend_Session hinterlegt sind. Diese Aufgabe erledigt folgende kleine Klasse - sie ist abzulegen unter website/lib/Website/Tool/ An den User gelangt man nun mit dem Befehl Website_Tool_Backend::getCurrentUser()

class Website_Tool_Backend {

  /**
   * @var Website_Tool_Backend
   */
  protected static $instance;

  /**
   * @return Website_Tool_Backend
   */
  protected static function getInstance () {
    if(!self::$instance) {
      self::$instance = new self();
    }

    return self::$instance;
  }

  private $pimcore_session = null;

  public function __construct() {
    if (!array_key_exists("pimcore_admin_sid", $_COOKIE)) return null;

    $file_name = ini_get("session.save_path").DIRECTORY_SEPARATOR."sess_".$_COOKIE["pimcore_admin_sid"];

    if (!is_file($file_name)) throw new Exception("Session file \"".$file_name."\" doesn't exist");
    if (!is_readable($file_name)) throw new Exception("Session file \"".$file_name."\" is not readable");

    $file = file_get_contents($file_name);
    if (substr($file, 0, 13) != "pimcore_admin") throw new Exception("Something's wrong with \"".$file_name."\", can't find starter.");
    $parts = explode("|", $file, 2);
    $pimcore_session = unserialize($parts[1]);

    if ($pimcore_session === false) throw new Exception("Couldn't unserialize session data from File \"".$file_name."\"");

    $this->pimcore_session = $pimcore_session;
  }

  /**
   * Gets the user currently logged in pimcore, or null of not logged in.
   *
   * @return User
   * @throws Exception
   */
  public static function getCurrentUser() {
    $backend_tool = self::getInstance();
    return $backend_tool->pimcore_session["user"];
  }

}