{"id":272,"date":"2016-07-22T02:11:44","date_gmt":"2016-07-22T00:11:44","guid":{"rendered":"http:\/\/lab.fawno.com\/?p=272"},"modified":"2022-03-07T13:39:56","modified_gmt":"2022-03-07T12:39:56","slug":"","status":"publish","type":"post","link":"https:\/\/lab.fawno.com\/en\/2016\/07\/22\/fawnoemail-enviar-emails-desde-cakephp-con-imagenes-embebidas\/","title":{"rendered":"","raw":""},"content":{"rendered":"","protected":false,"raw":""},"excerpt":{"rendered":"","protected":false,"raw":""},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","_editorskit_title_hidden":false,"_editorskit_reading_time":0,"_editorskit_typography_data":[],"_editorskit_blocks_typography":"","_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","_es_post_content":"\n

Una de las ventajas de utilizar un Framework<\/a> como CakePHP<\/a> es que enviar emails es muy sencillo.<\/p>\n\n\n\n

Sin embargo hay dos cosas que la clase CakeEmail no hace:<\/p>\n\n\n\n

  1. Detectar autom\u00e1ticamente los tipos MIME<\/a><\/li>
  2. Embeber autom\u00e1ticamente las im\u00e1genes<\/li><\/ol>\n\n\n\n

    Para solucionar ambos puntos he creado una clase que extiende a CakeEmail dot\u00e1ndola de estas funcionalidades: FawnoEmail<\/a>.<\/p>\n\n\n\n

    Para a\u00f1adir la detecci\u00f3n de los tipos MIME he clonado la funci\u00f3n attachments<\/a> de la clase original y le he a\u00f1adido el siguiente c\u00f3digo:<\/p>\n\n\n\n

    if (!isset($fileInfo['mimetype'])) {\n  if (function_exists('mime_content_type')) {\n    $fileInfo['mimetype'] = mime_content_type($fileInfo['file']);\n  } else {\n    $fileInfo['mimetype'] = 'application\/octet-stream';\n  }\n}<\/pre>\n\n\n\n

    B\u00e1sicamente CakeEmail establece el MimeType como 'application\/octet-stream' para todos los adjuntos que no especifiquen expl\u00edcitamente un MimeType. Lo que he hecho es detectar si existe la funci\u00f3n \"mime_content_type<\/a>\" y usarla en caso afirmativo.<\/p>\n\n\n\n

    En teor\u00eda la funci\u00f3n \"mime_content_type\" existe desde la versi\u00f3n 4.3 de PHP y por tanto no ser\u00eda necesario comprobar la existencia de la funci\u00f3n...<\/p>\n\n\n\n

    Para embeber las im\u00e1genes de manera autom\u00e1tica he extendido la funci\u00f3n _renderTemplates<\/a>. En t\u00e9rminos sencillos el truco consiste en obtener el renderizado del mail antes de ser enviado, de esta forma buscamos las im\u00e1genes a embeber y procedemos a ello.<\/p>\n\n\n\n

    La primera dificultad es determinar las im\u00e1genes que hay que embeber, lo he solucionado buscando todos las rutas que comiencen por \"file:\", \"file:\/\/\", \"cid:\" y \"cid:\/\/\".<\/p>\n\n\n\n

    Para cada imagen genero un contentId que utilizo para adjuntar la imagen y luego como ruta en el cuerpo del mail:<\/p>\n\n\n\n

    $rendered = parent::_renderTemplates($content);\n\nif (!empty($rendered['html'])) {\n  $rendered['html'] = str_replace(array('file:', 'file:\/\/', 'cid:\/\/'), 'cid:', $rendered['html']);\n  if (preg_match_all('~([\"\\'])cid:([^\\1]+)\\1~iU', $rendered['html'], $img)) {\n    $img = array_unique($img[2]);\n    foreach ($img as $file) if (is_file($file)) {\n      $cid = sha1($file);\n      $images['cid:' . $cid] = array('file' =&gt; $file, 'contentId' =&gt; $cid);\n      $files['cid:' . $cid] = $file;\n      $cids['cid:' . $cid] = $cid;\n    }\n    $this-&gt;addAttachments($images);\n    $rendered['html'] = str_replace($files, $cids, $rendered['html']);\n  }\n}<\/pre>\n\n\n\n

    En el GitHub de Fawno<\/a> ten\u00e9is disponible la clase.<\/p>\n","_es_post_name":"fawnoemail-enviar-emails-desde-cakephp-con-imagenes-embebidas","_es_post_excerpt":"","_es_post_title":"FawnoEmail: enviar emails desde CakePHP con im\u00e1genes embebidas","_en_post_content":"","_en_post_name":"","_en_post_excerpt":"","_en_post_title":"","edit_language":"en","footnotes":""},"categories":[15,5],"tags":[17,6],"class_list":["post-272","post","type-post","status-publish","format-standard","hentry","category-cakephp","category-php","tag-cakephp","tag-php"],"ninja_gutenberg_blocks_featured_media_urls":{"thumbnail":"","ninja_gutenberg_blocks_landscape_large":"","ninja_gutenberg_blocks_portrait_large":"","ninja_gutenberg_blocks_square_large":"","ninja_gutenberg_blocks_landscape":"","ninja_gutenberg_blocks_portrait":"","ninja_gutenberg_blocks_square":"","full":""},"_links":{"self":[{"href":"https:\/\/lab.fawno.com\/en\/wp-json\/wp\/v2\/posts\/272","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lab.fawno.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lab.fawno.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lab.fawno.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/lab.fawno.com\/en\/wp-json\/wp\/v2\/comments?post=272"}],"version-history":[{"count":4,"href":"https:\/\/lab.fawno.com\/en\/wp-json\/wp\/v2\/posts\/272\/revisions"}],"predecessor-version":[{"id":1866,"href":"https:\/\/lab.fawno.com\/en\/wp-json\/wp\/v2\/posts\/272\/revisions\/1866"}],"wp:attachment":[{"href":"https:\/\/lab.fawno.com\/en\/wp-json\/wp\/v2\/media?parent=272"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lab.fawno.com\/en\/wp-json\/wp\/v2\/categories?post=272"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lab.fawno.com\/en\/wp-json\/wp\/v2\/tags?post=272"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}