Categories: CakePHPPHP

FawnoEmail: enviar emails desde CakePHP con imágenes embebidas

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:

  1. Detectar automáticamente los tipos MIME
  2. 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.

alpha

Share
Published by
alpha
Tags: CakePHPPHP

Recent Posts

Apuntes de electrónica: Condensador y Bobina en alterna

Hace ya tiempo de mi última entrada de apuntes de electrónica. Fue la entrada sobre…

4 years ago

Review: Zoyi ZT-300AB Multimeter

Looking for cheap multimeters I found the Zoyi ZT-300AB, for about €20 we have a…

4 years ago

Zoyi multimeters, courtesy of Zotek Instruments

In my search for interesting multimeters I came across a manufacturer whose multimeters were sold…

4 years ago

Los productos remarcados

Desde que la industria empezó a deslocalizar sus fabricas llevando gran parte del peso de…

4 years ago

Análisis: Pinza amperimétrica Mestek CM83C

Desde que vi por primera vez una pinza amperimétrica quise tener una. Con la aparición…

4 years ago

Silencio

De lejos nos agobia, la distancia se hace notar con el silencio, de cerca es…

4 years ago