Example #1
0
 /**
  * Get the content hash to note if the content has been changed
  *
  * @return string
  */
 public function getContentHash()
 {
     if (null !== $this->helper) {
         return $this->helper->getContentHash();
     } else {
         return md5($this->getContent() . $this->getPlainText());
     }
 }
Example #2
0
 /**
  * Returns MailHelper wrapper for Swift_Message via $helper->message
  *
  * @param bool $cleanSlate False to preserve current settings, i.e. to process batched emails
  *
  * @return MailHelper
  */
 public function getMailer($cleanSlate = true)
 {
     if ($this->mailHelper == null) {
         $this->mailHelper = new MailHelper($this, $this->container->get('mailer'), array($this->getParameter('mailer_from_email') => $this->getParameter('mailer_from_name')));
     } else {
         $this->mailHelper->reset($cleanSlate);
     }
     return $this->mailHelper;
 }
 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();
 }
Example #4
0
 /**
  * Creates Hubspot lead.
  *
  * @param array $data
  *
  * @return mixed
  */
 public function createLead(array $data)
 {
     /*
      * As Hubspot integration requires a valid email
      * If the email is not valid we don't proceed with the request
      */
     $email = $data['email'];
     //Check if the is a valid email
     MailHelper::validateEmail($email);
     //Format data for request
     $formattedLeadData = $this->integration->formatLeadDataForCreateOrUpdate($data);
     return $this->request('v1/contact/createOrUpdate/email/' . $email, $formattedLeadData, 'POST');
 }
Example #5
0
 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();
 }
Example #6
0
 /**
  * @param User $user
  */
 public function sendResetEmail(User $user)
 {
     $mailer = $this->mailHelper->getMailer();
     $resetToken = $this->getResetToken($user);
     $resetLink = $this->router->generate('mautic_user_passwordresetconfirm', ['token' => $resetToken], true);
     $mailer->setTo([$user->getEmail() => $user->getName()]);
     $mailer->setSubject($this->translator->trans('mautic.user.user.passwordreset.subject'));
     $text = $this->translator->trans('mautic.user.user.passwordreset.email.body', ['%name%' => $user->getFirstName(), '%resetlink%' => '<a href="' . $resetLink . '">' . $resetLink . '</a>']);
     $text = str_replace('\\n', "\n", $text);
     $html = nl2br($text);
     $mailer->setBody($html);
     $mailer->setPlainText(strip_tags($text));
     $mailer->send();
 }
