/** * Send the message * * @param bool $dispatchSendEvent * @param bool $isQueueFlush * * @return bool */ public function send($dispatchSendEvent = false, $isQueueFlush = false) { // Set from email $from = $this->message->getFrom(); if (empty($from)) { $this->setFrom($this->from); } // Set system return path if applicable if (!$isQueueFlush && ($bounceEmail = $this->generateBounceEmail($this->idHash))) { $this->message->setReturnPath($bounceEmail); } elseif (!empty($this->returnPath)) { $this->message->setReturnPath($this->returnPath); } if (empty($this->errors)) { if (!$isQueueFlush) { // Only add unsubscribe header to one-off sends as tokenized sends are built by the transport $this->addUnsubscribeHeader(); // Search/replace tokens if this is not a queue flush // Generate tokens from listeners if ($dispatchSendEvent) { $this->dispatchSendEvent(); } // Queue an asset stat if applicable $this->queueAssetDownloadEntry(); } $this->message->setSubject($this->subject); $this->message->setBody($this->body['content'], $this->body['contentType'], $this->body['charset']); $this->setMessagePlainText($isQueueFlush); if (!$isQueueFlush) { // Set metadata if applicable if (method_exists($this->message, 'addMetadata')) { foreach ($this->queuedRecipients as $email => $name) { $this->message->addMetadata($email, array('leadId' => !empty($this->lead) ? $this->lead['id'] : null, 'emailId' => !empty($this->email) ? $this->email->getId() : null, 'hashId' => $this->idHash, 'source' => $this->source, 'tokens' => $this->getTokens())); } } else { // Replace token content $tokens = $this->getTokens(); if (!empty($tokens)) { // Replace tokens $search = array_keys($tokens); $replace = $tokens; self::searchReplaceTokens($search, $replace, $this->message); } } } // Attach assets if (!empty($this->assets)) { /** @var \Mautic\AssetBundle\Entity\Asset $asset */ foreach ($this->assets as $asset) { if (!in_array($asset->getId(), $this->attachedAssets)) { $this->attachedAssets[] = $asset->getId(); $this->attachFile($asset->getFilePath(), $asset->getOriginalFileName(), $asset->getMime()); } } } // Set custom headers if (!empty($this->headers)) { $headers = $this->message->getHeaders(); foreach ($this->headers as $headerKey => $headerValue) { if ($headers->has($headerKey)) { $header = $headers->get($headerKey); $header->setFieldBodyModel($headerValue); } else { $headers->addTextHeader($headerKey, $headerValue); } } } try { $failures = array(); $this->mailer->send($this->message, $failures); if (!empty($failures)) { $this->errors['failures'] = $failures; $this->logError('Sending failed for one or more recipients'); } // Clear the log so that previous output is not associated with new errors $this->logger->clear(); } catch (\Exception $e) { $this->logError($e); // Exception encountered when sending so all recipients are considered failures $this->errors['failures'] = array_merge(array_keys((array) $this->message->getTo()), array_keys((array) $this->message->getCc()), array_keys((array) $this->message->getBcc())); } } $error = empty($this->errors); $this->createAssetDownloadEntries(); return $error; }
/** * Send the message. * * @param bool $dispatchSendEvent * @param bool $isQueueFlush (a tokenized/batch send via API such as Mandrill) * @param bool $useOwnerAsMailer * * @return bool */ public function send($dispatchSendEvent = false, $isQueueFlush = false, $useOwnerAsMailer = true) { if ($this->tokenizationEnabled && !empty($this->queuedRecipients) && !$isQueueFlush) { // This transport uses tokenization and queue()/flushQueue() was not used therefore use them in order // properly populate metadata for this transport if ($result = $this->queue($dispatchSendEvent)) { $result = $this->flushQueue(); } return $result; } // Set from email if (!$isQueueFlush && $useOwnerAsMailer && $this->factory->getParameter('mailer_is_owner') && isset($this->lead['id'])) { if (!isset($this->lead['owner_id'])) { $this->lead['owner_id'] = 0; } elseif (isset($this->lead['owner_id'])) { if (!isset(self::$leadOwners[$this->lead['owner_id']])) { $owner = $this->factory->getModel('lead')->getRepository()->getLeadOwner($this->lead['owner_id']); if ($owner) { self::$leadOwners[$owner['id']] = $owner; } } else { $owner = self::$leadOwners[$this->lead['owner_id']]; } } if (!empty($owner)) { $this->setFrom($owner['email'], $owner['first_name'] . ' ' . $owner['last_name']); } else { $this->setFrom($this->from); } } elseif (!($from = $this->message->getFrom())) { $this->setFrom($this->from); } // Set system return path if applicable if (!$isQueueFlush && ($bounceEmail = $this->generateBounceEmail($this->idHash))) { $this->message->setReturnPath($bounceEmail); } elseif (!empty($this->returnPath)) { $this->message->setReturnPath($this->returnPath); } if (empty($this->errors)) { if (!$isQueueFlush) { // Only add unsubscribe header to one-off sends as tokenized sends are built by the transport $this->addUnsubscribeHeader(); // Search/replace tokens if this is not a queue flush // Generate tokens from listeners if ($dispatchSendEvent) { $this->dispatchSendEvent(); } // Queue an asset stat if applicable $this->queueAssetDownloadEntry(); } $this->message->setSubject($this->subject); // Only set body if not empty or if plain text is empty - this ensures an empty HTML body does not show for // messages only with plain text if (!empty($this->body['content']) || empty($this->plainText)) { $this->message->setBody($this->body['content'], $this->body['contentType'], $this->body['charset']); } $this->setMessagePlainText($isQueueFlush); if (!$isQueueFlush) { // Set metadata if applicable if (method_exists($this->message, 'addMetadata')) { foreach ($this->queuedRecipients as $email => $name) { $this->message->addMetadata($email, ['leadId' => !empty($this->lead) ? $this->lead['id'] : null, 'emailId' => !empty($this->email) ? $this->email->getId() : null, 'hashId' => $this->idHash, 'source' => $this->source, 'tokens' => $this->getTokens()]); } } else { // Replace token content $tokens = $this->getTokens(); if (!empty($tokens)) { // Replace tokens $search = array_keys($tokens); $replace = $tokens; self::searchReplaceTokens($search, $replace, $this->message); } } } // Attach assets if (!empty($this->assets)) { /** @var \Mautic\AssetBundle\Entity\Asset $asset */ foreach ($this->assets as $asset) { if (!in_array($asset->getId(), $this->attachedAssets)) { $this->attachedAssets[] = $asset->getId(); $this->attachFile($asset->getFilePath(), $asset->getOriginalFileName(), $asset->getMime()); } } } // Set custom headers if (!empty($this->headers)) { $headers = $this->message->getHeaders(); foreach ($this->headers as $headerKey => $headerValue) { if ($headers->has($headerKey)) { $header = $headers->get($headerKey); $header->setFieldBodyModel($headerValue); } else { $headers->addTextHeader($headerKey, $headerValue); } } } try { $failures = []; if (!$this->transport->isStarted()) { $this->transportStartTime = time(); } $this->mailer->send($this->message, $failures); if (!empty($failures)) { $this->errors['failures'] = $failures; $this->logError('Sending failed for one or more recipients'); } // Clear the log so that previous output is not associated with new errors $this->logger->clear(); } catch (\Exception $e) { $this->logError($e); // Exception encountered when sending so all recipients are considered failures $this->errors['failures'] = array_merge(array_keys((array) $this->message->getTo()), array_keys((array) $this->message->getCc()), array_keys((array) $this->message->getBcc())); } } ++$this->messageSentCount; $this->checkIfTransportNeedsRestart(); $error = empty($this->errors); $this->createAssetDownloadEntries(); return $error; }