Zend Framework : une aide d'action pour envoyer un PDF au navigateur

Zend_Pdf

Zend_Pdf ne dispose pas d'une méthode Output comme FPDF qui permet de générer et d'envoyer le fichier PDF au navigateur. Et c'est normal car le Zend Framework est conçu de façon à ce que chaque classe puisse être utilisée indépendamment des autres classes. Si on incluait une méthode similaire dans Zend_PDF, cela créerait une dépendance avec Zend_Controller_Response_Http qui peut être gênante si on génère des PDF depuis un script CLI ou dans une application qui n'utilise pas le modèle MVC.

Cette approche est cependant bien pratique, car l'envoi d'un PDF nécessite de positionner plusieurs entêtes (type, disposition et taille du contenu, contrôle du cache) et cela peut devenir rapidement fastidieux si on génère du PDF depuis plusieurs contrôleurs différents.

Pour résoudre ce problème, il faut écrire une aide d'action :

<?php
class Wiip_Controller_Action_Helper_SendPdf extends Zend_Controller_Action_Helper_Abstract
{
    public function 
direct($data$contentDisposition 'inline'$filename null)
    {
        if (!isset(
$filename)) $filename uniqid();

        
$this->getResponse()->setHeader('Content-Type''application/pdf');
        switch (
$contentDisposition) {
            case 
'inline':
                
$this->getResponse()->setHeader('Content-Disposition''inline');
                break;
            case 
'attachment':
                
$this->getResponse()->setHeader('Content-Disposition'"attachment; filename=\"$filename.pdf\"");
                break;
            default:
                throw new 
Exception("Unknown Content-Disposition ($contentDisposition)");
        }
                            
        
$this->getResponse()->setHeader('Content-Length'strlen($data))
                            ->
setHeader('Cache-Control''private, max-age=0, must-revalidate')
                            ->
setHeader('Pragma''public')
                            ->
setBody($data);
    }
}
?>

Elle peut être utilisée comme ceci :

<?php
public function pdfAction()
{
  
// Création d'un PDF et d'une page A4
  
$pdf = new Zend_Pdf();        
  
$pdfPage $pdf->newPage(Zend_Pdf_Page::SIZE_A4);
  
$pdf->pages[] = $pdfPage;

  
// On dessine quelque chose dans le PDF

  // On récupère le contenu du PDF
  
$data $pdf->render();

  
// Envoi du PDF au navigateur
  
$this->_helper->sendPdf($data);
}
?>

Par défaut, on envoie un entête Content-Disposition de type inline qui force l'affichage du PDF dans le navigateur. Si vous spécifiez attachment dans l'argument $contentDisposition, le navigateur devrait proposer à l'utilisateur de télécharger le fichier. Vous pouvez alors dans ce cas spécifier le nom du fichier avec l'argument $filename.

Si vous spécifier inline, le navigateur transmettra le fichier directement au plugin installé dans le navigateur (Acrobat Reader le plus souvent). Normalement, ce plugin proposera un bouton qui permet d'enregistrer une copie du fichier. Pour fournir un nom par défaut, vous devez utiliser une petite astuce : passez le nom du fichier en tant que dernier paramètre dans l'URL. Par exemple : /moncontroleur/monaction/filename/monnomdefichierpardefaut. Acrobat Reader devrait alors proposer monnomdefichierpardefaut.pdf comme nom de fichier par défaut. Si vous utilisez l'aide d'action Url pour générer vos URL, évitez les espaces, car il seront remplacés par un signe + (Zend_Controller_Router_Route::assemble utilise urlencode pour encoder les paramètres).

A lire également

Commentaires

Exactement ce que je recherchai, merci !

Bonjour,

n'étant encore qu'un débutant sur le framework, je voudrais avoir plus de précisions sur l'utilisation de cette classe, car je n'ai pas tout compris...
Où faut-il placer ces fichiers, et comment les utiliser ? pardonnez moi peut-être que pour certains cela est simple mais là je vois pas trop...

Merci d'avance.

Impeccable cette action helper.

Par contre maintenant il y a peu etre quelques choses à faire avec l'helper
ContextSwtich.

ContextSwitch c'est approprié si tu veux avoir plusieurs formats de réponse différents (HTML et PDF par exemple) pour la même action. A l'usage, c'est rarement le cas et c'est inutilement compliqué. Le plus simple c'est d'avoir une action pour chaque format.

Ajouter un commentaire