vendor/swiftmailer/lib/classes/Swift/Mime/Headers/ParameterizedHeader.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 /**
       
    13  * An abstract base MIME Header.
       
    14  * @package Swift
       
    15  * @subpackage Mime
       
    16  * @author Chris Corbyn
       
    17  */
       
    18 class Swift_Mime_Headers_ParameterizedHeader
       
    19   extends Swift_Mime_Headers_UnstructuredHeader
       
    20   implements Swift_Mime_ParameterizedHeader
       
    21 {
       
    22   
       
    23   /**
       
    24    * The Encoder used to encode the parameters.
       
    25    * @var Swift_Encoder
       
    26    * @access private
       
    27    */
       
    28   private $_paramEncoder;
       
    29   
       
    30   /**
       
    31    * The parameters as an associative array.
       
    32    * @var string[]
       
    33    * @access private
       
    34    */
       
    35   private $_params = array();
       
    36   
       
    37   /**
       
    38    * RFC 2231's definition of a token.
       
    39    * @var string
       
    40    * @access private
       
    41    */
       
    42   private $_tokenRe;
       
    43   
       
    44   /**
       
    45    * Creates a new ParameterizedHeader with $name.
       
    46    * @param string $name
       
    47    * @param Swift_Mime_HeaderEncoder $encoder
       
    48    * @param Swift_Encoder $paramEncoder, optional
       
    49    * @param Swift_Mime_Grammar $grammar
       
    50    */ 
       
    51   public function __construct($name, Swift_Mime_HeaderEncoder $encoder,
       
    52     Swift_Encoder $paramEncoder = null, Swift_Mime_Grammar $grammar)
       
    53   {
       
    54     parent::__construct($name, $encoder, $grammar);
       
    55     $this->_paramEncoder = $paramEncoder;
       
    56     $this->_tokenRe = '(?:[\x21\x23-\x27\x2A\x2B\x2D\x2E\x30-\x39\x41-\x5A\x5E-\x7E]+)';
       
    57   }
       
    58   
       
    59   /**
       
    60    * Get the type of Header that this instance represents.
       
    61    * @return int
       
    62    * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX
       
    63    * @see TYPE_DATE, TYPE_ID, TYPE_PATH
       
    64    */
       
    65   public function getFieldType()
       
    66   {
       
    67     return self::TYPE_PARAMETERIZED;
       
    68   }
       
    69   
       
    70   /**
       
    71    * Set the character set used in this Header.
       
    72    * @param string $charset
       
    73    */
       
    74   public function setCharset($charset)
       
    75   {
       
    76     parent::setCharset($charset);
       
    77     if (isset($this->_paramEncoder))
       
    78     {
       
    79       $this->_paramEncoder->charsetChanged($charset);
       
    80     }
       
    81   }
       
    82   
       
    83   /**
       
    84    * Set the value of $parameter.
       
    85    * @param string $parameter
       
    86    * @param string $value
       
    87    */
       
    88   public function setParameter($parameter, $value)
       
    89   {
       
    90     $this->setParameters(array_merge($this->getParameters(), array($parameter => $value)));
       
    91   }
       
    92   
       
    93   /**
       
    94    * Get the value of $parameter.
       
    95    * @return string
       
    96    */
       
    97   public function getParameter($parameter)
       
    98   {
       
    99     $params = $this->getParameters();
       
   100     return array_key_exists($parameter, $params)
       
   101       ? $params[$parameter]
       
   102       : null;
       
   103   }
       
   104   
       
   105   /**
       
   106    * Set an associative array of parameter names mapped to values.
       
   107    * @param string[]
       
   108    */
       
   109   public function setParameters(array $parameters)
       
   110   {
       
   111     $this->clearCachedValueIf($this->_params != $parameters);
       
   112     $this->_params = $parameters;
       
   113   }
       
   114   
       
   115   /**
       
   116    * Returns an associative array of parameter names mapped to values.
       
   117    * @return string[]
       
   118    */
       
   119   public function getParameters()
       
   120   {
       
   121     return $this->_params;
       
   122   }
       
   123   
       
   124   /**
       
   125    * Get the value of this header prepared for rendering.
       
   126    * @return string
       
   127    */
       
   128   public function getFieldBody() //TODO: Check caching here
       
   129   {
       
   130     $body = parent::getFieldBody();
       
   131     foreach ($this->_params as $name => $value)
       
   132     {
       
   133       if (!is_null($value))
       
   134       {
       
   135         //Add the parameter
       
   136         $body .= '; ' . $this->_createParameter($name, $value);
       
   137       }
       
   138     }
       
   139     return $body;
       
   140   }
       
   141   
       
   142   // -- Protected methods
       
   143   
       
   144   /**
       
   145    * Generate a list of all tokens in the final header.
       
   146    * This doesn't need to be overridden in theory, but it is for implementation
       
   147    * reasons to prevent potential breakage of attributes.
       
   148    * @return string[]
       
   149    * @access protected
       
   150    */
       
   151   protected function toTokens($string = null)
       
   152   {
       
   153     $tokens = parent::toTokens(parent::getFieldBody());
       
   154     
       
   155     //Try creating any parameters
       
   156     foreach ($this->_params as $name => $value)
       
   157     {
       
   158       if (!is_null($value))
       
   159       {
       
   160         //Add the semi-colon separator
       
   161         $tokens[count($tokens)-1] .= ';';
       
   162         $tokens = array_merge($tokens, $this->generateTokenLines(
       
   163           ' ' . $this->_createParameter($name, $value)
       
   164           ));
       
   165       }
       
   166     }
       
   167     
       
   168     return $tokens;
       
   169   }
       
   170   
       
   171   // -- Private methods
       
   172   
       
   173   /**
       
   174    * Render a RFC 2047 compliant header parameter from the $name and $value.
       
   175    * @param string $name
       
   176    * @param string $value
       
   177    * @return string
       
   178    * @access private
       
   179    */
       
   180   private function _createParameter($name, $value)
       
   181   {
       
   182     $origValue = $value;
       
   183     
       
   184     $encoded = false;
       
   185     //Allow room for parameter name, indices, "=" and DQUOTEs
       
   186     $maxValueLength = $this->getMaxLineLength() - strlen($name . '=*N"";') - 1;
       
   187     $firstLineOffset = 0;
       
   188     
       
   189     //If it's not already a valid parameter value...
       
   190     if (!preg_match('/^' . $this->_tokenRe . '$/D', $value))
       
   191     {
       
   192       //TODO: text, or something else??
       
   193       //... and it's not ascii
       
   194       if (!preg_match('/^' . $this->getGrammar()->getDefinition('text') . '*$/D', $value))
       
   195       {
       
   196         $encoded = true;
       
   197         //Allow space for the indices, charset and language
       
   198         $maxValueLength = $this->getMaxLineLength() - strlen($name . '*N*="";') - 1;
       
   199         $firstLineOffset = strlen(
       
   200           $this->getCharset() . "'" . $this->getLanguage() . "'"
       
   201           );
       
   202       }
       
   203     }
       
   204     
       
   205     //Encode if we need to
       
   206     if ($encoded || strlen($value) > $maxValueLength)
       
   207     {
       
   208       if (isset($this->_paramEncoder))
       
   209       {
       
   210         $value = $this->_paramEncoder->encodeString(
       
   211           $origValue, $firstLineOffset, $maxValueLength
       
   212           );
       
   213       }
       
   214       else //We have to go against RFC 2183/2231 in some areas for interoperability
       
   215       {
       
   216         $value = $this->getTokenAsEncodedWord($origValue);
       
   217         $encoded = false;
       
   218       }
       
   219     }
       
   220     
       
   221     $valueLines = isset($this->_paramEncoder) ? explode("\r\n", $value) : array($value);
       
   222     
       
   223     //Need to add indices
       
   224     if (count($valueLines) > 1)
       
   225     {
       
   226       $paramLines = array();
       
   227       foreach ($valueLines as $i => $line)
       
   228       {
       
   229         $paramLines[] = $name . '*' . $i .
       
   230           $this->_getEndOfParameterValue($line, $encoded, $i == 0);
       
   231       }
       
   232       return implode(";\r\n ", $paramLines);
       
   233     }
       
   234     else
       
   235     {
       
   236       return $name . $this->_getEndOfParameterValue(
       
   237         $valueLines[0], $encoded, true
       
   238         );
       
   239     }
       
   240   }
       
   241   
       
   242   /**
       
   243    * Returns the parameter value from the "=" and beyond.
       
   244    * @param string $value to append
       
   245    * @param boolean $encoded
       
   246    * @param boolean $firstLine
       
   247    * @return string
       
   248    * @access private
       
   249    */
       
   250   private function _getEndOfParameterValue($value, $encoded = false, $firstLine = false)
       
   251   {
       
   252     if (!preg_match('/^' . $this->_tokenRe . '$/D', $value))
       
   253     {
       
   254       $value = '"' . $value . '"';
       
   255     }
       
   256     $prepend = '=';
       
   257     if ($encoded)
       
   258     {
       
   259       $prepend = '*=';
       
   260       if ($firstLine)
       
   261       {
       
   262         $prepend = '*=' . $this->getCharset() . "'" . $this->getLanguage() .
       
   263           "'";
       
   264       }
       
   265     }
       
   266     return $prepend . $value;
       
   267   }
       
   268   
       
   269 }