Chyba v \Nette\Mail\Message addEmbeddedFile – Content-ID se nedá použít v šabloně

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
iguana007
Člen | 970
+
0
-

Dnes jsem narazil na problém při vytváření emailu, který by obsahoval obrázky přímo v těle. Klient požadoval vkládat obrázky tak, aby přišly rovnou s emailem a netahaly se z externího serveru.
Na nette-chatu jsme zkoušeli vymyslet všechny možné postupy, jak obrázek do těla vložit, ale nic nezabralo. Prolezl jsem celé fórum a žadný z uvedených kódů taky nezabral.

Proto jsem začal pátrat po tom, jak to má správně fungovat v praxi a našel jsem problém, proč to nejde.
Když chceme vložit obrázek přimo do těla emailu a nemít jej vylistovaný mezi přílohami emailu, musí se obrázek vložit do hlaviček, na což nám slouží metoda: addEmbeddedFile – ta funguje v pohodě, až na jednu věc, generuje náhodné Content-ID, které pak nejde následně vložit do šablony pomocí cid:.

Obrázky se mi začaly v pohodě vkládat v momentě, kdy jsem metodě addEmbeddedFile přidal čtvrtý parametr $cid, kód metody tedy nyní vypadá takto:

public function addEmbeddedFile($file, $content = NULL, $contentType = NULL, $cid=NULL)
{
        return $this->inlines[$file] = $this->createAttachment($file, $content, $contentType, 'inline')
                //->setHeader('Content-ID', $this->getRandomId());
                ->setHeader('Content-ID', $cid);
}

a email jsem zkusil poslat takto:

<?php
require './libs/Nette/loader.php';
$mail = new \Nette\Mail\Message;
$mail->setFrom('info@server.cz');
$mail->addTo('muj@email.cz');
$mail->setSubject('test');
$mail->addEmbeddedFile('obrazek.jpg',  file_get_contents('obrazek.jpg'),'image/jpeg; name=obrazek.jpg','<xxx>');
$mail->setHTMLBody('<b>Sample HTML</b> <img src="cid:xxx">',FALSE);
$mail->send();
echo 'done!';

a email dorazil úplně bez problému i s obrázkem. Důležitá je právě vazba mezi Content-ID a cid: uvedeném v těle zprávy – email klient si už tyto vazby spojí sám.

Při vyřešení problému, mi pomohl tento článek: http://www.campaignmonitor.com/…s-revisited/

Nejsem si jist, jestli to je z hlediska Nette bug nebo záměr dávat do Content-ID random string, proto to dávám nejdříve tady, místo do issue trackeru.

Filip Procházka
Moderator | 4668
+
0
-

Funguje to řešení i na Gmailu atd? v té tabulce má, že to na Gmailu nefunguje.

iguana007
Člen | 970
+
0
-

Mě to funguje i v Gmailu – nevím jak to testoval, ale mě toto řešení fungovalo už před 3mi lety, kdy jsem ještě Nette nepoužíval.

Edit: zkusil jsem i Yahoo a tam to taky běží

Editoval iguana007 (26. 5. 2011 14:30)

iguana007
Člen | 970
+
0
-

Tak jsem nad tím ještě přemýšlel a napadlo mě, že by se to možná dalo obejít takto:

<?php
require './libs/Nette/loader.php';
$mail = new \Nette\Mail\Message;
$mail->setFrom('info@server.cz');
$mail->addTo('muj@email.cz');
$mail->setSubject('test');
$obrazek = $mail->addEmbeddedFile('obrazek.jpg')->getHeader('Content-ID');
$obrazek = str_replace('<','',$obrazek);
$obrazek = str_replace('>','',$obrazek);
$mail->setHTMLBody('<b>Sample HTML</b> <img src="cid:'.$obrazek.'">',FALSE);
$mail->send();
echo 'done!';

Nebo by se musela upravit metoda setHTMLBody aby nahrazovala obrazky v html cid: kódy, ale to by musel být k dispozici asi nějaký přepínač, který by umožňoval zapnout/vypnout volbu, jestli mají být obrázky načítány ze serveru nebo embedovány do hlavičky emailu.

Co si myslíte vy?

bojovyletoun
Člen | 667
+
0
-

detail: $obrazek = trim($obrazek,"><");

iguana007
Člen | 970
+
0
-

Já si říkal, že to musí jít nějak jednodušeji :) a dodnes jsem nevěděl, že má trim druhý parametr :D
Dal jsem si facku a ode dneška budu víc čumět v tom IDE co mi to napovídá :)

David Grudl
Nette Core | 8145
+
0
-

Mělo by to fungovat takto:

<?php
$mail = new \Nette\Mail\Message;
$mail->setFrom('info@server.cz');
$mail->addTo('muj@email.cz');
$mail->setSubject('test');
$mail->setHTMLBody('<b>Sample HTML</b> <img src="obrazek.jpg">', '/path/to/images');
$mail->send();
iguana007
Člen | 970
+
0
-

Aha, problém byl asi u mě v tom druhém parametru metody: setHTMLBody – zkusím to a dám vědět, ale co jsem se díval do zdrojového kódu, tak by to mělo běžet ok.
Díky

iguana007
Člen | 970
+
0
-

Tak ten druhý parametr vše vyřešil, funguje to super.

Kdyby někdo nevěděl, tak ještě doplním, že ‚/path/to/images‘ je absolutní cesta k obrázkům na serveru. Do šablony emailu se už potom uvádí pouze název obrázku bez cesty.

Díky