Mail + pièce jointe PDF généré en PHP

Discussion dans 'Développement d'un site Web ou d'une appli mobile' créé par xdeslandes, 29 Juillet 2011.

  1. xdeslandes
    xdeslandes WRInaute occasionnel
    Inscrit:
    29 Décembre 2004
    Messages:
    332
    J'aime reçus:
    0
    Bonjour,

    J'ai un script qui génère des bons de livraison (BL) en PDF ou en HTML (suivant un paramètre html=0 ou 1 dans l'url)
    Après avoir épluché quelques posts, j'ai mis en place, en bas du BL HTML une fonctionnalité qui permet de saisir une adresse mail pour envoyer le BL au format PDF en PJ.

    Le mail parvient bien au destinataire, avec une PJ au format PDF: mais ce fichier pdf joint est vide (ou réduit à 0 je ne sais pas): il fait 0 ko et ne peut être ouvert pas Adobe Reader.

    J'ai tenté plusieurs soluces, mais en vain.

    Explications techniques:
    genrer_BL.php génère le BL au format DF ou HTML. Le format HTML affiche en plus un formulaire pour saisir l'adresse mail.
    envoyer_mailBL.php reçoit le $_POST, traite l'adresse, envoie le mail avec ça comme code:
    Code:
    	// Destinataire du mail
    	$destination = $_POST['mail_dest_bl'];
    	// Expediteur du mail
    	$from_mail = 'monadresse@mondomaine.com';
    	$from_name = "Prénom NOM";
    	// sujet du mail
    	$sujet = '[Mon entreprise] - votre BL';
    	// Chaine permettant de différencier les différentes parties du mail
    	$uid = md5(uniqid(time()));
    	$message = "Bonjour,\nVous trouverez en pièce jointe le BL demandé au format PDF.\n";
    	$message .= $signature_mail;
    	
    	// Traitement pour attacher une PJ
    	// D'abord on lit le fichier
    	$fichier = 'generer_BL.php?id_course='.$_POST['id_course'].'&pj=BL-'.$_POST['num_BT'].'.pdf&html=0';
    	$attachement = chunk_split(base64_encode($fichier));
    	
    	$header = "From: ".$from_name." <".$from_mail.">\r\n";
    	$header .= "Reply-To: ".$from_mail."\r\n";
    	$header .= "MIME-Version: 1.0\r\n";
    	$header .= "Content-Type: multipart/mixed; boundary=\"".$uid."\"\r\n\r\n";
    	$header .= "This is a multi-part message in MIME format.\r\n";
    	$header .= "--".$uid."\r\n";
    	$header .= "Content-type:text/plain; charset=iso-8859-1\r\n";
    	$header .= "Content-Transfer-Encoding: 7bit\r\n\r\n";
    	$header .= $message."\r\n\r\n";
    	$header .= "--".$uid."\r\n";
    	$header .= "Content-Type: application/pdf; name=\"BL-".$_POST['num_BT'].".pdf\"\r\n";
    	$header .= "Content-Transfer-Encoding: base64\r\n";
    	$header .= "Content-Disposition: attachment; filename=\"BL-".$_POST['num_BT'].".pdf\"\r\n\r\n";
    	$header .= $attachement."\r\n\r\n";
    	$header .= "--".$uid."--";	
    	// enfin on envoi le mail
    	$is_sent = @mail($destination, $sujet, "", $header);
    	if ($is_sent)
    	{
    		header('Location: generer_BL.php?id_course='.$_POST['id_course'].'&html=1&mail=ok');
    	}
    	else echo 'Envoi raté:<br />'.$headers;
    
    Avec $_POST['num_BT'] et $_POST['id_course'] qui étaient en type="hidden" dans le formulaire.

    generer_BVL.php génère le PDF avec mPDF (super d'ailleurs). Lorsqu'il est appelé avec le paramètre pj, il ressort le PDF avec ça:
    Code:
    	if (isset($_GET['pj']))
    		$livraison_mpdf -> Output('', 'S');
    	else
    		$livraison_mpdf -> Output();
    	exit;
    
    Où peut se trouver mon souci ?
     
  2. spout
    spout WRInaute accro
    Inscrit:
    14 Mai 2003
    Messages:
    9 032
    J'aime reçus:
    291
    Au lieu de réinventer toute la roue, tu as essayé l'envoi avec des libs style PHPMailer ou Swift Mailer ?
     
  3. UsagiYojimbo
    UsagiYojimbo WRInaute accro
    Inscrit:
    23 Novembre 2005
    Messages:
    11 887
    J'aime reçus:
    74
    +10 000

    1. Génération de la PJ physiquement sur le serveur
    2. Envoi du mail avec la PJ via PHPMailer
    3. Suppression de la PJ
     
  4. poulpe
    poulpe WRInaute discret
    Inscrit:
    29 Juin 2004
    Messages:
    88
    J'aime reçus:
    0
    d'accord avec spout, swiftmailer va te permettre de faire ca simplement, et c'est une mecanique eproouvee...
     
  5. xdeslandes
    xdeslandes WRInaute occasionnel
    Inscrit:
    29 Décembre 2004
    Messages:
    332
    J'aime reçus:
    0
    Wouaiiiis, bon d'accord. Cela me semblait être comme "utiliser une bombe nulcéaire pour tuer une mouche".
    Je ne pense d'ailleurs pas que le souci soit logiciel/applicatif.

    Mais bon, vous n'êtes pas les premiers à me le dire. Je tente PHPMailer et je reviens...
     
  6. UsagiYojimbo
    UsagiYojimbo WRInaute accro
    Inscrit:
    23 Novembre 2005
    Messages:
    11 887
    J'aime reçus:
    74
    Il suffit de pas grand chose, lors de la constitution des en-têtes d'un mail, pour merdoyer et envoyer un truc mal interprété ou planté.

    Tu as vérifié que le fichier que tu essaies d'envoyer était correctement généré ?
     
  7. xdeslandes
    xdeslandes WRInaute occasionnel
    Inscrit:
    29 Décembre 2004
    Messages:
    332
    J'aime reçus:
    0
    Tu veux dire si ses en-têtes http l'étaient ?

    En début de script PHP générateur du PDF, j'ai ça (donné par la web dev toolbar de Google Chrome):
    Code:
    include ($chem."mpdf51/mpdf.php");
    
    qui se charge d'envoyer les en-têtes correct (j'espère).

    Lorsque je génère le pdf "à la main", j'obtiens ça:
    Code:
    Request URL:http://plateforme.transporturgent.com/courses/generer_BL.php?id_course=7940&html=0
    Request Method:GET
    Status Code:200 OK
    Request Headers
    Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
    Accept-Encoding:gzip,deflate,sdch
    Accept-Language:fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
    Cache-Control:max-age=0
    Connection:keep-alive
    [...]
    Host:plateforme.transporturgent.com
    If-Modified-Since:Sat, 30 Jul 2011 13:39:00 GMT
    User-Agent:Mozilla/5.0 (Windows NT 5.1) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.122 Safari/534.30
    Query String Parametersview URL encoded
    id_course:7940
    html:0
    Response Headers
    Cache-Control:public, must-revalidate, max-age=0
    Connection:Keep-Alive
    Content-Encoding:gzip
    Content-Length:44543
    Content-Type:application/pdf
    Content-disposition:inline; filename="mpdf.pdf"
    Date:Sat, 30 Jul 2011 13:39:49 GMT
    Expires:Sat, 26 Jul 1997 05:00:00 GMT
    Keep-Alive:timeout=15, max=100
    Last-Modified:Sat, 30 Jul 2011 13:39:51 GMT
    Pragma:public
    Server:Apache/2.2.16 (Unix) mod_ssl/2.2.16 OpenSSL/0.9.8o
    Vary:Accept-Encoding,User-Agent
    X-Powered-By:PHP/5.2.13-pl1-gentoo
    (J'ai supprimé des infos concernant les cookies)

    C'est bien ou pas ?
     
  8. jcaron
    jcaron WRInaute accro
    Inscrit:
    13 Février 2004
    Messages:
    2 593
    J'aime reçus:
    0
    A moins que j'aie besoin de lunettes, il manque quand même un énorme truc dans ton script: générer ou récupérer le PDF!

    Tu fais:
    Code:
    $fichier = 'generer_BL.php?id_course='.$_POST['id_course'].'&pj=BL-'.$_POST['num_BT'].'.pdf&html=0';
    $attachement = chunk_split(base64_encode($fichier));
    
    Bref, ton fichier attaché, c'est juste l'URL (relative), pas le fichier lui-même. Si tu veux utiliser la logique que tu sembles privilégier (i.e. appeler le générateur de PDF à travers un appel http), il te manque un file_get_contents ou équivalent. Mais ça pose probablement un problème d'authentification (je suppose que tout le monde n'a pas accès à ce script), et c'est probablement un peu lourd pour pas grand chose, tu dois pouvoir gérer le PDF en interne directement, non?

    Au passage, l'utilisation de $_POST['truc'] sans filtrage, sans escape, sans rien, c'est quand même très dangereux.

    Et l'utilisation de librairies adaptées pour générer le mail ce n'est effectivement pas forcément une mauvaise idée.

    Jacques.
     
  9. UsagiYojimbo
    UsagiYojimbo WRInaute accro
    Inscrit:
    23 Novembre 2005
    Messages:
    11 887
    J'aime reçus:
    74
    +1 Jcaron. En fait ce que je te demandais c'est si le fichier créé physiquement était correcte ou pas. Or a priori, tu ne génères pas ce fichier, je vois mal dans ce cas comment tu peux l'envoyer en PJ.
     
  10. xdeslandes
    xdeslandes WRInaute occasionnel
    Inscrit:
    29 Décembre 2004
    Messages:
    332
    J'aime reçus:
    0
    ici, ce n'est pas dangereux.

    Ce que vous dites est juste. J'ai bien tenté de faire un file_get_content ou un fgets (je ne me souviens plus), mais j'avais alors un problème de récursivité.
    J'ai bientôt terminé mon test avec phpmailer. Je vous tiens au jus.
     
  11. jcaron
    jcaron WRInaute accro
    Inscrit:
    13 Février 2004
    Messages:
    2 593
    J'aime reçus:
    0
    Il est très, très rare que ce ne soit pas dangereux. Les gens mal intentionnés ont généralement plus d'imagination que les ceux qui développent.

    Jacques.
     
  12. xdeslandes
    xdeslandes WRInaute occasionnel
    Inscrit:
    29 Décembre 2004
    Messages:
    332
    J'aime reçus:
    0
    PhpMailer me répond:
    Code:
    Language string failed to load: recipients_failedmediaprodx@gmail.com
    Kesako ? Comment réparer ?
     
  13. UsagiYojimbo
    UsagiYojimbo WRInaute accro
    Inscrit:
    23 Novembre 2005
    Messages:
    11 887
    J'aime reçus:
    74
  14. xdeslandes
    xdeslandes WRInaute occasionnel
    Inscrit:
    29 Décembre 2004
    Messages:
    332
    J'aime reçus:
    0
    Merci.
    Bon, tout est OK: mes mails partent (et arrivent), cela fonctionne aussi avec une PJ 'en dur' (un fichier pdf stocké à côté du script), mais lorsque je lui demande d'attacher mon fichier pdf généré à la volée comme ça:
    Code:
    	$fichier = 'generer_BL.php?id_course='.$_POST['id_course'].'&pj=BL-'.$_POST['num_BT'].'.pdf&html=0';
    	$mail->AddAttachment($fichier);
    
    on me répond
    Code:
    Could not access file: generer_BL.php?id_course=3350&pj=BL-003020811.pdf&html=0
    C'est une question d'identification ?
    Peut-être faut-il générer le fichier, puis l'enregistrer, l'attacher au mail, et accessoirement le supprimer ensuite ?
     
  15. UsagiYojimbo
    UsagiYojimbo WRInaute accro
    Inscrit:
    23 Novembre 2005
    Messages:
    11 887
    J'aime reçus:
    74
    Je pense plutôt que c'est ça. perso je n'ai jamais procédé autrement.
     
  16. bproductiv
    bproductiv WRInaute accro
    Inscrit:
    27 Décembre 2004
    Messages:
    3 705
    J'aime reçus:
    0
    Je pense aussi, car là à part une url $fichier contient rien, faut te servir de curl pour générer le fichier non ?
     
  17. xdeslandes
    xdeslandes WRInaute occasionnel
    Inscrit:
    29 Décembre 2004
    Messages:
    332
    J'aime reçus:
    0
    Merc UsagiYojimbo.
    Du coup, dans mon script, je dois "déclencher" la génération du fichier, puis attacher ce fichier.
    Mais comment puis-je enregistrer le fichier généré (cela devient un autre problème !): avec un file_get_contents ??
     
  18. UsagiYojimbo
    UsagiYojimbo WRInaute accro
    Inscrit:
    23 Novembre 2005
    Messages:
    11 887
    J'aime reçus:
    74
  19. spout
    spout WRInaute accro
    Inscrit:
    14 Mai 2003
    Messages:
    9 032
    J'aime reçus:
    291
    Dans mPDF, tu as la méthode Output() qui te permet de sauvegarder dans un fichier au lieu de l'envoyer au navigateur si tu lui passe les bons paramètres:
    http://mpdf1.com/manual/index.php?tid=125
    Je pense que tu dois regarder à ce niveau là.
     
  20. xdeslandes
    xdeslandes WRInaute occasionnel
    Inscrit:
    29 Décembre 2004
    Messages:
    332
    J'aime reçus:
    0
    Oui, spout, j'avais bien pris connaissance de cette doc, mais comment faire appel à ce fichier ? Comment juste déclencher la génération du doc php tout en poursuivant le script d'envoi du mail ?
    Dans l'idéal:
    1- je génère le doc pdf avec output('nomfichier.pdf', 'F')
    2- je joint le document généré avec PHPMailer
    3- je supprime le document

    Si j'appelle directement le script generer_BL.php, pas de soucis: le fichier nomfichier.pdf est bien présent sur le serveur, et je
    le joins sans souci dans mon mail.
    Mon problème est de déclencher la phase 1...
     
  21. xdeslandes
    xdeslandes WRInaute occasionnel
    Inscrit:
    29 Décembre 2004
    Messages:
    332
    J'aime reçus:
    0
    Je viens de tenter ça:
    Code:
    	$nom_fichierBL = 'BL-123456789.pdf';
    	$fichier = 'generer_BL.php?id_course='.$_POST['id_course'].'&pj='.$nom_fichierBL.'&html=0';
    	file_put_contents($nom_fichierBL, $fichier);
    	
    	// envoi du mail avec PhpMailer
    	$mail = new PHPmailer();
    	$mail -> SetLanguage('en', $chem.'phpmailer/language/');
    //	$mail->IsSMTP();
    //	$mail->Host = 'smtp.transport-urgent.com';
    	$mail->From = 'exploitation@transporturgent.com';
    	$mail->AddAddress($destination);
    	$mail->AddReplyTo($from_mail, $from_name);	
    	$mail->Subject = $sujet;
    	$mail->Body = $message;
    	$mail->AddAttachment($nom_fichierBL);
    
    Et ça marche ...presque: le fichier est bien généré, il est ensuite joint à au mail. Mais ce fichier pdf ne fait que 56 octets (au lieu d'environ 50ko) et n'est pas lisible. Ce doit être un pb au niveau de mon file_get_contents...
     
  22. jcaron
    jcaron WRInaute accro
    Inscrit:
    13 Février 2004
    Messages:
    2 593
    J'aime reçus:
    0
    file_put_contents met dans un fichier des données que tu as déjà en mémoire, pas le contenu d'un autre fichier. Il faut donc d'abord que tu récupères le fichier avec file_get_contents, ou que tu utilises copy() pour faire directement la copie.

    Mais:
    - il faut que tu donnes une URL complète, pas juste une URL relative comme tu la construits jusque là
    - il est très vraisemblable que ça ne marchera pas parce que tu ne seras pas authentifié (je suppose que tout le monde n'a pas accès à ces URLs sans login ni rien...).

    Ce serait donc probablement plus efficace que tu appelles le code qui génère le PDF en lui disant de stocker tout ça dans un fichier. Si le code correspondant est déjà dans une fonction, il suffit de l'appeler. Dans le cas contraire, il faut que tu découpes ton script generer_BL.php en deux parties:
    - une partie qui contient une fonction avec le code de génération lui-même
    - une partie qui ne fait que un include du fichier précédent + appel de la fonction

    Ensuite dans le script d'envoi, un include du premier fichier + appel de la fonction, et hop.

    Jacques.
     
  23. xdeslandes
    xdeslandes WRInaute occasionnel
    Inscrit:
    29 Décembre 2004
    Messages:
    332
    J'aime reçus:
    0
    Merci pour ces tuyaux Jacques. Mais
    C'est pourtant ce que je fais (voir mon code plus haut), non ? Je ne comprends pas...
     
  24. jcaron
    jcaron WRInaute accro
    Inscrit:
    13 Février 2004
    Messages:
    2 593
    J'aime reçus:
    0
    Non, tu donnes juste un bout d'URL. Ce qu'il faut que tu fasses, c'est intégrer le code correspondant (via un include).

    Par exemple, si ton generer_BL.php c'est:
    Code:
    <?php
    toto();
    titi();
    tutu(param1,param2);
    ?>
    
    Il faut que tu découpes ça en un fichier qui contient le boulot, par exemple generer_BL.inc.php, qui contient:
    Code:
    function generer_BL($param1,$param2)
    {
      toto();
      titi();
      tutu($param1,$param2);
    }
    
    et ton generer_BL.php devient:
    Code:
    <?php
    include('generer_BL.inc.php');
    generer_BL(param1,param2);
    ?>
    
    Comme ça, tu peux inclure generer_BL.inc.php aussi dans ton script d'envoi de mail, et appeler la fonction au bon endroit pour generer le BL (en changeant les paramètres pour qu'il stocke ça dans un fichier plutôt que d'afficher.

    Jacques.
     
  25. xdeslandes
    xdeslandes WRInaute occasionnel
    Inscrit:
    29 Décembre 2004
    Messages:
    332
    J'aime reçus:
    0
    Yessss ! Merci Jacques.
    Cela m'a fait brasser pas mal mon code, mais cela fonctionne bien.

    Il me reste un détail propre à PHPMailer: le mail provient de Root User, alors que je lui ai indiqué
    Code:
    $mail->AddReplyTo($from_mail, $from_name);
    avec $from_name='mon nom';

    Et en mettant
    Code:
    $mail->SetFrom($from_mail, $from_name);
    on a une erreur:
    Code:
    Fatal error: Call to undefined method PHPMailer::SetFrom() in /home/transpor/www/courses/envoi_mailBL.php on line 65
    Je ne trouve rien dans la doc officielle (qui mentionne pourtantcette méthode)
     
  26. xdeslandes
    xdeslandes WRInaute occasionnel
    Inscrit:
    29 Décembre 2004
    Messages:
    332
    J'aime reçus:
    0
    En fait, on peut utiliser
    Code:
    $mail->From = '';
    $mail->FromName = '';
    Problème résolu !
     
  27. spout
    spout WRInaute accro
    Inscrit:
    14 Mai 2003
    Messages:
    9 032
    J'aime reçus:
    291
  28. Wefficient
    Wefficient WRInaute occasionnel
    Inscrit:
    2 Octobre 2007
    Messages:
    353
    J'aime reçus:
    0
    Moi je vois un autre problème à ta manière de proceder et cette fois ci c'est pas dans le code.
    Les règles emailing utilisées par les FAI et webmails font qu'ils n'aiment pas trop les pièces jointes, trop souvent associées à la propagations de virus ou de malwares.
    Pourquoi ne pas générer ton fichier sur ton serveur, et mettre dans ton mail un lien vers celui-ci ?
    Ainsi plus de fichier joint et moins de risques pour ta délivrabilité.

    Oui, on est loin du codage pur là :)
     
  29. xdeslandes
    xdeslandes WRInaute occasionnel
    Inscrit:
    29 Décembre 2004
    Messages:
    332
    J'aime reçus:
    0
    J'y ai bien pensé, mais à 80-100ko le pdf et à raisons de 5 à 10 envois par jour, cela fait du stokage inutile. Il faudrait alors penser à un système de conservation pendant N jours ou un truc du genre. J'ai aussi écarté cette solution car ces pdf peuvent être générés à la volée et sont donc dispo en permanence, sans qu'ils soient stockés quelquepart.
    Merci en tous cas.
     
Chargement...
Similar Threads - Mail pièce jointe Forum Date
Profondeur des pages et maillage interne Débuter en référencement 28 Juin 2020
Maillage Interne : stratégie Techniques avancées de référencement 22 Juin 2020
Ma première campagne Mailjet pour mon site Développement d'un site Web ou d'une appli mobile 29 Mai 2020
mot de passe gmail refusé Gmail, Google Talk, Blogger et Orkut 25 Mars 2020
WordPress Ajout d'un répertoire : maj du maillage interne ? Développement d'un site Web ou d'une appli mobile 9 Mars 2020
Emails type code de confirmation d'inscription : HTML ou TXT Administration d'un site Web 21 Février 2020
Mail automatique et Excel Développement d'un site Web ou d'une appli mobile 20 Février 2020
OVH - Comptes Emails hébergement + Exchange Développement d'un site Web ou d'une appli mobile 11 Février 2020
Email de détection de non conformités AdSense AdSense 3 Février 2020
Envoi de mail unitaire Développement d'un site Web ou d'une appli mobile 30 Janvier 2020
  1. Ce site utilise des cookies. En continuant à utiliser ce site, vous acceptez l'utilisation des cookies.
    Rejeter la notice