public function indexAction($idHash) { /** @var \Mautic\EmailBundle\Model\EmailModel $model */ $model = $this->factory->getModel('email'); $stat = $model->getEmailStatus($idHash); if (!empty($stat)) { $entity = $stat->getEmail(); $model->hitEmail($stat, $this->request, true); // Check for stored copy $content = $stat->getCopy(); if (!empty($content)) { // Copy stored in stats $tokens = $stat->getTokens(); if (!empty($tokens)) { // Override tracking_pixel so as to not cause a double hit $tokens['{tracking_pixel}'] = MailHelper::getBlankPixel(); $content = str_ireplace(array_keys($tokens), $tokens, $content); } } else { // Old way where stats didn't store content //the lead needs to have fields populated $statLead = $stat->getLead(); $lead = $this->factory->getModel('lead')->getLead($statLead->getId()); $template = $entity->getTemplate(); if (!empty($template)) { $slots = $this->factory->getTheme($template)->getSlots('email'); $response = $this->render('MauticEmailBundle::public.html.php', array('inBrowser' => true, 'slots' => $slots, 'content' => $entity->getContent(), 'email' => $entity, 'lead' => $lead, 'template' => $template)); //replace tokens $content = $response->getContent(); } else { $content = $entity->getCustomHtml(); } $content = EmojiHelper::toEmoji($content, 'short'); $tokens = $stat->getTokens(); // Override tracking_pixel so as to not cause a double hit $tokens['{tracking_pixel}'] = MailHelper::getBlankPixel(); $event = new EmailSendEvent(null, array('content' => $content, 'lead' => $lead, 'email' => $entity, 'idHash' => $idHash, 'tokens' => $tokens)); $this->factory->getDispatcher()->dispatch(EmailEvents::EMAIL_ON_DISPLAY, $event); $content = $event->getContent(true); } $analytics = htmlspecialchars_decode($this->factory->getParameter('google_analytics', '')); // Check for html doc if (strpos($content, '<html>') === false) { $content = "<html>\n<head>{$analytics}</head>\n<body>{$content}</body>\n</html>"; } elseif (strpos($content, '<head>') === false) { $content = str_replace('<html>', "<html>\n<head>\n{$analytics}\n</head>", $content); } elseif (!empty($analytics)) { $content = str_replace('</head>', $analytics . "\n</head>", $content); } return new Response($content); } $this->notFound(); }
public function indexAction($idHash) { /** @var \Mautic\EmailBundle\Model\EmailModel $model */ $model = $this->getModel('email'); $stat = $model->getEmailStatus($idHash); if (!empty($stat)) { if ($this->get('mautic.security')->isAnonymous()) { $model->hitEmail($stat, $this->request, true); } $tokens = $stat->getTokens(); if (is_array($tokens)) { // Override tracking_pixel so as to not cause a double hit $tokens['{tracking_pixel}'] = MailHelper::getBlankPixel(); } if ($copy = $stat->getStoredCopy()) { $subject = $copy->getSubject(); $content = $copy->getBody(); // Convert emoji $content = EmojiHelper::toEmoji($content, 'short'); $subject = EmojiHelper::toEmoji($subject, 'short'); // Replace tokens if (!empty($tokens)) { $content = str_ireplace(array_keys($tokens), $tokens, $content); $subject = str_ireplace(array_keys($tokens), $tokens, $subject); } } else { $subject = ''; $content = ''; } // Add analytics $analytics = $this->factory->getHelper('template.analytics')->getCode(); // Check for html doc if (strpos($content, '<html>') === false) { $content = "<html>\n<head>{$analytics}</head>\n<body>{$content}</body>\n</html>"; } elseif (strpos($content, '<head>') === false) { $content = str_replace('<html>', "<html>\n<head>\n{$analytics}\n</head>", $content); } elseif (!empty($analytics)) { $content = str_replace('</head>', $analytics . "\n</head>", $content); } // Add subject as title if (!empty($subject)) { if (strpos($content, '<title></title>') !== false) { $content = str_replace('<title></title>', "<title>{$subject}</title>", $content); } elseif (strpos($content, '<title>') === false) { $content = str_replace('<head>', "<head>\n<title>{$subject}</title>", $content); } } return new Response($content); } $this->notFound(); }
/** * {@inheritdoc} */ protected function getPayload() { $metadata = $this->getMetadata(); $mauticTokens = $mandrillMergeVars = $mandrillMergePlaceholders = array(); // Mandrill uses *|PLACEHOLDER|* for tokens so Mautic's need to be replaced if (!empty($metadata)) { $metadataSet = reset($metadata); $tokens = !empty($metadataSet['tokens']) ? $metadataSet['tokens'] : array(); $mauticTokens = array_keys($tokens); $mandrillMergeVars = $mandrillMergePlaceholders = array(); foreach ($mauticTokens as $token) { $mandrillMergeVars[$token] = strtoupper(preg_replace("/[^a-z0-9]+/i", "", $token)); $mandrillMergePlaceholders[$token] = '*|' . $mandrillMergeVars[$token] . '|*'; } } $message = $this->messageToArray($mauticTokens, $mandrillMergePlaceholders, true); // Not used ATM unset($message['headers']); $message['from_email'] = $message['from']['email']; $message['from_name'] = $message['from']['name']; unset($message['from']); if (!empty($metadata)) { // Mandrill will only send a single email to cc and bcc of the first set of tokens // so we have to manually set them as to addresses // Problem is that it's not easy to know what email is sent so will tack it at the top $insertCcEmailHeader = true; $message['html'] = '*|HTMLCCEMAILHEADER|*' . $message['html']; if (!empty($message['text'])) { $message['text'] = '*|TEXTCCEMAILHEADER|*' . $message['text']; } // Do not expose all the emails in the if using metadata $message['preserve_recipients'] = false; $bcc = $message['recipients']['bcc']; $cc = $message['recipients']['cc']; // Unset the cc and bcc as they will need to be sent as To with each set of tokens unset($message['recipients']['bcc'], $message['recipients']['cc']); } // Generate the recipients $recipients = $rcptMergeVars = $rcptMetadata = array(); $translator = $this->factory->getTranslator(); foreach ($message['recipients'] as $type => $typeRecipients) { foreach ($typeRecipients as $rcpt) { $rcpt['type'] = $type; $recipients[] = $rcpt; if ($type == 'to' && isset($metadata[$rcpt['email']])) { if (!empty($metadata[$rcpt['email']]['tokens'])) { $mergeVars = array('rcpt' => $rcpt['email'], 'vars' => array()); // This must not be included for CC and BCCs $trackingPixelToken = array(); foreach ($metadata[$rcpt['email']]['tokens'] as $token => $value) { if ($token == '{tracking_pixel}') { $trackingPixelToken = array(array('name' => $mandrillMergeVars[$token], 'content' => $value)); continue; } $mergeVars['vars'][] = array('name' => $mandrillMergeVars[$token], 'content' => $value); } if (!empty($insertCcEmailHeader)) { // Make a copy before inserted the blank tokens $ccMergeVars = $mergeVars; $mergeVars['vars'] = array_merge($mergeVars['vars'], $trackingPixelToken, array(array('name' => 'HTMLCCEMAILHEADER', 'content' => ''), array('name' => 'TEXTCCEMAILHEADER', 'content' => ''))); } else { // Just merge the tracking pixel tokens $mergeVars['vars'] = array_merge($mergeVars['vars'], $trackingPixelToken); } // Add the vars $rcptMergeVars[] = $mergeVars; // Special handling of CC and BCC with tokens if (!empty($cc) || !empty($bcc)) { $ccMergeVars['vars'] = array_merge($ccMergeVars['vars'], array(array('name' => 'HTMLCCEMAILHEADER', 'content' => $translator->trans('mautic.core.email.cc.copy', array('%email%' => $rcpt['email'])) . "<br /><br />"), array('name' => 'TEXTCCEMAILHEADER', 'content' => $translator->trans('mautic.core.email.cc.copy', array('%email%' => $rcpt['email'])) . "\n\n"), array('name' => 'TRACKINGPIXEL', 'content' => MailHelper::getBlankPixel()))); // If CC and BCC, remove the ct from URLs to prevent false lead tracking foreach ($ccMergeVars['vars'] as &$var) { if (strpos($var['content'], 'http') !== false && ($ctPos = strpos($var['content'], 'ct=') !== false)) { // URL so make sure a ct query is not part of it $var['content'] = substr($var['content'], 0, $ctPos); } } // Send same tokens to each CC if (!empty($cc)) { foreach ($cc as $ccRcpt) { $recipients[] = $ccRcpt; $ccMergeVars['rcpt'] = $ccRcpt['email']; $rcptMergeVars[] = $ccMergeVars; } } // And same to BCC if (!empty($bcc)) { foreach ($bcc as $ccRcpt) { $recipients[] = $ccRcpt; $ccMergeVars['rcpt'] = $ccRcpt['email']; $rcptMergeVars[] = $ccMergeVars; } } } unset($ccMergeVars, $mergeVars, $metadata[$rcpt['email']]['tokens']); } if (!empty($metadata[$rcpt['email']])) { $rcptMetadata[] = array('rcpt' => $rcpt['email'], 'values' => $metadata[$rcpt['email']]); unset($metadata[$rcpt['email']]); } } } } $message['to'] = $recipients; unset($message['recipients']); // Set the merge vars $message['merge_vars'] = $rcptMergeVars; // Set the rest of $metadata as recipient_metadata $message['recipient_metadata'] = $rcptMetadata; // Set the reply to if (!empty($message['replyTo'])) { $message['headers']['Reply-To'] = $message['replyTo']['email']; } unset($message['replyTo']); // Package it up $payload = json_encode(array('key' => $this->getPassword(), 'message' => $message)); return $payload; }
public function indexAction($idHash) { /** @var \Mautic\EmailBundle\Model\EmailModel $model */ $model = $this->factory->getModel('email'); $stat = $model->getEmailStatus($idHash); if (!empty($stat)) { $emailEntity = $stat->getEmail(); if ($this->factory->getSecurity()->isAnonymous()) { $model->hitEmail($stat, $this->request, true); } $tokens = $stat->getTokens(); if (is_array($tokens)) { // Override tracking_pixel so as to not cause a double hit $tokens['{tracking_pixel}'] = MailHelper::getBlankPixel(); } // Check for stored copy $copy = $stat->getStoredCopy(); if (null === $copy) { /** * @deprecated - to be removed in 2.0 */ $subject = ''; $content = $stat->getCopy(); if (empty($content) && null !== $emailEntity) { // Old way where stats didn't store content //the lead needs to have fields populated $statLead = $stat->getLead(); $lead = $this->factory->getModel('lead')->getLead($statLead->getId()); $template = $emailEntity->getTemplate(); if (!empty($template)) { $slots = $this->factory->getTheme($template)->getSlots('email'); $assetsHelper = $this->factory->getHelper('template.assets'); $assetsHelper->addCustomDeclaration('<meta name="robots" content="noindex">'); $this->processSlots($slots, $emailEntity); $logicalName = $this->factory->getHelper('theme')->checkForTwigTemplate(':' . $template . ':email.html.php'); $response = $this->render($logicalName, array('inBrowser' => true, 'slots' => $slots, 'content' => $emailEntity->getContent(), 'email' => $emailEntity, 'lead' => $lead, 'template' => $template)); $content = $response->getContent(); } else { $content = $emailEntity->getCustomHtml(); } $event = new EmailSendEvent(null, array('content' => $content, 'lead' => $lead, 'email' => $emailEntity, 'idHash' => $idHash, 'tokens' => $tokens)); $this->factory->getDispatcher()->dispatch(EmailEvents::EMAIL_ON_DISPLAY, $event); $content = $event->getContent(); } } else { $subject = $copy->getSubject(); $content = $copy->getBody(); } // Convert emoji $content = EmojiHelper::toEmoji($content, 'short'); $subject = EmojiHelper::toEmoji($subject, 'short'); // Replace tokens if (!empty($tokens)) { $content = str_ireplace(array_keys($tokens), $tokens, $content); $subject = str_ireplace(array_keys($tokens), $tokens, $subject); } // Add analytics $analytics = $this->factory->getHelper('template.analytics')->getCode(); // Check for html doc if (strpos($content, '<html>') === false) { $content = "<html>\n<head>{$analytics}</head>\n<body>{$content}</body>\n</html>"; } elseif (strpos($content, '<head>') === false) { $content = str_replace('<html>', "<html>\n<head>\n{$analytics}\n</head>", $content); } elseif (!empty($analytics)) { $content = str_replace('</head>', $analytics . "\n</head>", $content); } // Add subject as title if (!empty($subject)) { if (strpos($content, '<title></title>') !== false) { $content = str_replace('<title></title>', "<title>{$subject}</title>", $content); } elseif (strpos($content, '<title>') === false) { $content = str_replace('<head>', "<head>\n<title>{$subject}</title>", $content); } } return new Response($content); } $this->notFound(); }