vendor/swiftmailer/lib/classes/Swift/Mime/Grammar.php
changeset 0 7f95f8617b0b
equal deleted inserted replaced
-1:000000000000 0:7f95f8617b0b
       
     1 <?php
       
     2 
       
     3 /*
       
     4  * This file is part of SwiftMailer.
       
     5  * (c) 2004-2009 Chris Corbyn
       
     6  *
       
     7  * For the full copyright and license information, please view the LICENSE
       
     8  * file that was distributed with this source code.
       
     9  */
       
    10 
       
    11 /**
       
    12  * Defines the grammar to use for validation, implements the RFC 2822 (and friends) ABNF grammar definitions.
       
    13  * @package Swift
       
    14  * @subpackage Mime
       
    15  * @author Fabien Potencier
       
    16  * @author Chris Corbyn
       
    17  */
       
    18 class Swift_Mime_Grammar
       
    19 {
       
    20   /**
       
    21    * Special characters used in the syntax which need to be escaped.
       
    22    * @var string[]
       
    23    * @access private
       
    24    */
       
    25   private $_specials = array();
       
    26 
       
    27   /**
       
    28    * Tokens defined in RFC 2822 (and some related RFCs).
       
    29    * @var string[]
       
    30    * @access private
       
    31    */
       
    32   private $_grammar = array();
       
    33   
       
    34   /**
       
    35    * Initialize some RFC 2822 (and friends) ABNF grammar definitions.
       
    36    * @access protected
       
    37    */
       
    38   public function __construct()
       
    39   {
       
    40     $this->_specials = array(
       
    41       '(', ')', '<', '>', '[', ']',
       
    42       ':', ';', '@', ',', '.', '"'
       
    43       );
       
    44     
       
    45     /*** Refer to RFC 2822 for ABNF grammar ***/
       
    46     
       
    47     //All basic building blocks
       
    48     $this->_grammar['NO-WS-CTL'] = '[\x01-\x08\x0B\x0C\x0E-\x19\x7F]';
       
    49     $this->_grammar['WSP'] = '[ \t]';
       
    50     $this->_grammar['CRLF'] = '(?:\r\n)';
       
    51     $this->_grammar['FWS'] = '(?:(?:' . $this->_grammar['WSP'] . '*' .
       
    52         $this->_grammar['CRLF'] . ')?' . $this->_grammar['WSP'] . ')';
       
    53     $this->_grammar['text'] = '[\x00-\x08\x0B\x0C\x0E-\x7F]';
       
    54     $this->_grammar['quoted-pair'] = '(?:\\\\' . $this->_grammar['text'] . ')';
       
    55     $this->_grammar['ctext'] = '(?:' . $this->_grammar['NO-WS-CTL'] .
       
    56         '|[\x21-\x27\x2A-\x5B\x5D-\x7E])';
       
    57     //Uses recursive PCRE (?1) -- could be a weak point??
       
    58     $this->_grammar['ccontent'] = '(?:' . $this->_grammar['ctext'] . '|' .
       
    59         $this->_grammar['quoted-pair'] . '|(?1))';
       
    60     $this->_grammar['comment'] = '(\((?:' . $this->_grammar['FWS'] . '|' .
       
    61         $this->_grammar['ccontent']. ')*' . $this->_grammar['FWS'] . '?\))';
       
    62     $this->_grammar['CFWS'] = '(?:(?:' . $this->_grammar['FWS'] . '?' .
       
    63         $this->_grammar['comment'] . ')*(?:(?:' . $this->_grammar['FWS'] . '?' .
       
    64         $this->_grammar['comment'] . ')|' . $this->_grammar['FWS'] . '))';
       
    65     $this->_grammar['qtext'] = '(?:' . $this->_grammar['NO-WS-CTL'] .
       
    66         '|[\x21\x23-\x5B\x5D-\x7E])';
       
    67     $this->_grammar['qcontent'] = '(?:' . $this->_grammar['qtext'] . '|' .
       
    68         $this->_grammar['quoted-pair'] . ')';
       
    69     $this->_grammar['quoted-string'] = '(?:' . $this->_grammar['CFWS'] . '?"' .
       
    70         '(' . $this->_grammar['FWS'] . '?' . $this->_grammar['qcontent'] . ')*' .
       
    71         $this->_grammar['FWS'] . '?"' . $this->_grammar['CFWS'] . '?)';
       
    72     $this->_grammar['atext'] = '[a-zA-Z0-9!#\$%&\'\*\+\-\/=\?\^_`\{\}\|~]';
       
    73     $this->_grammar['atom'] = '(?:' . $this->_grammar['CFWS'] . '?' .
       
    74         $this->_grammar['atext'] . '+' . $this->_grammar['CFWS'] . '?)';
       
    75     $this->_grammar['dot-atom-text'] = '(?:' . $this->_grammar['atext'] . '+' .
       
    76         '(\.' . $this->_grammar['atext'] . '+)*)';
       
    77     $this->_grammar['dot-atom'] = '(?:' . $this->_grammar['CFWS'] . '?' .
       
    78         $this->_grammar['dot-atom-text'] . '+' . $this->_grammar['CFWS'] . '?)';
       
    79     $this->_grammar['word'] = '(?:' . $this->_grammar['atom'] . '|' .
       
    80         $this->_grammar['quoted-string'] . ')';
       
    81     $this->_grammar['phrase'] = '(?:' . $this->_grammar['word'] . '+?)';
       
    82     $this->_grammar['no-fold-quote'] = '(?:"(?:' . $this->_grammar['qtext'] .
       
    83         '|' . $this->_grammar['quoted-pair'] . ')*")';
       
    84     $this->_grammar['dtext'] = '(?:' . $this->_grammar['NO-WS-CTL'] .
       
    85         '|[\x21-\x5A\x5E-\x7E])';
       
    86     $this->_grammar['no-fold-literal'] = '(?:\[(?:' . $this->_grammar['dtext'] .
       
    87         '|' . $this->_grammar['quoted-pair'] . ')*\])';
       
    88     
       
    89     //Message IDs
       
    90     $this->_grammar['id-left'] = '(?:' . $this->_grammar['dot-atom-text'] . '|' .
       
    91         $this->_grammar['no-fold-quote'] . ')';
       
    92     $this->_grammar['id-right'] = '(?:' . $this->_grammar['dot-atom-text'] . '|' .
       
    93         $this->_grammar['no-fold-literal'] . ')';
       
    94     
       
    95     //Addresses, mailboxes and paths
       
    96     $this->_grammar['local-part'] = '(?:' . $this->_grammar['dot-atom'] . '|' .
       
    97         $this->_grammar['quoted-string'] . ')';
       
    98     $this->_grammar['dcontent'] = '(?:' . $this->_grammar['dtext'] . '|' .
       
    99         $this->_grammar['quoted-pair'] . ')';
       
   100     $this->_grammar['domain-literal'] = '(?:' . $this->_grammar['CFWS'] . '?\[(' .
       
   101         $this->_grammar['FWS'] . '?' . $this->_grammar['dcontent'] . ')*?' .
       
   102         $this->_grammar['FWS'] . '?\]' . $this->_grammar['CFWS'] . '?)';
       
   103     $this->_grammar['domain'] = '(?:' . $this->_grammar['dot-atom'] . '|' .
       
   104         $this->_grammar['domain-literal'] . ')';
       
   105     $this->_grammar['addr-spec'] = '(?:' . $this->_grammar['local-part'] . '@' .
       
   106         $this->_grammar['domain'] . ')';
       
   107   }
       
   108   
       
   109   /**
       
   110    * Get the grammar defined for $name token.
       
   111    * @param string $name execatly as written in the RFC
       
   112    * @return string
       
   113    */
       
   114   public function getDefinition($name)
       
   115   {
       
   116     if (array_key_exists($name, $this->_grammar))
       
   117     {
       
   118       return $this->_grammar[$name];
       
   119     }
       
   120     else
       
   121     {
       
   122       throw new Swift_RfcComplianceException(
       
   123         "No such grammar '" . $name . "' defined."
       
   124         );
       
   125     }
       
   126   }
       
   127   
       
   128   /**
       
   129    * Returns the tokens defined in RFC 2822 (and some related RFCs).
       
   130    * @return array
       
   131    */
       
   132   public function getGrammarDefinitions()
       
   133   {
       
   134     return $this->_grammar;
       
   135   }
       
   136   
       
   137   /**
       
   138    * Returns the current special characters used in the syntax which need to be escaped.
       
   139    * @return array
       
   140    */
       
   141   public function getSpecials()
       
   142   {
       
   143     return $this->_specials;
       
   144   }
       
   145   
       
   146   /**
       
   147    * Escape special characters in a string (convert to quoted-pairs).
       
   148    * @param string $token
       
   149    * @param string[] $include additonal chars to escape
       
   150    * @param string[] $exclude chars from escaping
       
   151    * @return string
       
   152    */
       
   153   public function escapeSpecials($token, $include = array(),
       
   154     $exclude = array())
       
   155   {
       
   156     foreach (
       
   157       array_merge(array('\\'), array_diff($this->_specials, $exclude), $include) as $char)
       
   158     {
       
   159       $token = str_replace($char, '\\' . $char, $token);
       
   160     }
       
   161     return $token;
       
   162   }
       
   163 }