Файл: concrete5.7.5.6/concrete/src/Mail/Service.php
Строк: 401
<?php
namespace ConcreteCoreMail;
use Config;
use ConcreteCoreLoggingGroupLogger;
use ZendMailMessage;
use ZendMailTransportSendmail as SendmailTransport;
use ZendMailTransportSmtp as SmtpTransport;
use ZendMailTransportSmtpOptions;
use ZendMimeMessage as MimeMessage;
use ZendMimeMime;
use ZendMimePart as MimePart;
use Exception;
use MonologLogger;
class Service
{
protected $headers;
protected $to;
protected $replyto;
protected $cc;
protected $bcc;
protected $from;
protected $data;
protected $subject;
protected $attachments;
protected $template;
protected $body;
protected $bodyHTML;
protected $testing;
public function __construct()
{
$this->reset();
}
/**
* this method is called by the Loader::helper to clean up the instance of this object
* resets the class scope variables.
*/
public function reset()
{
$this->headers = array();
$this->to = array();
$this->replyto = array();
$this->cc = array();
$this->bcc = array();
$this->from = array();
$this->data = array();
$this->subject = '';
$this->attachments = array();
$this->template = '';
$this->body = false;
$this->bodyHTML = false;
$this->testing = false;
}
public static function getMailerObject()
{
$response = array();
$response['mail'] = new Message();
$response['mail']->setEncoding(APP_CHARSET);
if (strcasecmp(Config::get('concrete.mail.method'), 'smtp') == 0) {
$config = array(
'host' => Config::get('concrete.mail.methods.smtp.server'),
);
$username = Config::get('concrete.mail.methods.smtp.username');
$password = Config::get('concrete.mail.methods.smtp.password');
if ($username != '') {
$config['connection_class'] = 'login';
$config['connection_config'] = array();
$config['connection_config']['username'] = $username;
$config['connection_config']['password'] = $password;
}
$port = Config::get('concrete.mail.methods.smtp.port', '');
if ($port != '') {
$config['port'] = $port;
}
$encr = Config::get('concrete.mail.methods.smtp.encryption', '');
if ($encr != '') {
$config['connection_config']['ssl'] = $encr;
}
$transport = new SmtpTransport();
$options = new SmtpOptions($config);
$transport->setOptions($options);
$response['transport'] = $transport;
} else {
$response['transport'] = new SendmailTransport();
}
return $response;
}
/**
* Adds a parameter to a mail template.
*
* @param string $key
* @param string $val
*/
public function addParameter($key, $val)
{
$this->data[$key] = $val;
}
/**
* Add attachment to send with an email.
*
* Sample Code:
* $attachment = $mailHelper->addAttachment($fileObject);
* $attachment->filename = "CustomFilename";
* $mailHelper->send();
*
* @param ConcreteCoreFileFile $fob File to attach
*
* @return StdClass Pointer to the attachment
*
* @throws Exception
*/
public function addAttachment(ConcreteCoreFileFile $fob)
{
// Get file version.
$fv = $fob->getVersion();
// Get file data.
$mimetype = $fv->getMimeType();
$filename = $fv->getFilename();
$resource = $fob->getFileResource();
$content = $resource->read();
// Create attachment.
$mp = new MimePart($content);
$mp->type = $mimetype;
$mp->disposition = Mime::DISPOSITION_ATTACHMENT;
$mp->encoding = Mime::ENCODING_BASE64;
$mp->filename = $filename;
// Add mimepart to attachments.
$this->attachments[] = $mp;
}
/**
* Loads an email template from the /mail/ directory.
*
* @param string $template
* @param string $pkgHandle
*/
public function load($template, $pkgHandle = null)
{
extract($this->data);
// loads template from mail templates directory
if (file_exists(DIR_FILES_EMAIL_TEMPLATES."/{$template}.php")) {
include DIR_FILES_EMAIL_TEMPLATES."/{$template}.php";
} else {
if ($pkgHandle != null) {
if (is_dir(DIR_PACKAGES.'/'.$pkgHandle)) {
include DIR_PACKAGES.'/'.$pkgHandle.'/'.DIRNAME_MAIL_TEMPLATES."/{$template}.php";
} else {
include DIR_PACKAGES_CORE.'/'.$pkgHandle.'/'.DIRNAME_MAIL_TEMPLATES."/{$template}.php";
}
} else {
include DIR_FILES_EMAIL_TEMPLATES_CORE."/{$template}.php";
}
}
if (isset($from)) {
$this->from($from[0], $from[1]);
}
$this->template = $template;
$this->subject = $subject;
$this->body = (isset($body) && is_string($body)) ? $body : false;
$this->bodyHTML = (isset($bodyHTML) && is_string($bodyHTML)) ? $bodyHTML : false;
}
/**
* Manually set the text body of a mail message, typically the body is set in the template + load method.
*
* @param string|false $body Set the text body (false to not use plain text body)
*/
public function setBody($body)
{
$this->body = $body;
}
/**
* Manually set the message's subject.
*
* @param string $subject
*/
public function setSubject($subject)
{
$this->subject = $subject;
}
/**
* Returns the message's subject.
*
* @return string
*/
public function getSubject()
{
return $this->subject;
}
/**
* Returns the message's text body.
*
* @return string|false
*/
public function getBody()
{
return $this->body;
}
/**
* Returns the message's html body.
*
* @return string|false
*/
public function getBodyHTML()
{
return $this->bodyHTML;
}
/**
* manually set the HTML portion of a MIME encoded message, can also be done by setting $bodyHTML in a mail template.
*
* @param string|false $html Set the html body (false to not use html body)
*/
public function setBodyHTML($html)
{
$this->bodyHTML = $html;
}
/**
* @param MailImporter $importer
* @param array $data
*/
public function enableMailResponseProcessing($importer, $data)
{
foreach ($this->to as $em) {
$importer->setupValidation($em[0], $data);
}
$this->from($importer->getMailImporterEmail());
$this->body = $importer->setupBody(($this->body === false) ? '' : $this->body);
}
/**
* @param array $arr
*
* @return string
*
* @todo documentation
*/
protected function generateEmailStrings($arr)
{
$str = '';
for ($i = 0; $i < count($arr); $i++) {
$v = $arr[$i];
if (isset($v[1])) {
$str .= '"'.$v[1].'" <'.$v[0].'>';
} elseif (isset($v[0])) {
$str .= $v[0];
}
if (($i + 1) < count($arr)) {
$str .= ', ';
}
}
return $str;
}
/**
* Sets the from address on the email about to be sent out.
*
* @param string $email
* @param string $name
*/
public function from($email, $name = null)
{
$this->from = array($email, $name);
}
/**
* Sets to the to email address on the email about to be sent out.
*
* @param string $email
* @param string $name
*/
public function to($email, $name = null)
{
if (strpos($email, ',') > 0) {
$email = explode(',', $email);
foreach ($email as $em) {
$this->to[] = array($em, $name);
}
} else {
$this->to[] = array($email, $name);
}
}
/**
* Adds an email address to the cc field on the email about to be sent out.
*
* @param string $email
* @param string $name
*
* @since 5.5.1
*/
public function cc($email, $name = null)
{
if (strpos($email, ',') > 0) {
$email = explode(',', $email);
foreach ($email as $em) {
$this->cc[] = array($em, $name);
}
} else {
$this->cc[] = array($email, $name);
}
}
/**
* Adds an email address to the bcc field on the email about to be sent out.
*
* @param string $email
* @param string $name
*
* @since 5.5.1
*/
public function bcc($email, $name = null)
{
if (strpos($email, ',') > 0) {
$email = explode(',', $email);
foreach ($email as $em) {
$this->bcc[] = array($em, $name);
}
} else {
$this->bcc[] = array($email, $name);
}
}
/*
* Sets the reply-to address on the email about to be sent out
* @param string $email
* @param string $name
* @return void
*/
public function replyto($email, $name = null)
{
if (strpos($email, ',') > 0) {
$email = explode(',', $email);
foreach ($email as $em) {
$this->replyto[] = array($em, $name);
}
} else {
$this->replyto[] = array($email, $name);
}
}
/** Set the testing state (if true the email logging never occurs and sending errors will throw an exception)
* @param bool $testing
*/
public function setTesting($testing)
{
$this->testing = $testing ? true : false;
}
/** Retrieve the testing state
* @return boolean
*/
public function getTesting()
{
return $this->testing;
}
/**
* Set additional headers
*
* @param array $headers
* @param string $val
*/
public function setAdditionalHeaders($headers)
{
$this->headers = $headers;
}
/**
* Sends the email.
*
* @param bool $resetData Whether or not to reset the service to its default values.
*
* @throws Exception
*/
public function sendMail($resetData = true)
{
$_from[] = $this->from;
$fromStr = $this->generateEmailStrings($_from);
$toStr = $this->generateEmailStrings($this->to);
$replyStr = $this->generateEmailStrings($this->replyto);
$zendMailData = self::getMailerObject();
$mail = $zendMailData['mail'];
$transport = $zendMailData['transport'];
if (is_array($this->from) && count($this->from)) {
if ($this->from[0] != '') {
$from = $this->from;
}
}
if (!isset($from)) {
$from = array(Config::get('concrete.email.default.address'), Config::get('concrete.email.default.name'));
$fromStr = Config::get('concrete.email.default.address');
}
// The currently included Zend library has a bug in setReplyTo that
// adds the Reply-To address as a recipient of the email. We must
// set the Reply-To before any header with addresses and then clear
// all recipients so that a copy is not sent to the Reply-To address.
if (is_array($this->replyto)) {
foreach ($this->replyto as $reply) {
$mail->setReplyTo($reply[0], $reply[1]);
}
}
$mail->setFrom($from[0], $from[1]);
$mail->setSubject($this->subject);
foreach ($this->to as $to) {
$mail->addTo($to[0], $to[1]);
}
if (is_array($this->cc) && count($this->cc)) {
foreach ($this->cc as $cc) {
$mail->addCc($cc[0], $cc[1]);
}
}
if (is_array($this->bcc) && count($this->bcc)) {
foreach ($this->bcc as $bcc) {
$mail->addBcc($bcc[0], $bcc[1]);
}
}
$headers = $mail->getHeaders();
if ($headers->has('messageid')) {
$messageIdHeader = $headers->get('messageid');
} else {
$messageIdHeader = new ZendMailHeaderMessageId();
$headers->addHeader($messageIdHeader);
}
$headers->addHeaders($this->headers);
$messageIdHeader->setId();
$body = new MimeMessage();
if (($this->body !== false) && ($this->bodyHTML !== false)) {
$alternatives = new MimeMessage();
$text = new MimePart($this->body);
$text->type = 'text/plain';
$text->charset = APP_CHARSET;
$alternatives->addPart($text);
$html = new MimePart($this->bodyHTML);
$html->type = 'text/html';
$html->charset = APP_CHARSET;
$alternatives->addPart($html);
$alternativesPath = new MimePart($alternatives->generateMessage());
$alternativesPath->type = 'multipart/alternative;'.Mime::LINEEND.' boundary="'.$alternatives->getMime()->boundary().'"';
$body->addPart($alternativesPath);
} elseif ($this->body !== false) {
$text = new MimePart($this->body);
$text->type = 'text/plain';
$text->charset = APP_CHARSET;
$body->addPart($text);
} elseif ($this->bodyHTML !== false) {
$html = new MimePart($this->bodyHTML);
$html->type = 'text/html';
$html->charset = APP_CHARSET;
$body->addPart($html);
}
foreach ($this->attachments as $att) {
$body->addPart($att);
}
if (count($body->getParts()) === 0) {
$text = new MimePart('');
$text->type = 'text/plain';
$text->charset = APP_CHARSET;
$body->addPart($text);
}
$mail->setBody($body);
try {
if (Config::get('concrete.email.enabled')) {
$transport->send($mail);
}
} catch (Exception $e) {
if ($this->getTesting()) {
throw $e;
}
$l = new GroupLogger(LOG_TYPE_EXCEPTIONS, Logger::CRITICAL);
$l->write(t('Mail Exception Occurred. Unable to send mail: ').$e->getMessage());
$l->write($e->getTraceAsString());
if (Config::get('concrete.log.emails')) {
$l->write(t('Template Used').': '.$this->template);
$l->write(t('To').': '.$toStr);
$l->write(t('From').': '.$fromStr);
if (isset($this->replyto)) {
$l->write(t('Reply-To').': '.$replyStr);
}
$l->write(t('Subject').': '.$this->subject);
$l->write(t('Body').': '.$this->body);
}
$l->close();
}
// add email to log
if (Config::get('concrete.log.emails') && !$this->getTesting()) {
$l = new GroupLogger(LOG_TYPE_EMAILS, Logger::INFO);
if (Config::get('concrete.email.enabled')) {
$l->write('**'.t('EMAILS ARE ENABLED. THIS EMAIL WAS SENT TO mail()').'**');
} else {
$l->write('**'.t('EMAILS ARE DISABLED. THIS EMAIL WAS LOGGED BUT NOT SENT').'**');
}
$l->write(t('Template Used').': '.$this->template);
$l->write(t('Mail Details: %s', $mail->toString()));
$l->close();
}
// clear data if applicable
if ($resetData) {
$this->reset();
}
}
}