Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 400 and 401]

   1  <?php
   2  /**
   3   * Copyright 2012-2017 Horde LLC (http://www.horde.org/)
   4   *
   5   * See the enclosed file LICENSE for license information (BSD). If you
   6   * did not receive this file, see http://www.horde.org/licenses/bsd.
   7   *
   8   * @category  Horde
   9   * @copyright 2012-2017 Horde LLC
  10   * @license   http://www.horde.org/licenses/bsd New BSD License
  11   * @package   Mail
  12   */
  13  
  14  /**
  15   * Object representation of a RFC 822 e-mail address.
  16   *
  17   * @author    Michael Slusarz <slusarz@horde.org>
  18   * @category  Horde
  19   * @copyright 2012-2017 Horde LLC
  20   * @license   http://www.horde.org/licenses/bsd New BSD License
  21   * @package   Mail
  22   *
  23   * @property-read string $bare_address  The bare mailbox@host address.
  24   * @property-read string $bare_address_idn  The bare mailbox@host address (IDN
  25   *                                          encoded). (@since 2.1.0)
  26   * @property-read boolean $eai  Returns true if the local (mailbox) address
  27   *                              part requires EAI (UTF-8) support.
  28   *                              (@since 2.5.0)
  29   * @property-read string $encoded  The full MIME/IDN encoded address (UTF-8).
  30   * @property string $host  Returns the host part (UTF-8).
  31   * @property-read string $host_idn  Returns the IDN encoded host part.
  32   * @property-read string $label  The shorthand label for this address.
  33   * @property string $personal  The personal part (UTF-8).
  34   * @property-read string $personal_encoded  The MIME encoded personal part
  35   *                                          (UTF-8).
  36   * @property-read boolean $valid  Returns true if there is enough information
  37   *                                in object to create a valid address.
  38   */
  39  class Horde_Mail_Rfc822_Address extends Horde_Mail_Rfc822_Object
  40  {
  41      /**
  42       * Comments associated with the personal phrase.
  43       *
  44       * @var array
  45       */
  46      public $comment = array();
  47  
  48      /**
  49       * Local-part of the address (UTF-8).
  50       *
  51       * @var string
  52       */
  53      public $mailbox = null;
  54  
  55      /**
  56       * Hostname of the address.
  57       *
  58       * @var string
  59       */
  60      protected $_host = null;
  61  
  62      /**
  63       * Personal part of the address.
  64       *
  65       * @var string
  66       */
  67      protected $_personal = null;
  68  
  69      /**
  70       * Constructor.
  71       *
  72       * @param string $address  If set, address is parsed and used as the
  73       *                         object address. Address is not validated;
  74       *                         first e-mail address parsed is used.
  75       */
  76      public function __construct($address = null)
  77      {
  78          if (!is_null($address)) {
  79              $rfc822 = new Horde_Mail_Rfc822();
  80              $addr = $rfc822->parseAddressList($address);
  81              if (count($addr)) {
  82                  foreach ($addr[0] as $key => $val) {
  83                      $this->$key = $val;
  84                  }
  85              }
  86          }
  87      }
  88  
  89      /**
  90       */
  91      public function __set($name, $value)
  92      {
  93          switch ($name) {
  94          case 'host':
  95              try {
  96                  $value = Horde_Idna::decode($value);
  97              } catch (Horde_Idna_Exception $e) {}
  98              $this->_host = Horde_String::lower($value);
  99              break;
 100  
 101          case 'personal':
 102              $this->_personal = !empty($value)
 103                  ? Horde_Mime::decode($value)
 104                  : null;
 105              break;
 106          }
 107      }
 108  
 109      /**
 110       * @throws Horde_Idna_Exception
 111       */
 112      public function __get($name)
 113      {
 114          switch ($name) {
 115          case 'bare_address':
 116              return is_null($this->host)
 117                  ? $this->mailbox
 118                  : $this->mailbox . '@' . $this->host;
 119  
 120          case 'bare_address_idn':
 121              $personal = $this->_personal;
 122              $this->_personal = null;
 123              $res = $this->encoded;
 124              $this->_personal = $personal;
 125              return $res;
 126  
 127          case 'eai':
 128              return is_null($this->mailbox)
 129                  ? false
 130                  : Horde_Mime::is8bit($this->mailbox);
 131  
 132          case 'encoded':
 133              return $this->writeAddress(true);
 134  
 135          case 'host':
 136              return $this->_host;
 137  
 138          case 'host_idn':
 139              return Horde_Idna::encode($this->_host);
 140  
 141          case 'label':
 142              return is_null($this->personal)
 143                  ? $this->bare_address
 144                  : $this->_personal;
 145  
 146          case 'personal':
 147              return $this->_personal === null || (strcasecmp($this->_personal, $this->bare_address) === 0)
 148                  ? null
 149                  : $this->_personal;
 150  
 151          case 'personal_encoded':
 152              return Horde_Mime::encode($this->personal);
 153  
 154          case 'valid':
 155              return !empty($this->mailbox);
 156          }
 157      }
 158  
 159      /**
 160       */
 161      protected function _writeAddress($opts)
 162      {
 163          $rfc822 = new Horde_Mail_Rfc822();
 164  
 165          $address = $rfc822->encode($this->mailbox, 'address');
 166          $host = empty($opts['idn']) ? $this->host : $this->host_idn;
 167          if (!empty($host)) {
 168              $address .= '@' . $host;
 169          }
 170          $personal = $this->personal;
 171          if (!empty($personal)) {
 172              if (!empty($opts['encode'])) {
 173                  $personal = Horde_Mime::encode($this->personal, $opts['encode']);
 174              }
 175              if (empty($opts['noquote'])) {
 176                  $personal = $rfc822->encode($personal, 'personal');
 177              }
 178          }
 179          if (!empty($opts['comment']) && !empty($this->comment)) {
 180              foreach ($this->comment as $val) {
 181                  $personal .= ' (' . $rfc822->encode($val, 'comment') . ')';
 182              }
 183          }
 184  
 185          return (!empty($personal) && ($personal != $address))
 186              ? ltrim($personal) . ' <' . $address . '>'
 187              : $address;
 188      }
 189  
 190      /**
 191       */
 192      public function match($ob)
 193      {
 194          if (!($ob instanceof Horde_Mail_Rfc822_Address)) {
 195              $ob = new Horde_Mail_Rfc822_Address($ob);
 196          }
 197  
 198          return ($this->bare_address == $ob->bare_address);
 199      }
 200  
 201      /**
 202       * Do a case-insensitive match on the address. Per RFC 822/2822/5322,
 203       * although the host portion of an address is case-insensitive, the
 204       * mailbox portion is platform dependent.
 205       *
 206       * @param mixed $ob  Address data.
 207       *
 208       * @return boolean  True if the data reflects the same case-insensitive
 209       *                  address.
 210       */
 211      public function matchInsensitive($ob)
 212      {
 213          if (!($ob instanceof Horde_Mail_Rfc822_Address)) {
 214              $ob = new Horde_Mail_Rfc822_Address($ob);
 215          }
 216  
 217          return (Horde_String::lower($this->bare_address) == Horde_String::lower($ob->bare_address));
 218      }
 219  
 220      /**
 221       * Do a case-insensitive match on the address for a given domain.
 222       * Matches as many parts of the subdomain in the address as is given in
 223       * the input.
 224       *
 225       * @param string $domain  Domain to match.
 226       *
 227       * @return boolean  True if the address matches the given domain.
 228       */
 229      public function matchDomain($domain)
 230      {
 231          $host = $this->host;
 232          if (is_null($host)) {
 233              return false;
 234          }
 235  
 236          $match_domain = explode('.', $domain);
 237          $match_host = array_slice(explode('.', $host), count($match_domain) * -1);
 238  
 239          return (strcasecmp($domain, implode('.', $match_host)) === 0);
 240      }
 241  
 242  }