From 3eef059ca6328736ef05356432854b87f5fc20fc Mon Sep 17 00:00:00 2001 From: =?utf8?q?Tim=20D=C3=BCsterhus?= Date: Sun, 14 Jun 2015 19:09:17 +0200 Subject: [PATCH] Add Mailbox classes for new email system --- .../lib/system/email/EmailGrammar.class.php | 91 +++++++++++++++++++ .../files/lib/system/email/Mailbox.class.php | 83 +++++++++++++++++ .../lib/system/email/UserMailbox.class.php | 41 +++++++++ 3 files changed, 215 insertions(+) create mode 100644 wcfsetup/install/files/lib/system/email/EmailGrammar.class.php create mode 100644 wcfsetup/install/files/lib/system/email/Mailbox.class.php create mode 100644 wcfsetup/install/files/lib/system/email/UserMailbox.class.php diff --git a/wcfsetup/install/files/lib/system/email/EmailGrammar.class.php b/wcfsetup/install/files/lib/system/email/EmailGrammar.class.php new file mode 100644 index 0000000000..049153de38 --- /dev/null +++ b/wcfsetup/install/files/lib/system/email/EmailGrammar.class.php @@ -0,0 +1,91 @@ + + * @package com.woltlab.wcf + * @subpackage system.email + * @category Community Framework + */ +final class EmailGrammar { + /** + * Returns a regular expression matching the given type in RFC 5322. + * + * @param string $type + * @return string + */ + public static function getGrammar($type) { + switch ($type) { + case 'VCHAR': + return '[\x21-\x7E]'; + case 'WSP': + return '[\x20\x09]'; + case 'FWS': + return "(?:(?:".self::getGrammar('WSP')."*\r\n)?".self::getGrammar('WSP')."+)"; + case 'CFWS': + // note: no support for comments + return self::getGrammar('FWS'); + case 'quoted-pair': + return "(?:\\\\(?:".self::getGrammar('WSP')."|".self::getGrammar('VCHAR')."))"; + case 'atext': + return "[a-zA-Z0-9!#$%&'*+-/=?^_`{|}~]"; + case 'atom': + return "(?:".self::getGrammar('CFWS')."?".self::getGrammar('atext')."+".self::getGrammar('CFWS')."?)"; + case 'id-left': + case 'dot-atom-text': + return "(?:".self::getGrammar('atext')."+(?:\\.".self::getGrammar('atext').'+)*)'; + case 'no-fold-literal': + return "(?:\\[".self::getGrammar('dtext')."*\\])"; + case 'id-right': + return "(?:".self::getGrammar('dot-atom-text')."|".self::getGrammar('no-fold-literal').")"; + case 'dot-atom': + return "(?:".self::getGrammar('CFWS')."?".self::getGrammar('dot-atom-text').self::getGrammar('CFWS')."?)"; + case 'qtext': + return '[\x21\x23-\x5B\x5D-\x7E]'; + case 'qcontent': + return "(?:".self::getGrammar('qtext')."|".self::getGrammar('quoted-pair').")"; + case 'quoted-string': + return "(?:".self::getGrammar('CFWS')."?\"(?:".self::getGrammar('FWS')."?".self::getGrammar('qcontent').")*".self::getGrammar('FWS')."?\"".self::getGrammar('CFWS')."?)"; + case 'word': + return "(?:".self::getGrammar('atom')."|".self::getGrammar('quoted-string').")"; + case 'display-name': + case 'phrase': + return "(?:".self::getGrammar('word')."+)"; + case 'local-part': + return "(?:".self::getGrammar('dot-atom')."|".self::getGrammar('quoted-string').")"; + case 'dtext': + return '[\x21-\x5A\x5E-\x7E]'; + case 'domain-literal': + return "(?:".self::getGrammar('CFWS')."?\\[(?:".self::getGrammar('FWS')."?".self::getGrammar('dtext').")*".self::getGrammar('FWS')."?\\]".self::getGrammar('CFWS')."?)"; + case 'domain': + return "(?:".self::getGrammar('dot-atom')."|".self::getGrammar('domain-literal').")"; + case 'addr-spec': + return "(?:".self::getGrammar('local-part')."@".self::getGrammar('domain').")"; + case 'angle-addr': + return "(?:".self::getGrammar('CFWS')."?<".self::getGrammar('addr-spec').">".self::getGrammar('CFWS')."?)"; + case 'name-addr': + return "(?:".self::getGrammar('display-name')."?".self::getGrammar('angle-addr').")"; + case 'mailbox': + return "(?:".self::getGrammar('name-addr')."|".self::getGrammar('addr-spec').")"; + case 'msg-id': + return "(?:".self::getGrammar('CFWS')."?<".self::getGrammar('id-left')."@".self::getGrammar('id-right').">".self::getGrammar('CFWS')."?)"; + } + } + + /** + * Encode text using quoted printable encoding. + * + * @param string $header Header to encode + * @return string Encoded header + */ + public static function encodeMimeHeader($header) { + return mb_encode_mimeheader($header, "UTF-8", "Q", "\r\n"); + } + + private function __construct() { } +} diff --git a/wcfsetup/install/files/lib/system/email/Mailbox.class.php b/wcfsetup/install/files/lib/system/email/Mailbox.class.php new file mode 100644 index 0000000000..8205c1e041 --- /dev/null +++ b/wcfsetup/install/files/lib/system/email/Mailbox.class.php @@ -0,0 +1,83 @@ + + * @package com.woltlab.wcf + * @subpackage system.email + * @category Community Framework + */ +class Mailbox { + /** + * The email address of this mailbox. + * @var string + */ + protected $address; + + /** + * The human readable name of this mailbox. + * @var string + */ + protected $name = null; + + /** + * Creates a new Mailbox. + * + * @param string $address email address of this mailbox + * @param string $name human readable name of this mailbox (or null) + */ + public function __construct($address, $name = null) { + if (!preg_match('(^'.EmailGrammar::getGrammar('addr-spec').'$)', $address)) { + throw new SystemException("The given email address '".$address."' is invalid."); + } + + $this->address = $address; + $this->name = $name; + } + + /** + * Returns the human readable name of this mailbox. + * + * @return string + */ + public function getName() { + return $this->name; + } + + /** + * Returns the email address of this mailbox. + * + * @return string + */ + public function getAddress() { + return $this->address; + } + + /** + * Returns a string representation for use in a RFC 5233 message. + * + * @return string + */ + public function __toString() { + if ($this->name === null) { + return $this->address; + } + + $name = $this->name; + if (!preg_match('(^'.EmailGrammar::getGrammar('atom').'$)', $name)) { + if (($encoded = EmailGrammar::encodeMimeHeader($name)) === $name) { + $name = '"'.addcslashes($name, '\\"').'"'; + } + else { + $name = $encoded; + } + } + + return $name.' <'.$this->address.'>'; + } +} diff --git a/wcfsetup/install/files/lib/system/email/UserMailbox.class.php b/wcfsetup/install/files/lib/system/email/UserMailbox.class.php new file mode 100644 index 0000000000..6e9a01c9b5 --- /dev/null +++ b/wcfsetup/install/files/lib/system/email/UserMailbox.class.php @@ -0,0 +1,41 @@ + + * @package com.woltlab.wcf + * @subpackage system.email + * @category Community Framework + */ +class UserMailbox extends Mailbox { + /** + * User object belonging to this Mailbox + * @var \wcf\data\user\User + */ + protected $user = null; + + /** + * Creates a new Mailbox. + * + * @param \wcf\data\user\User $user User object belonging to this Mailbox + */ + public function __construct(User $user) { + parent::__construct($user->email, $user->username); + + $this->user = $user; + } + + /** + * Returns the User object belonging to this Mailbox. + * + * @return \wcf\data\user\User + */ + public function getUser() { + return $this->user; + } +} -- 2.20.1