Una de las ventajas de utilizar un Framework como CakePHP es que enviar emails es muy sencillo.
Sin embargo hay dos cosas que la clase CakeEmail no hace:
- Detectar automáticamente los tipos MIME
- Embeber automáticamente las imágenes
Para solucionar ambos puntos he creado una clase que extiende a CakeEmail dotándola de estas funcionalidades: FawnoEmail.
Para añadir la detección de los tipos MIME he clonado la función attachments de la clase original y le he añadido el siguiente código:
if (!isset($fileInfo['mimetype'])) { if (function_exists('mime_content_type')) { $fileInfo['mimetype'] = mime_content_type($fileInfo['file']); } else { $fileInfo['mimetype'] = 'application/octet-stream'; } }
Básicamente CakeEmail establece el MimeType como ‘application/octet-stream’ para todos los adjuntos que no especifiquen explícitamente un MimeType. Lo que he hecho es detectar si existe la función “mime_content_type” y usarla en caso afirmativo.
En teoría la función “mime_content_type” existe desde la versión 4.3 de PHP y por tanto no sería necesario comprobar la existencia de la función…
Para embeber las imágenes de manera automática he extendido la función _renderTemplates. En términos sencillos el truco consiste en obtener el renderizado del mail antes de ser enviado, de esta forma buscamos las imágenes a embeber y procedemos a ello.
La primera dificultad es determinar las imágenes que hay que embeber, lo he solucionado buscando todos las rutas que comiencen por “file:”, “file://”, “cid:” y “cid://”.
Para cada imagen genero un contentId que utilizo para adjuntar la imagen y luego como ruta en el cuerpo del mail:
$rendered = parent::_renderTemplates($content); if (!empty($rendered['html'])) { $rendered['html'] = str_replace(array('file:', 'file://', 'cid://'), 'cid:', $rendered['html']); if (preg_match_all('~(["\'])cid:([^\1]+)\1~iU', $rendered['html'], $img)) { $img = array_unique($img[2]); foreach ($img as $file) if (is_file($file)) { $cid = sha1($file); $images['cid:' . $cid] = array('file' => $file, 'contentId' => $cid); $files['cid:' . $cid] = $file; $cids['cid:' . $cid] = $cid; } $this->addAttachments($images); $rendered['html'] = str_replace($files, $cids, $rendered['html']); } }
En el GitHub de Fawno tenéis disponible la clase.