Vom: 16.10.2012

Umgehung des Layouts bei Pimcore

Wer in Pimcore anstelle einer HTML-Ausgabe direkt eine Datei zum Runterladen produzieren möchte, stößt schnell auf das Problem dass einem die nützlichen Features von Pimcore – wie zum Beispiel die Erzeugung der richtigen HTTP-Header oder eines HTML-Grundgerüsts – in die Quere geraten. So kann man beispielsweise mit PHPExcel zwar on the fly Excel-Dokumente erzeugen und abspeichern, aber nicht ohne Weiteres an den User zurückgeben z.B. mit print file_get_contents("export.xlsx"); da zum einen ein HTML-Mimetype gesendet wird, und zum anderen – so fern vorhanden – noch HTML mit ausgegeben wird. Ein direkter Download unter dem gewünschten Filenamen findet so auch nicht statt. Hier muß man also die richtigen Maßnahmen ergreifen, um aus dem HTML-Framework auszubrechen und direkt die gewünschten Fileinhalte und Header produzieren.

Headerausgabe

Pimcore benutzt das Zend_Controller_Response Objekt des Zend Frameworks, welches Inhalte und/oder Header vereinigt um sie in einem Rutsch zu versenden. Die Header und Inhalte werden von Pimcore automatisch erzeugt, man kann diese aber auch explizit setzen. Besonders wichtig hier ist das Headerfeld des MIME-Types "Content-Type", welches dem Browser sagt, von welchem Typ die empfangenen Daten sind. Meist ist das HTML (was direkt dargestellt wird), bei einem Download aber muss dies entsprechend gesetzt werden. Der MIME-Type für Excel ist application/vnd.ms-excel. Es kann, per Headerfield "Content-Disposition", bestimmt werden, unter welchem Filenamen die heruntergeladene Datei abgespeichert werden soll. Fehlt dieser Header erzeugen die Browser für gewöhnlich einen Namen aus Bestandteilen der aufgerufenen URL. Zu guter Letzt können auch noch Headerinformationen gesetzt werden, die das Cacheingverhalten des Browsers (und unter Umständen auch das einiger Proxys) beinflussen um so von vornherein unerwartete Probleme zu vermeiden. Zusammengefasst als Code sieht das, hier im Controller, so aus:

        $Response = $this->getResponse();
        $Response->setHeader("Content-Type", "application/vnd.ms-excel", true);
        $Response->setHeader("Content-Disposition", "attachment; filename=".$filename.".xlsx");
        $Response->setHeader("Expires", "0");
        $Response->setHeader("Cache-Control", "must-revalidate, post-check=0,pre-check=0");
        $Response->setHeader("Pragma", "public");

Deaktivierung der Layout-Ausgaben

Nun muß man Pimcore anweisen, die sonst übliche Ausgabe des Layouts und aller hier unnötigen Inhalte zu unterlassen:

$this->disableLayout(); // Nur nötig, wenn ein Layout verwendet wird
$this->removeViewRenderer();

Ausgabe des Inhalts

Zu guter Letzt kann nun der Inhalt ausgegeben werden. Ich nehme hier als Beispiel wieder die Ausgabe meines PHPExcel-Objekts:

        $objWriter = new PHPExcel_Writer_Excel2007($ExcelExport_Category);
        $tmp_filename = PIMCORE_TEMPORARY_DIRECTORY."/xls_export_".uniqid().".xlsx";
        $objWriter->save($tmp_filename);
        print file_get_contents($tmp_filename);
        unlink($tmp_filename);