mails versturen
Er is al het nodige over geschreven op dit forum, maar tijdens mijn zoektocht kwam ik hierover nog niets tegen. Ik verstuur periodiek e-mails met een unieke url. Ik gebruik hiervoor Swift Mailer, een prima bibliotheek (imho). Zelf ben ik niet zo blij met de mogelijkheden van 'text/plain' waar het gaat om het tonen van de URL. Dan biedt 'text/html' meer mogelijkheden. 'Best practice' is wellicht om op beide manieren in één bericht te sturen (dat kan met Swift Mailer) en het mailprogramma van de ontvanger (bijv Outlook, Gmail, tc.) de afhandeling te laten doen. Hoe zorg ik ervoor dat de URL in 'text/plain' ook netjes zichtbaar wordt in het email-bericht? Wat zijn jullie ervaringen?
Gewijzigd op 02/12/2017 20:23:03 door Nick Vledder
In een text/plain mail zul je de URL gewoon moeten noemen in de body. De enige manier om die URL netjes te krijgen is door deze netjes te maken met rewrites.
Zelf gebruik ik het volgende om van een "html" mail een "plain" versie te maken (even geknipt uit een iets grotere mailwrapper class, dus dat moet je d'r even bij verzinnen):
//zonder code tags, want die braken allemaal over de regex ...
public $markup = ['b' => '*','i' => '/','u' => '_'];
public static function stripQuotes($str,$quotes = ["'",'"']){
return in_array($quote = substr($str,0,1),$quotes) && (substr($str,-1) == $quote) ? substr($str,1,-1) : $str;
}
public function stripTags($body){
foreach($this->markup as $tag => $char) $body = preg_replace("/(<$tag.*?>|<\\/$tag>)/",$char,$body);
if(preg_match_all('/<a.*?href\s*=\s*([^\s>]+).*?>(.*?)<\\/a>/',$body,$matches,PREG_SET_ORDER))
foreach($matches as list($full,$link,$descr)){
$link = self::stripQuotes($link);
$body = str_replace($full,$descr . ($link == $descr ? '' : " ($link)"),$body);
}
return strip_tags($body);
}
Bij een link (<a href=[link]>[descr]</a>) wordt de [link] dan dus tussen haakjes achter de [descr] gezet (indien niet gelijk aan elkaar).
Tevens worden <b>, <i>, en <u> omgezet naar resp. *...*, /.../. en _..._. Daarna trekt een strip_tags() alle overige markup d'r uit.
Met SwiftMailer wordt het dan:
//zonder code tags, want die braken allemaal over de regex ...
public $markup = ['b' => '*','i' => '/','u' => '_'];
public static function stripQuotes($str,$quotes = ["'",'"']){
return in_array($quote = substr($str,0,1),$quotes) && (substr($str,-1) == $quote) ? substr($str,1,-1) : $str;
}
public function stripTags($body){
foreach($this->markup as $tag => $char) $body = preg_replace("/(<$tag.*?>|<\\/$tag>)/",$char,$body);
if(preg_match_all('/<a.*?href\s*=\s*([^\s>]+).*?>(.*?)<\\/a>/',$body,$matches,PREG_SET_ORDER))
foreach($matches as list($full,$link,$descr)){
$link = self::stripQuotes($link);
$body = str_replace($full,$descr . ($link == $descr ? '' : " ($link)"),$body);
}
return strip_tags($body);
}
Bij een link (<a href=[link]>[descr]</a>) wordt de [link] dan dus tussen haakjes achter de [descr] gezet (indien niet gelijk aan elkaar).
Tevens worden <b>, <i>, en <u> omgezet naar resp. *...*, /.../. en _..._. Daarna trekt een strip_tags() alle overige markup d'r uit.
Met SwiftMailer wordt het dan:
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
$message = new \Swift_Message();
//...
$message->setTo($to);
if($subject) $message->setSubject($subject);
if($body){
if($html) $message->setBody($body,'text/html')->addPart($this->stripTags($body),'text/plain');
else $message->setBody($body);
}
return $message;
//...
$message->setTo($to);
if($subject) $message->setSubject($subject);
if($body){
if($html) $message->setBody($body,'text/html')->addPart($this->stripTags($body),'text/plain');
else $message->setBody($body);
}
return $message;
Gewijzigd op 02/12/2017 22:37:28 door Rob Doemaarwat
Ik gooi het zelf gewoon door een tekst browser print only mode. Dan blijft je markup behouden inclusief tabellen, het enige dat je dan krijgt is bijvoorbeeld iets als "klik hier (http://www.example.org/linkje)"
@Ben: "gooi het [...] door een tekst browser print only mode": is dat iets wat je via PHP/command line aanroept, of doe je dat handmatig?
Workaround: stuur het naar een soort van verkorte / tiny-URL (specifiek bedoeld voor links vanuit e-mailverkeer) die je binnen de site doorverwijst. Bijkomend voordeel van iedereen door hetzelfde poortje sturen: kun je ook meteen functionaliteit inbouwen die bijhoudt hoe vaak mensen op dat soort links klinken.
Rob dat gaat gewoon via exec binnen PHP. Werkt prima.
@Allen Bedankt voor de antwoorden. Voor de huidige URL maak ik al wel gebruik van rewrite (format URL: controller/action/id) in .htaccess. Desalniettemin is de optie van een tiny-URL wel 'nice to have' in de toekomst. Ik ga aan de slag met het advies van Rob en zal de resultaten bekijken in verschillende mailprogramma's. Resultaten zal ik posten in dit topic...
Toevoeging op 04/12/2017 14:43:17:
... korte samenvatting. Heb verschillende mailprogramma's een email gestuurd (SMTP mbv SwiftMailer). Zowel Hotmail als Gmail tonen de geschreven tekst en de url netjes. Zowel in 'text/html' als 'text/plain' gaan goed.
In SwiftMailer maakt het niet de volgorde niet uit:
$message->setBody($this->plainbody, 'text/plain')->addPart($this->htmlbody, 'text/html');
of
$message->setBody($this->htmlbody, 'text/html')->addPart($this->plainbody, 'text/plain');
SquirrelMail heeft een voorkeur voor 'text/plain', maar biedt vervolgens wel de mogelijkheid ook in html de html-versie te openen (dit gaat ook goed). Stuur je echter enkel de 'text/html'-versie dan gaat het mis bij de anchor-tag. Dit is alleen te ondervangen door de url ook in de omschrijving van de anchor-tag op te nemen. Vbd <a href="$url">$url</a>.
Toevoeging op 04/12/2017 14:43:17:
... korte samenvatting. Heb verschillende mailprogramma's een email gestuurd (SMTP mbv SwiftMailer). Zowel Hotmail als Gmail tonen de geschreven tekst en de url netjes. Zowel in 'text/html' als 'text/plain' gaan goed.
In SwiftMailer maakt het niet de volgorde niet uit:
$message->setBody($this->plainbody, 'text/plain')->addPart($this->htmlbody, 'text/html');
of
$message->setBody($this->htmlbody, 'text/html')->addPart($this->plainbody, 'text/plain');
SquirrelMail heeft een voorkeur voor 'text/plain', maar biedt vervolgens wel de mogelijkheid ook in html de html-versie te openen (dit gaat ook goed). Stuur je echter enkel de 'text/html'-versie dan gaat het mis bij de anchor-tag. Dit is alleen te ondervangen door de url ook in de omschrijving van de anchor-tag op te nemen. Vbd <a href="$url">$url</a>.