Example #7
0
 /**
  * @param Events\SubmissionEvent $event
  */
 public function onFormSubmitActionRepost(Events\SubmissionEvent $event)
 {
     if (!$event->checkContext('form.repost')) {
         return;
     }
     $post = $event->getPost();
     $results = $event->getResults();
     $config = $event->getActionConfig();
     $fields = $event->getFields();
     $lead = $event->getSubmission()->getLead();
     $matchedFields = [];
     $payload = ['mautic_contact' => $lead->getProfileFields(), 'mautic_form' => ['id' => $post['formId'], 'name' => $post['formName'], 'url' => $post['return']]];
     $fieldTypes = [];
     foreach ($fields as $field) {
         $fieldTypes[$field['alias']] = $field['type'];
         if (!isset($post[$field['alias']]) || 'button' == $field['type']) {
             continue;
         }
         $key = !empty($config[$field['alias']]) ? $config[$field['alias']] : $field['alias'];
         // Use the cleaned value by default - but if set to not save result, get from post
         $value = isset($results[$field['alias']]) ? $results[$field['alias']] : $post[$field['alias']];
         $matchedFields[$key] = $field['alias'];
         $payload[$key] = $value;
     }
     $headers = ['X-Forwarded-For' => $event->getSubmission()->getIpAddress()->getIpAddress()];
     if (!empty($config['authorization_header'])) {
         if (strpos($config['authorization_header'], ':') !== false) {
             list($key, $value) = explode(':', $config['authorization_header']);
         } else {
             $key = 'Authorization';
             $value = $config['authorization_header'];
         }
         $headers[trim($key)] = trim($value);
     }
     try {
         $client = new Client(['timeout' => 15]);
         $response = $client->post($config['post_url'], ['form_params' => $payload, 'headers' => $headers]);
         if ($redirect = $this->parseResponse($response, $matchedFields)) {
             $event->setPostSubmitCallbackResponse('form.repost', new RedirectResponse($redirect));
         }
     } catch (ServerException $exception) {
         $this->parseResponse($exception->getResponse(), $matchedFields);
     } catch (\Exception $exception) {
         if ($exception instanceof ValidationException) {
             if ($violations = $exception->getViolations()) {
                 throw $exception;
             }
         }
         $email = $config['failure_email'];
         // Failed so send email if applicable
         if (!empty($email)) {
             // Remove Mautic values and password fields
             foreach ($post as $key => $value) {
                 if (in_array($key, ['messenger', 'submit', 'formId', 'formid', 'formName', 'return'])) {
                     unset($post[$key]);
                 }
                 if (isset($fieldTypes[$key]) && in_array($fieldTypes[$key], ['password'])) {
                     $post[$key] = '*********';
                 }
             }
             $post['mautic_contact'] = array_filter($payload['mautic_contact']);
             $post['mautic_form'] = $payload['mautic_form'];
             $results = $this->postToHtml($post);
             $submission = $event->getSubmission();
             $emails = $emails = $this->getEmailsFromString($email);
             $this->mailer->setTo($emails);
             $this->mailer->setSubject($this->translator->trans('mautic.form.action.repost.failed_subject', ['%form%' => $submission->getForm()->getName()]));
             $this->mailer->setBody($this->translator->trans('mautic.form.action.repost.failed_message', ['%link%' => $this->router->generate('mautic_form_results', ['objectId' => $submission->getForm()->getId(), 'result' => $submission->getId()], UrlGeneratorInterface::ABSOLUTE_URL), '%message%' => $exception->getMessage(), '%results%' => $results]));
             $this->mailer->parsePlainText();
             $this->mailer->send();
         }
     }
 }
 /**
  * {@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;
 }
 /**
  * Converts \Swift_Message into associative array.
  *
  * @param array      $search            If the mailer requires tokens in another format than Mautic's, pass array of Mautic tokens to replace
  * @param array      $replace           If the mailer requires tokens in another format than Mautic's, pass array of replacement tokens
  * @param bool|false $binaryAttachments True to convert file attachments to binary
  *
  * @return array|\Swift_Message
  */
 protected function messageToArray($search = [], $replace = [], $binaryAttachments = false)
 {
     if (!empty($search)) {
         MailHelper::searchReplaceTokens($search, $replace, $this->message);
     }
     $from = $this->message->getFrom();
     $fromEmail = current(array_keys($from));
     $fromName = $from[$fromEmail];
     $message = ['html' => $this->message->getBody(), 'text' => MailHelper::getPlainTextFromMessage($this->message), 'subject' => $this->message->getSubject(), 'from' => ['name' => $fromName, 'email' => $fromEmail]];
     // Generate the recipients
     $message['recipients'] = ['to' => [], 'cc' => [], 'bcc' => []];
     $to = $this->message->getTo();
     foreach ($to as $email => $name) {
         $message['recipients']['to'][$email] = ['email' => $email, 'name' => $name];
     }
     $cc = $this->message->getCc();
     if (!empty($cc)) {
         foreach ($cc as $email => $name) {
             $message['recipients']['cc'][$email] = ['email' => $email, 'name' => $name];
         }
     }
     $bcc = $this->message->getBcc();
     if (!empty($bcc)) {
         foreach ($bcc as $email => $name) {
             $message['recipients']['bcc'][$email] = ['email' => $email, 'name' => $name];
         }
     }
     $replyTo = $this->message->getReplyTo();
     if (!empty($replyTo)) {
         foreach ($replyTo as $email => $name) {
             $message['replyTo'] = ['email' => $email, 'name' => $name];
         }
     }
     $returnPath = $this->message->getReturnPath();
     if (!empty($returnPath)) {
         $message['returnPath'] = $returnPath;
     }
     // Attachments
     $children = $this->message->getChildren();
     $attachments = [];
     foreach ($children as $child) {
         if ($child instanceof \Swift_Attachment) {
             $attachments[] = ['type' => $child->getContentType(), 'name' => $child->getFilename(), 'content' => $child->getEncoder()->encodeString($child->getBody())];
         }
     }
     if ($binaryAttachments) {
         // Convert attachments to binary if applicable
         $message['attachments'] = $attachments;
         $fileAttachments = $this->getAttachments();
         if (!empty($fileAttachments)) {
             foreach ($fileAttachments as $attachment) {
                 if (file_exists($attachment['filePath']) && is_readable($attachment['filePath'])) {
                     try {
                         $swiftAttachment = \Swift_Attachment::fromPath($attachment['filePath']);
                         if (!empty($attachment['fileName'])) {
                             $swiftAttachment->setFilename($attachment['fileName']);
                         }
                         if (!empty($attachment['contentType'])) {
                             $swiftAttachment->setContentType($attachment['contentType']);
                         }
                         if (!empty($attachment['inline'])) {
                             $swiftAttachment->setDisposition('inline');
                         }
                         $message['attachments'][] = ['type' => $swiftAttachment->getContentType(), 'name' => $swiftAttachment->getFilename(), 'content' => $swiftAttachment->getEncoder()->encodeString($swiftAttachment->getBody())];
                     } catch (\Exception $e) {
                         error_log($e);
                     }
                 }
             }
         }
     } else {
         $message['binary_attachments'] = $attachments;
         $message['file_attachments'] = $this->getAttachments();
     }
     $message['headers'] = [];
     $headers = $this->message->getHeaders()->getAll();
     /** @var \Swift_Mime_Header $header */
     foreach ($headers as $header) {
         if ($header->getFieldType() == \Swift_Mime_Header::TYPE_TEXT) {
             $message['headers'][$header->getFieldName()] = $header->getFieldBodyModel();
         }
     }
     return $message;
 }
