/** * Trigger point actions for page hits. * * @param Events\PageHitEvent $event */ public function onPageHit(Events\PageHitEvent $event) { $hit = $event->getHit(); $redirect = $hit->getRedirect(); if ($redirect && ($email = $hit->getEmail())) { // Check for an email stat $clickthrough = $event->getClickthroughData(); if (isset($clickthrough['stat'])) { $stat = $this->emailModel->getEmailStatus($clickthrough['stat']); } if (empty($stat)) { if ($lead = $hit->getLead()) { // Try searching by email and lead IDs $stats = $this->emailModel->getEmailStati($hit->getSourceId(), $lead->getId()); if (count($stats)) { $stat = $stats[0]; } } } if (!empty($stat)) { // Check to see if it has been marked as opened if (!$stat->isRead()) { // Mark it as read $this->emailModel->hitEmail($stat, $this->request); } } } }
/** * @param CampaignExecutionEvent $event */ public function onCampaignTriggerAction(CampaignExecutionEvent $event) { $emailSent = false; $lead = $event->getLead(); $leadCredentials = $lead instanceof Lead ? $lead->getProfileFields() : $lead; $leadCredentials['owner_id'] = $lead instanceof Lead && ($owner = $lead->getOwner()) ? $owner->getId() : 0; if (!empty($leadCredentials['email'])) { $config = $event->getConfig(); $emailId = (int) $config['email']; $email = $this->emailModel->getEntity($emailId); if ($email != null && $email->isPublished()) { // Determine if this email is transactional/marketing $type = isset($config['email_type']) ? $config['email_type'] : 'transactional'; if ('marketing' == $type) { // Determine if this lead has received the email before $stats = $this->emailModel->getStatRepository()->findContactEmailStats($leadCredentials['id'], $emailId); if (count($stats)) { // Already sent return $event->setResult(true); } } $eventDetails = $event->getEventDetails(); $options = ['source' => ['campaign', $eventDetails['campaign']['id']]]; $emailSent = $this->emailModel->sendEmail($email, $leadCredentials, $options); } $event->setChannel('email', $emailId); } return $event->setResult($emailSent); }
/** * @param ChannelBroadcastEvent $event */ public function onBroadcast(ChannelBroadcastEvent $event) { if (!$event->checkContext('email')) { return; } // Get list of published broadcasts or broadcast if there is only a single ID $id = $event->getId(); $emails = $this->model->getRepository()->getPublishedBroadcasts($id); $output = $event->getOutput(); /** @var Email $email */ while (($email = $emails->next()) !== false) { list($sentCount, $failedCount, $ignore) = $this->model->sendEmailToLists($email[0], null, 100, true, $output); $event->setResults($this->translator->trans('mautic.email.email') . ': ' . $email[0]->getName(), $sentCount, $failedCount); $this->em->detach($email[0]); } }
/** * @param CampaignExecutionEvent $event */ public function onCampaignTriggerAction(CampaignExecutionEvent $event) { $emailSent = false; $lead = $event->getLead(); $leadCredentials = $lead instanceof Lead ? $lead->getProfileFields() : $lead; $leadCredentials['owner_id'] = $lead instanceof Lead && ($owner = $lead->getOwner()) ? $owner->getId() : 0; if (!empty($leadCredentials['email'])) { $config = $event->getConfig(); $emailId = (int) $config['email']; $email = $this->emailModel->getEntity($emailId); $type = isset($config['email_type']) ? $config['email_type'] : 'transactional'; $options = ['source' => ['campaign.event', $event->getEvent()['id']], 'email_attempts' => isset($config['attempts']) ? $config['attempts'] : 3, 'email_priority' => isset($config['priority']) ? $config['priority'] : 2, 'email_type' => $type]; $event->setChannel('email', $emailId); if ($email != null && $email->isPublished()) { // Determine if this email is transactional/marketing $stats = []; if ('marketing' == $type) { // Determine if this lead has received the email before $leadIds = implode(',', [$leadCredentials['id']]); $stats = $this->emailModel->getStatRepository()->checkContactsSentEmail($leadIds, $emailId); $emailSent = true; // Assume it was sent to prevent the campaign event from getting rescheduled over and over } if (empty($stats)) { $emailSent = $this->emailModel->sendEmail($email, $leadCredentials, $options); } } else { return $event->setFailed('Email not found or published'); } } else { return $event->setFailed('Contact does not have an email'); } return $event->setResult($emailSent); }
/** * Sends campaign emails. * * @param MessageQueueBatchProcessEvent $event */ public function onProcessMessageQueueBatch(MessageQueueBatchProcessEvent $event) { if (!$event->checkContext('email')) { return; } $messages = $event->getMessages(); $emailId = $event->getChannelId(); $email = $this->emailModel->getEntity($emailId); $sendTo = []; $messagesByContact = []; $options = ['email_type' => 'marketing']; /** @var MessageQueue $message */ foreach ($messages as $id => $message) { $contact = $message->getLead()->getProfileFields(); if (empty($contact['email'])) { // No email so just let this slide $message->setProcessed(); $message->setSuccess(); } $sendTo[$contact['id']] = $contact; $messagesByContact[$contact['id']] = $message; } if (count($sendTo)) { $options['resend_message_queue'] = $messagesByContact; $errors = $this->emailModel->sendEmail($email, $sendTo, $options); // Let's see who was successful foreach ($messagesByContact as $contactId => $message) { // If the message is processed, it was rescheduled by sendEmail if (!$message->isProcessed()) { $message->setProcessed(); if (empty($errors[$contactId])) { $message->setSuccess(); } } } } $event->stopPropagation(); }
/** * @param EmailSendEvent $event */ public function onEmailGenerate(EmailSendEvent $event) { $idHash = $event->getIdHash(); $lead = $event->getLead(); $email = $event->getEmail(); if ($idHash == null) { // Generate a bogus idHash to prevent errors for routes that may include it $idHash = uniqid(); } $unsubscribeText = $this->coreParametersHelper->getParameter('unsubscribe_text'); if (!$unsubscribeText) { $unsubscribeText = $this->translator->trans('mautic.email.unsubscribe.text', ['%link%' => '|URL|']); } $unsubscribeText = str_replace('|URL|', $this->emailModel->buildUrl('mautic_email_unsubscribe', ['idHash' => $idHash]), $unsubscribeText); $event->addToken('{unsubscribe_text}', $unsubscribeText); $event->addToken('{unsubscribe_url}', $this->emailModel->buildUrl('mautic_email_unsubscribe', ['idHash' => $idHash])); $webviewText = $this->coreParametersHelper->getParameter('webview_text'); if (!$webviewText) { $webviewText = $this->translator->trans('mautic.email.webview.text', ['%link%' => '|URL|']); } $webviewText = str_replace('|URL|', $this->emailModel->buildUrl('mautic_email_webview', ['idHash' => $idHash]), $webviewText); $event->addToken('{webview_text}', $webviewText); // Show public email preview if the lead is not known to prevent 404 if (empty($lead['id']) && $email) { $event->addToken('{webview_url}', $this->emailModel->buildUrl('mautic_email_preview', ['objectId' => $email->getId()])); } else { $event->addToken('{webview_url}', $this->emailModel->buildUrl('mautic_email_webview', ['idHash' => $idHash])); } $signatureText = $this->coreParametersHelper->getParameter('default_signature_text'); $fromName = $this->coreParametersHelper->getParameter('mailer_from_name'); if (!empty($lead['owner_id'])) { $owner = $this->factory->getModel('lead')->getRepository()->getLeadOwner($lead['owner_id']); if ($owner && !empty($owner['signature'])) { $fromName = $owner['first_name'] . ' ' . $owner['last_name']; $signatureText = $owner['signature']; } } $signatureText = str_replace('|FROM_NAME|', $fromName, nl2br($signatureText)); $event->addToken('{signature}', $signatureText); $event->addToken('{subject}', $event->getSubject()); }
/** * Process if an email is resent. * * @param Events\QueueEmailEvent $event */ public function onEmailResend(Events\QueueEmailEvent $event) { $message = $event->getMessage(); if (isset($message->leadIdHash)) { $stat = $this->emailModel->getEmailStatus($message->leadIdHash); if ($stat !== null) { $stat->upRetryCount(); $retries = $stat->getRetryCount(); if (true || $retries > 3) { //tried too many times so just fail $reason = $this->translator->trans('mautic.email.dnc.retries', ['%subject%' => EmojiHelper::toShort($message->getSubject())]); $this->emailModel->setDoNotContact($stat, $reason); } else { //set it to try again $event->tryAgain(); } $this->em->persist($stat); $this->em->flush(); } } }
/** * @param MauticEvents\CommandListEvent $event */ public function onBuildCommandList(MauticEvents\CommandListEvent $event) { if ($this->security->isGranted(['email:emails:viewown', 'email:emails:viewother'], 'MATCH_ONE')) { $event->addCommands('mautic.email.emails', $this->emailModel->getCommandList()); } }
/** * Set a widget detail when needed. * * @param WidgetDetailEvent $event */ public function onWidgetDetailGenerate(WidgetDetailEvent $event) { $this->checkPermissions($event); $canViewOthers = $event->hasPermission('email:emails:viewother'); if ($event->getType() == 'emails.in.time') { $widget = $event->getWidget(); $params = $widget->getParams(); if (isset($params['flag'])) { $params['filter']['flag'] = $params['flag']; } if (!$event->isCached()) { $event->setTemplateData(['chartType' => 'line', 'chartHeight' => $widget->getHeight() - 80, 'chartData' => $this->emailModel->getEmailsLineChartData($params['timeUnit'], $params['dateFrom'], $params['dateTo'], $params['dateFormat'], $params['filter'], $canViewOthers)]); } $event->setTemplate('MauticCoreBundle:Helper:chart.html.php'); $event->stopPropagation(); } if ($event->getType() == 'ignored.vs.read.emails') { $widget = $event->getWidget(); $params = $widget->getParams(); if (!$event->isCached()) { $event->setTemplateData(['chartType' => 'pie', 'chartHeight' => $widget->getHeight() - 80, 'chartData' => $this->emailModel->getIgnoredVsReadPieChartData($params['dateFrom'], $params['dateTo'], [], $canViewOthers)]); } $event->setTemplate('MauticCoreBundle:Helper:chart.html.php'); $event->stopPropagation(); } if ($event->getType() == 'upcoming.emails') { $widget = $event->getWidget(); $params = $widget->getParams(); $height = $widget->getHeight(); $limit = round(($height - 80) / 60); $upcomingEmails = $this->emailModel->getUpcomingEmails($limit, $canViewOthers); $event->setTemplate('MauticDashboardBundle:Dashboard:upcomingemails.html.php'); $event->setTemplateData(['upcomingEmails' => $upcomingEmails]); $event->stopPropagation(); } if ($event->getType() == 'most.sent.emails') { if (!$event->isCached()) { $params = $event->getWidget()->getParams(); if (empty($params['limit'])) { // Count the emails limit from the widget height $limit = round(($event->getWidget()->getHeight() - 80) / 35 - 1); } else { $limit = $params['limit']; } $emails = $this->emailModel->getEmailStatList($limit, $params['dateFrom'], $params['dateTo'], [], ['groupBy' => 'sends', 'canViewOthers' => $canViewOthers]); $items = []; // Build table rows with links if ($emails) { foreach ($emails as &$email) { $emailUrl = $this->router->generate('mautic_email_action', ['objectAction' => 'view', 'objectId' => $email['id']]); $row = [['value' => $email['name'], 'type' => 'link', 'link' => $emailUrl], ['value' => $email['count']]]; $items[] = $row; } } $event->setTemplateData(['headItems' => [$event->getTranslator()->trans('mautic.dashboard.label.title'), $event->getTranslator()->trans('mautic.email.label.sends')], 'bodyItems' => $items, 'raw' => $emails]); } $event->setTemplate('MauticCoreBundle:Helper:table.html.php'); $event->stopPropagation(); } if ($event->getType() == 'most.read.emails') { if (!$event->isCached()) { $params = $event->getWidget()->getParams(); if (empty($params['limit'])) { // Count the emails limit from the widget height $limit = round(($event->getWidget()->getHeight() - 80) / 35 - 1); } else { $limit = $params['limit']; } $emails = $this->emailModel->getEmailStatList($limit, $params['dateFrom'], $params['dateTo'], [], ['groupBy' => 'reads', 'canViewOthers' => $canViewOthers]); $items = []; // Build table rows with links if ($emails) { foreach ($emails as &$email) { $emailUrl = $this->router->generate('mautic_email_action', ['objectAction' => 'view', 'objectId' => $email['id']]); $row = [['value' => $email['name'], 'type' => 'link', 'link' => $emailUrl], ['value' => $email['count']]]; $items[] = $row; } } $event->setTemplateData(['headItems' => [$event->getTranslator()->trans('mautic.dashboard.label.title'), $event->getTranslator()->trans('mautic.email.label.reads')], 'bodyItems' => $items, 'raw' => $emails]); } $event->setTemplate('MauticCoreBundle:Helper:table.html.php'); $event->stopPropagation(); } if ($event->getType() == 'created.emails') { if (!$event->isCached()) { $params = $event->getWidget()->getParams(); if (empty($params['limit'])) { // Count the emails limit from the widget height $limit = round(($event->getWidget()->getHeight() - 80) / 35 - 1); } else { $limit = $params['limit']; } $emails = $this->emailModel->getEmailList($limit, $params['dateFrom'], $params['dateTo'], [], ['groupBy' => 'creations', 'canViewOthers' => $canViewOthers]); $items = []; // Build table rows with links if ($emails) { foreach ($emails as &$email) { $emailUrl = $this->router->generate('mautic_email_action', ['objectAction' => 'view', 'objectId' => $email['id']]); $row = [['value' => $email['name'], 'type' => 'link', 'link' => $emailUrl]]; $items[] = $row; } } $event->setTemplateData(['headItems' => [$event->getTranslator()->trans('mautic.dashboard.label.title')], 'bodyItems' => $items, 'raw' => $emails]); } $event->setTemplate('MauticCoreBundle:Helper:table.html.php'); $event->stopPropagation(); } if ($event->getType() == 'device.granularity.email') { $widget = $event->getWidget(); $params = $widget->getParams(); if (!$event->isCached()) { $event->setTemplateData(['chartType' => 'pie', 'chartHeight' => $widget->getHeight() - 80, 'chartData' => $this->emailModel->getDeviceGranularityPieChartData($params['dateFrom'], $params['dateTo'], $canViewOthers)]); } $event->setTemplate('MauticCoreBundle:Helper:chart.html.php'); $event->stopPropagation(); } }