--- /dev/null
+<?php
+namespace wcf\system\background\job;
+use wcf\system\email\Email;
+use wcf\system\email\Mailbox;
+
+/**
+ * Delivers the given email to the given mailbox.
+ *
+ * @author Tim Duesterhus
+ * @copyright 2001-2015 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf
+ * @subpackage system.background.job
+ * @category Community Framework
+ */
+class EmailDeliveryBackgroundJob extends AbstractBackgroundJob {
+ /**
+ * email to send
+ * @var \wcf\system\email\Email
+ */
+ protected $email;
+
+ /**
+ * recipient mailbox
+ * @var \wcf\system\email\Mailbox
+ */
+ protected $mailbox;
+
+ /**
+ * instance of the default transport
+ * @var \wcf\system\email\transport\EmailTransport
+ */
+ protected static $transport = null;
+
+ /**
+ * Creates the job using the given the email and the destination mailbox.
+ *
+ * @param \wcf\system\email\Email $email
+ * @param \wcf\system\email\Mailbox $mailbox
+ * @see \wcf\system\email\transport\EmailTransport
+ */
+ public function __construct(Email $email, Mailbox $mailbox) {
+ $this->email = $email;
+ $this->mailbox = $mailbox;
+ }
+
+ /**
+ * Emails will be sent with an increasing timeout between the tries.
+ *
+ * @return int 5 minutes, 30 minutes, 2 hours.
+ */
+ public function retryAfter() {
+ switch ($this->getFailures()) {
+ case 1:
+ return 5 * 60;
+ case 2:
+ return 30 * 60;
+ case 3:
+ return 2 * 60 * 60;
+ }
+ }
+
+ /**
+ * @see \wcf\system\background\job\AbstractJob::perform();
+ */
+ public function perform() {
+ if (self::$transport === null) {
+ $name = '\wcf\system\email\transport\\'.ucfirst(MAIL_SEND_METHOD).'EmailTransport';
+ self::$transport = new $name();
+ }
+
+ self::$transport->deliver($this->email, $this->mailbox);
+ }
+}
<?php
namespace wcf\system\email;
+use wcf\system\background\job\EmailDeliveryBackgroundJob;
use wcf\system\email\mime\AbstractMimePart;
use wcf\system\email\mime\TextMimePart;
+use wcf\system\event\EventHandler;
use wcf\system\exception\SystemException;
use wcf\util\DateUtil;
use wcf\util\StringUtil;
throw new SystemException("The header '".$header."' may not be set. You may only set user defined headers (starting with 'X-').");
}
- $this->extraHeaders[] = [ $header, EmailGrammar::encodeMimeHeader($value) ];
+ $this->extraHeaders[] = [ $header, EmailGrammar::encodeQuotedPrintableHeader($value) ];
}
/**
$body .= $text;
}
+ // TODO: Where to put the email signature?
+
return $body;
}
+ /**
+ * Returns needed AbstractBackgroundJobs to deliver this email to every recipient.
+ *
+ * @return array<\wcf\system\background\job\AbstractBackgroundJob>
+ */
+ public function getJobs() {
+ $jobs = [ ];
+
+ // ensure every header is filled in
+ $this->getHeaders();
+
+ foreach ($this->recipients as $recipient) {
+ $mail = clone $this;
+
+ if ($recipient[1] instanceof UserMailbox) {
+ $mail->addHeader('X-Community-Framework-Recipient', $recipient[1]->getUser()->username);
+ }
+
+ $data = [ 'mail' => $mail, 'recipient' => $recipient, 'skip' => false ];
+ EventHandler::getInstance()->fireAction($this, 'getJobs', $data);
+
+ // an event decided that this email should be skipped
+ if ($data['skip']) continue;
+
+ $jobs[] = new EmailDeliveryBackgroundJob($mail, $recipient[1]);
+ }
+
+ return $jobs;
+ }
+
/**
* Returns the email RFC 2822 representation of this email.
*
*/
protected $mimeType;
+ /**
+ * the file contents
+ * @var string
+ */
+ protected $content = '';
+
/**
* Creates a new Attachment.
*
$this->mimeType = $mimeType ?: (FileUtil::getMimeType($path) ?: 'application/octet-stream');
$this->path = $path;
$this->filename = $filename ?: basename($path);
+ $this->content = file_get_contents($this->path);
}
/**
* @see \wcf\system\email\mime\AbstractMimePart::getContent()
*/
public function getContent() {
- return file_get_contents($this->path);
+ return $this->content;
}
}
--- /dev/null
+<?php
+namespace wcf\system\email\transport;
+use wcf\system\email\Email;
+use wcf\system\email\Mailbox;
+use wcf\system\io\File;
+use wcf\util\DateUtil;
+
+/**
+ * DebugEmailTransport is a debug implementation of an email transport which writes emails into
+ * a log file.
+ *
+ * @author Tim Duesterhus, Alexander Ebert
+ * @copyright 2001-2015 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf
+ * @subpackage system.email.transport
+ * @category Community Framework
+ */
+class DebugEmailTransport implements EmailTransport {
+ /**
+ * mbox file
+ * @var \wcf\system\io\File
+ */
+ protected $mbox = null;
+
+ /**
+ * Creates a new DebugTransport using the given mbox as target.
+ *
+ * @param string $mbox mbox location or null for default location
+ */
+ public function __construct($mbox = null) {
+ if ($mbox === null) $mbox = WCF_DIR.'log/debug.mbox';
+
+ $this->mbox = new File($mbox, 'ab');
+ }
+
+ /**
+ * Writes the given $email into the mbox.
+ *
+ * @param \wcf\system\email\Email $email
+ * @param \wcf\system\email\Mailbox $envelopeTo
+ */
+ public function deliver(Email $email, Mailbox $envelopeTo) {
+ $this->mbox->write("From ".$email->getSender()->getAddress()." ".DateUtil::getDateTimeByTimestamp(TIME_NOW)->format('D M d H:i:s Y')."\r\n");
+ $this->mbox->write("Delivered-To: ".$envelopeTo->getAddress()."\r\n");
+ $this->mbox->write($email);
+ $this->mbox->write("\r\n");
+ }
+}
--- /dev/null
+<?php
+namespace wcf\system\email\transport;
+use wcf\system\email\Email;
+use wcf\system\email\Mailbox;
+
+/**
+ * An EmailTransport sends emails.
+ *
+ * @author Tim Duesterhus
+ * @copyright 2001-2015 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf
+ * @subpackage system.email.transport
+ * @category Community Framework
+ */
+interface EmailTransport {
+ /**
+ * Delivers the given $email to the given Mailbox as the recipient.
+ *
+ * @param \wcf\system\email\Email $email
+ * @param \wcf\system\email\Mailbox $envelopeTo
+ */
+ public function deliver(Email $email, Mailbox $envelopeTo);
+}