Example #10
0
 /**
  * Send an email to lead(s)
  *
  * @param       $email
  * @param       $users
  * @param mixed $lead
  * @param array $tokens
  * @param array $assetAttachments
  * @param bool  $saveStat
  *
  * @return mixed
  * @throws \Doctrine\ORM\ORMException
  */
 public function sendEmailToUser($email, $users, $lead = null, $tokens = [], $assetAttachments = [], $saveStat = true)
 {
     if (!($emailId = $email->getId())) {
         return false;
     }
     if (!is_array($users)) {
         $user = ['id' => $users];
         $users = [$user];
     }
     //get email settings
     $emailSettings =& $this->getEmailSettings($email, false);
     //noone to send to so bail
     if (empty($users)) {
         return false;
     }
     $mailer = $this->mailHelper->getMailer();
     $mailer->setLead($lead, true);
     $mailer->setTokens($tokens);
     $mailer->setEmail($email, false, $emailSettings[$emailId]['slots'], $assetAttachments, !$saveStat);
     $errors = [];
     foreach ($users as $user) {
         $idHash = uniqid();
         $mailer->setIdHash($idHash);
         if (!is_array($user)) {
             $id = $user;
             $user = ['id' => $id];
         } else {
             $id = $user['id'];
         }
         if (!isset($user['email'])) {
             $userEntity = $this->userModel->getEntity($id);
             $user['email'] = $userEntity->getEmail();
             $user['firstname'] = $userEntity->getFirstName();
             $user['lastname'] = $userEntity->getLastName();
         }
         if (!$mailer->setTo($user['email'], $user['firstname'] . ' ' . $user['lastname'])) {
             $errors[] = "{$user['email']}: " . $this->translator->trans('mautic.email.bounce.reason.bad_email');
         } else {
             if (!$mailer->queue(true)) {
                 $errorArray = $mailer->getErrors();
                 unset($errorArray['failures']);
                 $errors[] = "{$user['email']}: " . implode('; ', $errorArray);
             }
             if ($saveStat) {
                 $saveEntities[] = $mailer->createEmailStat(false, $user['email']);
             }
         }
     }
     //flush the message
     if (!$mailer->flushQueue()) {
         $errorArray = $mailer->getErrors();
         unset($errorArray['failures']);
         $errors[] = implode('; ', $errorArray);
     }
     if (isset($saveEntities)) {
         $this->getStatRepository()->saveEntities($saveEntities);
     }
     //save some memory
     unset($mailer);
     return $errors;
 }
