/** * @param \Swift_Message $messageInstance * @param $contentHtml * @param array $embeddedImages * * @return mixed */ protected function _embedContentImages(\Swift_Message $messageInstance, $contentHtml, array $embeddedImages) { if ($embeddedImages !== NULL) { foreach ($embeddedImages as $stackIndex => $pathImage) { $cid = $messageInstance->embed(\Swift_Image::fromPath($pathImage)); $contentHtml = str_replace('{{imageStackIndex:' . $stackIndex . '}}', $cid, $contentHtml); } } return $contentHtml; }
/** * embed images to the given body * * @param string $body * @return string */ protected function embedImages($body) { foreach ($this->embedded as $image) { if (false !== strpos($body, $this->embeddedUrl . $image)) { $cid = $this->message->embed(Swift_Image::fromPath($this->embeddedDir . $image)); $body = str_replace($this->embeddedUrl . $image, $cid, $body); } } return $body; }
public function getEmbeddedHtmlMessage(\Swift_Message &$message) { $renderedHtml = $this->getRenderedHtmlMessage(); if (!empty($this->embedImages['urlPrefix'])) { $regexp = '#[\'"](' . preg_quote($this->embedImages['urlPrefix']) . '([^\'"]+\\.(gif|png|jpg|jpeg)?))[\'"]#ium'; preg_match_all($regexp, $renderedHtml, $matches, PREG_SET_ORDER); foreach ($matches as $match) { $embed = $message->embed(Swift_Image::fromPath($this->embedImages['path'] . $match[2])); $renderedHtml = str_replace($match[1], $embed, $renderedHtml); } } return $renderedHtml; }
/** * Embed the image in message and replace the image link by attachment id. * * @param \Swift_Message $message The swift mailer message * @param \DOMAttr $node The dom attribute of image * @param array $images The map of image ids passed by reference */ protected function embedImage(\Swift_Message $message, \DOMAttr $node, array &$images) { if (0 === strpos($node->nodeValue, 'cid:')) { return; } if (isset($images[$node->nodeValue])) { $node->nodeValue = $images[$node->nodeValue]; } else { $node->nodeValue = EmbedImageUtil::getLocalPath($node->nodeValue, $this->webDir, $this->hostPattern); $cid = $message->embed(\Swift_Image::fromPath($node->nodeValue)); $images[$node->nodeValue] = $cid; $node->nodeValue = $cid; } }
public function testWritingMessageToByteStreamTwiceProducesCorrectStructure() { $message = new Swift_Message(); $message->setSubject('test subject'); $message->setTo('*****@*****.**'); $message->setCc('*****@*****.**'); $message->setFrom('*****@*****.**'); $image = new Swift_Image('<data>', 'images.gif', 'images/gif'); $cid = $message->embed($image); $message->setBody('HTML part', 'text/html'); $id = $message->getId(); $date = preg_quote(date('r', $message->getDate()), '~'); $boundary = $message->getBoundary(); $imgId = $image->getId(); $pattern = '~^' . 'Message-ID: <' . $id . '>' . "\r\n" . 'Date: ' . $date . "\r\n" . 'Subject: test subject' . "\r\n" . 'From: user@domain.tld' . "\r\n" . 'To: user@domain.tld' . "\r\n" . 'Cc: other@domain.tld' . "\r\n" . 'MIME-Version: 1.0' . "\r\n" . 'Content-Type: multipart/related;' . "\r\n" . ' boundary="' . $boundary . '"' . "\r\n" . "\r\n\r\n" . '--' . $boundary . "\r\n" . 'Content-Type: text/html; charset=utf-8' . "\r\n" . 'Content-Transfer-Encoding: quoted-printable' . "\r\n" . "\r\n" . 'HTML part' . "\r\n\r\n" . '--' . $boundary . "\r\n" . 'Content-Type: images/gif; name=images.gif' . "\r\n" . 'Content-Transfer-Encoding: base64' . "\r\n" . 'Content-Disposition: inline; filename=images.gif' . "\r\n" . 'Content-ID: <' . preg_quote($imgId, '~') . '>' . "\r\n" . "\r\n" . preg_quote(base64_encode('<data>'), '~') . "\r\n\r\n" . '--' . $boundary . '--' . "\r\n" . '$~D'; $streamA = new Swift_ByteStream_ArrayByteStream(); $streamB = new Swift_ByteStream_ArrayByteStream(); $message->toByteStream($streamA); $message->toByteStream($streamB); $this->assertPatternInStream($pattern, $streamA); $this->assertPatternInStream($pattern, $streamB); }
/** * Embed in-memory data in the message and get the CID. * * @param string $data * @param string $name * @param string $contentType * @return string */ public function embedData($data, $name, $contentType = null) { $image = Swift_Image::newInstance($data, $name, $contentType); return $this->swift->embed($image); }
/** * Send the e-mail * * Friendly name portions (e.g. Admin <*****@*****.**>) are allowed. The * method takes an unlimited number of recipient addresses. * * @return boolean True if the e-mail was sent successfully */ public function sendTo() { $arrRecipients = $this->compileRecipients(func_get_args()); if (empty($arrRecipients)) { return false; } $this->objMessage->setTo($arrRecipients); $this->objMessage->setCharset($this->strCharset); $this->objMessage->setPriority($this->intPriority); // Default subject if ($this->strSubject == '') { $this->strSubject = 'No subject'; } $this->objMessage->setSubject($this->strSubject); // HTML e-mail if ($this->strHtml != '') { // Embed images if ($this->blnEmbedImages) { if ($this->strImageDir == '') { $this->strImageDir = TL_ROOT . '/'; } $arrMatches = array(); preg_match_all('/(src=|url\\()"([^"]+\\.(jpe?g|png|gif|bmp|tiff?|swf))"/Ui', $this->strHtml, $arrMatches); $strBase = \Environment::get('base'); // Check for internal images foreach (array_unique($arrMatches[2]) as $url) { // Try to remove the base URL $src = str_replace($strBase, '', $url); $src = rawurldecode($src); // see #3713 // Embed the image if the URL is now relative if (!preg_match('@^https?://@', $src) && file_exists($this->strImageDir . $src)) { $cid = $this->objMessage->embed(\Swift_EmbeddedFile::fromPath($this->strImageDir . $src)); $this->strHtml = str_replace(array('src="' . $url . '"', 'url("' . $url . '"'), array('src="' . $cid . '"', 'url("' . $cid . '"'), $this->strHtml); } } } $this->objMessage->setBody($this->strHtml, 'text/html'); } // Text content if ($this->strText != '') { if ($this->strHtml != '') { $this->objMessage->addPart($this->strText, 'text/plain'); } else { $this->objMessage->setBody($this->strText, 'text/plain'); } } // Add the administrator e-mail as default sender if ($this->strSender == '') { list($this->strSenderName, $this->strSender) = $this->splitFriendlyName($GLOBALS['TL_CONFIG']['adminEmail']); } // Sender if ($this->strSenderName != '') { $this->objMessage->setFrom(array($this->strSender => $this->strSenderName)); } else { $this->objMessage->setFrom($this->strSender); } // Send e-mail $intSent = self::$objMailer->send($this->objMessage, $this->arrFailures); // Log failures if (!empty($this->arrFailures)) { log_message('E-mail address rejected: ' . implode(', ', $this->arrFailures), $this->strLogFile); } // Return if no e-mails have been sent if ($intSent < 1) { return false; } $arrCc = $this->objMessage->getCc(); $arrBcc = $this->objMessage->getBcc(); // Add a log entry $strMessage = 'An e-mail has been sent to ' . implode(', ', array_keys($this->objMessage->getTo())); if (!empty($arrCc)) { $strMessage .= ', CC to ' . implode(', ', array_keys($arrCc)); } if (!empty($arrBcc)) { $strMessage .= ', BCC to ' . implode(', ', array_keys($arrBcc)); } log_message($strMessage, $this->strLogFile); return true; }
protected function addInlineImagesToMessage(\Swift_Message &$message, $fieldhtml) { $regex = '~data:[^;]+;[A-Za-z0-9]+,[^")\'\\s]+~'; preg_match_all($regex, $fieldhtml, $treffers, PREG_OFFSET_CAPTURE); $treffers = $treffers[0]; foreach ($treffers as $treffer) { $trefferexpl = explode(',', $treffer[0], 2); $data = explode(';', $trefferexpl[0]); $data = explode(':', $data[0]); $mimetype = $data[1]; $decoded = base64_decode($trefferexpl[1]); $image = new \Swift_Image(); $image->setBody($decoded, $mimetype); $cid = $message->embed($image); $fieldhtml = str_replace($treffer[0], $cid, $fieldhtml); } $message->setContentType("text/html")->setBody($fieldhtml, 'text/html'); return true; }
/** * Process inline images. Convert it to embedded attachments and update message body. * * @param \Swift_Message $message * @param EmailModel $model */ protected function processEmbeddedImages(\Swift_Message $message, EmailModel $model) { if ($model->getType() === 'html') { $guesser = ExtensionGuesser::getInstance(); $body = $message->getBody(); $body = preg_replace_callback('/<img(.*)src(\\s*)=(\\s*)["\'](.*)["\']/U', function ($matches) use($message, $guesser, $model) { if (count($matches) === 5) { // 1st match contains any data between '<img' and 'src' parts (e.g. 'width=100') $imgConfig = $matches[1]; // 4th match contains src attribute value $srcData = $matches[4]; if (strpos($srcData, 'data:image') === 0) { list($mime, $content) = explode(';', $srcData); list($encoding, $file) = explode(',', $content); $mime = str_replace('data:', '', $mime); $fileName = sprintf('%s.%s', uniqid(), $guesser->guess($mime)); $swiftAttachment = \Swift_Image::newInstance(ContentDecoder::decode($file, $encoding), $fileName, $mime); /** @var $message \Swift_Message */ $id = $message->embed($swiftAttachment); $attachmentContent = new EmailAttachmentContent(); $attachmentContent->setContent($file); $attachmentContent->setContentTransferEncoding($encoding); $emailAttachment = new EmailAttachment(); $emailAttachment->setEmbeddedContentId($swiftAttachment->getId()); $emailAttachment->setFileName($fileName); $emailAttachment->setContentType($mime); $attachmentContent->setEmailAttachment($emailAttachment); $emailAttachment->setContent($attachmentContent); $emailAttachmentModel = new EmailAttachmentModel(); $emailAttachmentModel->setEmailAttachment($emailAttachment); $model->addAttachment($emailAttachmentModel); return sprintf('<img%ssrc="%s"', $imgConfig, $id); } } }, $body); $message->setBody($body, 'text/html'); } }
/** * {@inheritdoc} */ public function embed(\Swift_Mime_MimeEntity $entity) { return $this->message->embed($entity); }
public function getCidPath(\Swift_Message $message, string $imagePath) : string { $path = $this->kernel->getRootDir() . '/../' . $imagePath; return $message->embed(\Swift_Image::fromPath($path)); }
/** * Process inline images.. * * @param \Swift_Message $m * The message which inline images are to be added to. * @param array $images * The images which are to be added as inline images to the provided * message. */ protected function embed(\Swift_Message $m, array $images) { // Iterate through each array element. foreach ($images as $image) { if ($image instanceof \stdClass) { // Validate required fields. if (empty($image->uri) || empty($image->filename) || empty($image->filemime) || empty($image->cid)) { continue; } // Keep track of the 'cid' assigned to the embedded image. $cid = NULL; // Get image data. if (valid_url($image->uri, TRUE)) { $content = file_get_contents($image->uri); } else { $content = file_get_contents(drupal_realpath($image->uri)); } $filename = $image->filename; $filemime = $image->filemime; // Embed image. $cid = $m->embed(\Swift_Image::newInstance($content, $filename, $filemime)); // The provided 'cid' needs to be replaced with the 'cid' returned // by the Swift Mailer library. $body = $m->getBody(); $body = preg_replace('/cid.*' . $image->cid . '/', $cid, $body); $m->setBody($body); } } }
protected function updateFilePath($file, Swift_Message $message, $templateName) { $id = str_replace('dmFile-', '', $file->id); if (!$id) { $id = $file->getAttribute('data-dm-file-id'); } if (is_numeric($id)) { $mediaRecord = dmDb::table('dmMedia')->findOneByIdWithFolder($id); if ($mediaRecord) { $embed = false; $embedExtensions = array_map('trim', explode(',', dmConfig::get('mail_template_embed_file_types', 'doc,docx,xls,xlsx,ppt,pptx,pdf,mdb'))); foreach ($embedExtensions as $ext) { if (dmString::endsWith($file->href, '.' . $ext, false)) { $embed = true; break; } } if (dmConfig::get('mail_template_embed_local_files_as_attachments', true) && $embed) { try { $file->href = $message->embed(Swift_EmbeddedFile::fromPath(dmOs::join(sfConfig::get('sf_web_dir'), $mediaRecord->getWebPath()))); } catch (Exception $e) { $this->logError($templateName, 'local', 'file', $file->href); $file->href = ''; } } else { if (file_exists(dmOs::join(sfConfig::get('sf_web_dir'), $link = $mediaRecord->getWebPath()))) { $file->href = $this->basePath . '/' . $mediaRecord->getWebPath(); } else { $this->logError($templateName, 'local', 'file', $file->href); $file->href = ''; } } return $file; } } if (dmString::startsWith($file->href, sfConfig::get('sf_root_dir')) || dmString::startsWith($file->href, $this->basePath)) { return $this->updateLocalFilePath($file, $message, $templateName); } else { return $this->updateRemoteFilePath($file, $message, $templateName); } }
/** * Add embedded HTML images (image dir) * * @access protected * @param Swift_Message $message */ protected function add_html_images(&$message) { $path = Config::$email_directory . '/media/'; if (!file_exists($path)) { return; } $html_body = $message->getBody(); if ($handle = opendir($path)) { while (false !== ($file = readdir($handle))) { if (substr($file, 0, 1) != '.' && strpos($html_body, $file) !== false) { $swift_image = \Swift_Image::newInstance(file_get_contents($path . $file), $file, Util::mime_type($path . $file)); $html_body = str_replace($file, $message->embed($swift_image), $html_body); } } } $message->setBody($html_body); closedir($handle); }
public function testEmbeddedFilesWithMultipartDataCreateMultipartRelatedContentAsAnAlternative() { $message = new Swift_Message(); $message->setCharset('utf-8'); $message->setSubject('test subject'); $message->addPart('plain part', 'text/plain'); $image = new Swift_Image('<image data>', 'image.gif', 'image/gif'); $cid = $message->embed($image); $message->setBody('<img src="' . $cid . '" />', 'text/html'); $message->setTo(array('*****@*****.**' => 'User')); $message->setFrom(array('*****@*****.**' => 'Other')); $message->setSender(array('*****@*****.**' => 'Other')); $id = $message->getId(); $date = preg_quote(date('r', $message->getDate()), '~'); $boundary = $message->getBoundary(); $cidVal = $image->getId(); $this->assertRegExp('~^' . 'Sender: Other <*****@*****.**>' . "\r\n" . 'Message-ID: <' . $id . '>' . "\r\n" . 'Date: ' . $date . "\r\n" . 'Subject: test subject' . "\r\n" . 'From: Other <*****@*****.**>' . "\r\n" . 'To: User <*****@*****.**>' . "\r\n" . 'MIME-Version: 1.0' . "\r\n" . 'Content-Type: multipart/alternative;' . "\r\n" . ' boundary="' . $boundary . '"' . "\r\n" . "\r\n\r\n" . '--' . $boundary . "\r\n" . 'Content-Type: text/plain; charset=utf-8' . "\r\n" . 'Content-Transfer-Encoding: quoted-printable' . "\r\n" . "\r\n" . 'plain part' . "\r\n\r\n" . '--' . $boundary . "\r\n" . 'Content-Type: multipart/related;' . "\r\n" . ' boundary="(.*?)"' . "\r\n" . "\r\n\r\n" . '--\\1' . "\r\n" . 'Content-Type: text/html; charset=utf-8' . "\r\n" . 'Content-Transfer-Encoding: quoted-printable' . "\r\n" . "\r\n" . '<img.*?/>' . "\r\n\r\n" . '--\\1' . "\r\n" . 'Content-Type: image/gif; name=image.gif' . "\r\n" . 'Content-Transfer-Encoding: base64' . "\r\n" . 'Content-Disposition: inline; filename=image.gif' . "\r\n" . 'Content-ID: <' . $cidVal . '>' . "\r\n" . "\r\n" . preg_quote(base64_encode('<image data>'), '~') . "\r\n\r\n" . '--\\1--' . "\r\n" . "\r\n\r\n" . '--' . $boundary . '--' . "\r\n" . '$~D', $message->toString()); }
/** * Send the e-mail * * Friendly name portions (e.g. Admin <*****@*****.**>) are allowed. The * method takes an unlimited number of recipient addresses. * * @return boolean True if the e-mail was sent successfully */ public function sendTo() { $arrRecipients = $this->compileRecipients(func_get_args()); if (empty($arrRecipients)) { return false; } $this->objMessage->setTo($arrRecipients); $this->objMessage->setCharset($this->strCharset); $this->objMessage->setPriority($this->intPriority); // Default subject if ($this->strSubject == '') { $this->strSubject = 'No subject'; } $this->objMessage->setSubject($this->strSubject); // HTML e-mail if ($this->strHtml != '') { // Embed images if ($this->blnEmbedImages) { if ($this->strImageDir == '') { $this->strImageDir = TL_ROOT . '/'; } $arrCid = array(); $arrMatches = array(); $strBase = \Environment::get('base'); // Thanks to @ofriedrich and @aschempp (see #4562) preg_match_all('/<[a-z][a-z0-9]*\\b[^>]*((src=|background=|url\\()["\']??)(.+\\.(jpe?g|png|gif|bmp|tiff?|swf))(["\' ]??(\\)??))[^>]*>/Ui', $this->strHtml, $arrMatches); // Check for internal images if (!empty($arrMatches) && isset($arrMatches[0])) { for ($i = 0, $c = count($arrMatches[0]); $i < $c; $i++) { $url = $arrMatches[3][$i]; // Try to remove the base URL $src = str_replace($strBase, '', $url); $src = rawurldecode($src); // see #3713 // Embed the image if the URL is now relative if (!preg_match('@^https?://@', $src) && file_exists($this->strImageDir . $src)) { if (!isset($arrCid[$src])) { $arrCid[$src] = $this->objMessage->embed(\Swift_EmbeddedFile::fromPath($this->strImageDir . $src)); } $this->strHtml = str_replace($arrMatches[1][$i] . $arrMatches[3][$i] . $arrMatches[5][$i], $arrMatches[1][$i] . $arrCid[$src] . $arrMatches[5][$i], $this->strHtml); } } } } $this->objMessage->setBody($this->strHtml, 'text/html'); } // Text content if ($this->strText != '') { if ($this->strHtml != '') { $this->objMessage->addPart($this->strText, 'text/plain'); } else { $this->objMessage->setBody($this->strText, 'text/plain'); } } // Add the administrator e-mail as default sender if ($this->strSender == '') { list($this->strSenderName, $this->strSender) = \String::splitFriendlyEmail(\Config::get('adminEmail')); } // Sender if ($this->strSenderName != '') { $this->objMessage->setFrom(array($this->strSender => $this->strSenderName)); } else { $this->objMessage->setFrom($this->strSender); } // Set the return path (see #5004) $this->objMessage->setReturnPath($this->strSender); // Send e-mail $intSent = self::$objMailer->send($this->objMessage, $this->arrFailures); // Log failures if (!empty($this->arrFailures)) { log_message('E-mail address rejected: ' . implode(', ', $this->arrFailures), $this->strLogFile); } // Return if no e-mails have been sent if ($intSent < 1) { return false; } $arrCc = $this->objMessage->getCc(); $arrBcc = $this->objMessage->getBcc(); // Add a log entry $strMessage = 'An e-mail has been sent to ' . implode(', ', array_keys($this->objMessage->getTo())); if (!empty($arrCc)) { $strMessage .= ', CC to ' . implode(', ', array_keys($arrCc)); } if (!empty($arrBcc)) { $strMessage .= ', BCC to ' . implode(', ', array_keys($arrBcc)); } log_message($strMessage, $this->strLogFile); return true; }