Example #11
0
 /**
  * @param      $fields
  * @param      $data
  * @param null $owner
  * @param null $list
  * @param null $tags
  * @param bool $persist Persist to the database; otherwise return entity
  *
  * @return bool
  * @throws \Doctrine\ORM\ORMException
  * @throws \Swift_RfcComplianceException
  */
 public function importLead($fields, $data, $owner = null, $list = null, $tags = null, $persist = true)
 {
     // Let's check for an existing lead by email
     $hasEmail = !empty($fields['email']) && !empty($data[$fields['email']]);
     if ($hasEmail) {
         // Validate the email
         MailHelper::validateEmail($data[$fields['email']]);
         $leadFound = $this->getRepository()->getLeadByEmail($data[$fields['email']]);
         $lead = $leadFound ? $this->em->getReference('MauticLeadBundle:Lead', $leadFound['id']) : new Lead();
         $merged = $leadFound;
     } else {
         $lead = new Lead();
         $merged = false;
     }
     if (!empty($fields['dateAdded']) && !empty($data[$fields['dateAdded']])) {
         $dateAdded = new DateTimeHelper($data[$fields['dateAdded']]);
         $lead->setDateAdded($dateAdded->getUtcDateTime());
     }
     unset($fields['dateAdded']);
     if (!empty($fields['dateModified']) && !empty($data[$fields['dateModified']])) {
         $dateModified = new DateTimeHelper($data[$fields['dateModified']]);
         $lead->setDateModified($dateModified->getUtcDateTime());
     }
     unset($fields['dateModified']);
     if (!empty($fields['lastActive']) && !empty($data[$fields['lastActive']])) {
         $lastActive = new DateTimeHelper($data[$fields['lastActive']]);
         $lead->setLastActive($lastActive->getUtcDateTime());
     }
     unset($fields['lastActive']);
     if (!empty($fields['dateIdentified']) && !empty($data[$fields['dateIdentified']])) {
         $dateIdentified = new DateTimeHelper($data[$fields['dateIdentified']]);
         $lead->setDateIdentified($dateIdentified->getUtcDateTime());
     }
     unset($fields['dateIdentified']);
     if (!empty($fields['createdByUser']) && !empty($data[$fields['createdByUser']])) {
         $userRepo = $this->em->getRepository('MauticUserBundle:User');
         $createdByUser = $userRepo->findByIdentifier($data[$fields['createdByUser']]);
         if ($createdByUser !== null) {
             $lead->setCreatedBy($createdByUser);
         }
     }
     unset($fields['createdByUser']);
     if (!empty($fields['modifiedByUser']) && !empty($data[$fields['modifiedByUser']])) {
         $userRepo = $this->em->getRepository('MauticUserBundle:User');
         $modifiedByUser = $userRepo->findByIdentifier($data[$fields['modifiedByUser']]);
         if ($modifiedByUser !== null) {
             $lead->setModifiedBy($modifiedByUser);
         }
     }
     unset($fields['modifiedByUser']);
     if (!empty($fields['ip']) && !empty($data[$fields['ip']])) {
         $addresses = explode(',', $data[$fields['ip']]);
         foreach ($addresses as $address) {
             $ipAddress = new IpAddress();
             $ipAddress->setIpAddress(trim($address));
             $lead->addIpAddress($ipAddress);
         }
     }
     unset($fields['ip']);
     if (!empty($fields['points']) && !empty($data[$fields['points']]) && $lead->getId() === null) {
         // Add points only for new leads
         $lead->setPoints($data[$fields['points']]);
         //add a lead point change log
         $log = new PointsChangeLog();
         $log->setDelta($data[$fields['points']]);
         $log->setLead($lead);
         $log->setType('lead');
         $log->setEventName($this->factory->getTranslator()->trans('mautic.lead.import.event.name'));
         $log->setActionName($this->factory->getTranslator()->trans('mautic.lead.import.action.name', array('%name%' => $this->factory->getUser()->getUsername())));
         $log->setIpAddress($this->factory->getIpAddress());
         $log->setDateAdded(new \DateTime());
         $lead->addPointsChangeLog($log);
     }
     unset($fields['points']);
     // Set unsubscribe status
     if (!empty($fields['doNotEmail']) && !empty($data[$fields['doNotEmail']]) && $hasEmail) {
         $doNotEmail = filter_var($data[$fields['doNotEmail']], FILTER_VALIDATE_BOOLEAN);
         if ($doNotEmail) {
             $reason = $this->factory->getTranslator()->trans('mautic.lead.import.by.user', array("%user%" => $this->factory->getUser()->getUsername()));
             // The email must be set for successful unsubscribtion
             $lead->addUpdatedField('email', $data[$fields['email']]);
             $this->unsubscribeLead($lead, $reason, false);
         }
     }
     unset($fields['doNotEmail']);
     if ($owner !== null) {
         $lead->setOwner($this->em->getReference('MauticUserBundle:User', $owner));
     }
     if ($tags !== null) {
         $this->modifyTags($lead, $tags, null, false);
     }
     // Set profile data
     foreach ($fields as $leadField => $importField) {
         // Prevent overwriting existing data with empty data
         if (array_key_exists($importField, $data) && !is_null($data[$importField]) && $data[$importField] != '') {
             $lead->addUpdatedField($leadField, $data[$importField]);
         }
     }
     $lead->imported = true;
     if ($persist) {
         $this->saveEntity($lead);
         if ($list !== null) {
             $this->addToLists($lead, array($list));
         }
     }
     return $merged;
 }
Example #12
0
 /**
  * @return array
  */
 public function getTextHeaders()
 {
     return $this->helper !== null ? $this->helper->getCustomHeaders() : $this->headers;
 }
Example #13
0
 /**
  * @param      $fields
  * @param      $data
  * @param null $owner
  * @param null $list
  * @param null $tags
  * @param bool $persist Persist to the database; otherwise return entity
  *
  * @return bool
  * @throws \Doctrine\ORM\ORMException
  * @throws \Swift_RfcComplianceException
  */
 public function importLead($fields, $data, $owner = null, $list = null, $tags = null, $persist = true)
 {
     // Let's check for an existing lead by email
     $hasEmail = !empty($fields['email']) && !empty($data[$fields['email']]);
     if ($hasEmail) {
         // Validate the email
         MailHelper::validateEmail($data[$fields['email']]);
         $leadFound = $this->getRepository()->getLeadByEmail($data[$fields['email']]);
         $lead = $leadFound ? $this->em->getReference('MauticLeadBundle:Lead', $leadFound['id']) : new Lead();
         $merged = $leadFound;
     } else {
         $lead = new Lead();
         $merged = false;
     }
     if (!empty($fields['dateAdded']) && !empty($data[$fields['dateAdded']])) {
         $dateAdded = new DateTimeHelper($data[$fields['dateAdded']]);
         $lead->setDateAdded($dateAdded->getUtcDateTime());
     }
     unset($fields['dateAdded']);
     if (!empty($fields['dateModified']) && !empty($data[$fields['dateModified']])) {
         $dateModified = new DateTimeHelper($data[$fields['dateModified']]);
         $lead->setDateModified($dateModified->getUtcDateTime());
     }
     unset($fields['dateModified']);
     if (!empty($fields['lastActive']) && !empty($data[$fields['lastActive']])) {
         $lastActive = new DateTimeHelper($data[$fields['lastActive']]);
         $lead->setLastActive($lastActive->getUtcDateTime());
     }
     unset($fields['lastActive']);
     if (!empty($fields['dateIdentified']) && !empty($data[$fields['dateIdentified']])) {
         $dateIdentified = new DateTimeHelper($data[$fields['dateIdentified']]);
         $lead->setDateIdentified($dateIdentified->getUtcDateTime());
     }
     unset($fields['dateIdentified']);
     if (!empty($fields['createdByUser']) && !empty($data[$fields['createdByUser']])) {
         $userRepo = $this->em->getRepository('MauticUserBundle:User');
         $createdByUser = $userRepo->findByIdentifier($data[$fields['createdByUser']]);
         if ($createdByUser !== null) {
             $lead->setCreatedBy($createdByUser);
         }
     }
     unset($fields['createdByUser']);
     if (!empty($fields['modifiedByUser']) && !empty($data[$fields['modifiedByUser']])) {
         $userRepo = $this->em->getRepository('MauticUserBundle:User');
         $modifiedByUser = $userRepo->findByIdentifier($data[$fields['modifiedByUser']]);
         if ($modifiedByUser !== null) {
             $lead->setModifiedBy($modifiedByUser);
         }
     }
     unset($fields['modifiedByUser']);
     if (!empty($fields['ip']) && !empty($data[$fields['ip']])) {
         $addresses = explode(',', $data[$fields['ip']]);
         foreach ($addresses as $address) {
             $ipAddress = new IpAddress();
             $ipAddress->setIpAddress(trim($address));
             $lead->addIpAddress($ipAddress);
         }
     }
     unset($fields['ip']);
     if (!empty($fields['points']) && !empty($data[$fields['points']]) && $lead->getId() === null) {
         // Add points only for new leads
         $lead->setPoints($data[$fields['points']]);
         //add a lead point change log
         $log = new PointsChangeLog();
         $log->setDelta($data[$fields['points']]);
         $log->setLead($lead);
         $log->setType('lead');
         $log->setEventName($this->translator->trans('mautic.lead.import.event.name'));
         $log->setActionName($this->translator->trans('mautic.lead.import.action.name', array('%name%' => $this->user->getUsername())));
         $log->setIpAddress($this->ipLookupHelper->getIpAddress());
         $log->setDateAdded(new \DateTime());
         $lead->addPointsChangeLog($log);
     }
     if (!empty($fields['stage']) && !empty($data[$fields['stage']])) {
         static $stages = [];
         $stageName = $data[$fields['stage']];
         if (!array_key_exists($stageName, $stages)) {
             // Set stage for contact
             $stage = $this->em->getRepository('MauticStageBundle:Stage')->getStageByName($stageName);
             if (empty($stage)) {
                 $stage = new Stage();
                 $stage->setName($stageName);
                 $stages[$stageName] = $stage;
             }
         } else {
             $stage = $stages[$stageName];
         }
         $lead->setStage($stage);
         //add a contact stage change log
         $log = new StagesChangeLog();
         $log->setEventName($stage->getId() . ":" . $stage->getName());
         $log->setLead($lead);
         $log->setActionName($this->translator->trans('mautic.lead.import.action.name', ['%name%' => $this->user->getUsername()]));
         $log->setDateAdded(new \DateTime());
         $lead->stageChangeLog($log);
     }
     unset($fields['stage']);
     // Set unsubscribe status
     if (!empty($fields['doNotEmail']) && !empty($data[$fields['doNotEmail']]) && $hasEmail) {
         $doNotEmail = filter_var($data[$fields['doNotEmail']], FILTER_VALIDATE_BOOLEAN);
         if ($doNotEmail) {
             $reason = $this->translator->trans('mautic.lead.import.by.user', array("%user%" => $this->user->getUsername()));
             // The email must be set for successful unsubscribtion
             $lead->addUpdatedField('email', $data[$fields['email']]);
             $this->addDncForLead($lead, 'email', $reason, DoNotContact::MANUAL);
         }
     }
     unset($fields['doNotEmail']);
     if ($owner !== null) {
         $lead->setOwner($this->em->getReference('MauticUserBundle:User', $owner));
     }
     if ($tags !== null) {
         $this->modifyTags($lead, $tags, null, false);
     }
     // Set profile data using the form so that values are validated
     $fieldData = [];
     foreach ($fields as $leadField => $importField) {
         // Prevent overwriting existing data with empty data
         if (array_key_exists($importField, $data) && !is_null($data[$importField]) && $data[$importField] != '') {
             $fieldData[$leadField] = $data[$importField];
         }
     }
     static $leadFields;
     if (null === $leadFields) {
         $leadFields = $this->leadFieldModel->getEntities(array('force' => array(array('column' => 'f.isPublished', 'expr' => 'eq', 'value' => true)), 'hydration_mode' => 'HYDRATE_ARRAY'));
     }
     $form = $this->createForm($lead, $this->formFactory, null, ['fields' => $leadFields, 'csrf_protection' => false]);
     // Unset stage and owner from the form because it's already been handled
     unset($form['stage'], $form['owner']);
     $form->submit($fieldData);
     if (!$form->isValid()) {
         $fieldErrors = [];
         foreach ($form as $formField) {
             $errors = $formField->getErrors(true);
             if (count($errors)) {
                 $errorString = $formField->getConfig()->getOption('label') . ": ";
                 foreach ($errors as $error) {
                     $errorString .= " {$error->getMessage()}";
                 }
                 $fieldErrors[] = $errorString;
             }
         }
         $fieldErrors = implode("\n", $fieldErrors);
         throw new \Exception($fieldErrors);
     } else {
         // All clear
         foreach ($fieldData as $field => $value) {
             $lead->addUpdatedField($field, $value);
         }
     }
     $lead->imported = true;
     if ($persist) {
         $this->saveEntity($lead);
         if ($list !== null) {
             $this->addToLists($lead, array($list));
         }
     }
     return $merged;
 }
Example #14
0
 /**
  * Sends the email to a specific lead
  *
  * @param int $id     Email ID
  * @param int $leadId Lead ID
  *
  * @return \Symfony\Component\HttpFoundation\Response
  * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
  */
 public function sendLeadAction($id, $leadId)
 {
     $entity = $this->model->getEntity($id);
     if (null !== $entity) {
         if (!$this->checkEntityAccess($entity, 'view')) {
             return $this->accessDenied();
         }
         $leadModel = $this->getModel('lead');
         $lead = $leadModel->getEntity($leadId);
         if ($lead == null) {
             return $this->notFound();
         } elseif (!$this->security->hasEntityAccess('lead:leads:viewown', 'lead:leads:viewother', $lead->getOwner())) {
             return $this->accessDenied();
         }
         $post = $this->request->request->all();
         $tokens = !empty($post['tokens']) ? $post['tokens'] : array();
         $cleantokens = array_map(function ($v) {
             return InputHelper::clean($v);
         }, $tokens);
         $leadFields = array_merge(array('id' => $leadId), $leadModel->flattenFields($lead->getFields()));
         if (MailHelper::applyFrequencyRules($lead)) {
             $this->model->sendEmail($entity, $leadFields, array('source' => array('api', 0), 'tokens' => $cleantokens));
         }
         $view = $this->view(array('success' => 1), Codes::HTTP_OK);
         return $this->handleView($view);
     }
     return $this->notFound();
 }
Example #15
0
 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();
 }