_paramEncoder = $paramEncoder; $this->_tokenRe = '(?:[\x21\x23-\x27\x2A\x2B\x2D\x2E\x30-\x39\x41-\x5A\x5E-\x7E]+)'; } /** * Get the type of Header that this instance represents. * @return int * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX * @see TYPE_DATE, TYPE_ID, TYPE_PATH */ public function getFieldType() { return self::TYPE_PARAMETERIZED; } /** * Set the character set used in this Header. * @param string $charset */ public function setCharset($charset) { parent::setCharset($charset); if (isset($this->_paramEncoder)) { $this->_paramEncoder->charsetChanged($charset); } } /** * Set the value of $parameter. * @param string $parameter * @param string $value */ public function setParameter($parameter, $value) { $this->setParameters(array_merge($this->getParameters(), array($parameter => $value))); } /** * Get the value of $parameter. * @return string */ public function getParameter($parameter) { $params = $this->getParameters(); return array_key_exists($parameter, $params) ? $params[$parameter] : null; } /** * Set an associative array of parameter names mapped to values. * @param string[] */ public function setParameters(array $parameters) { $this->clearCachedValueIf($this->_params != $parameters); $this->_params = $parameters; } /** * Returns an associative array of parameter names mapped to values. * @return string[] */ public function getParameters() { return $this->_params; } /** * Get the value of this header prepared for rendering. * @return string */ public function getFieldBody() //TODO: Check caching here { $body = parent::getFieldBody(); foreach ($this->_params as $name => $value) { if (!is_null($value)) { //Add the parameter $body .= '; ' . $this->_createParameter($name, $value); } } return $body; } // -- Protected methods /** * Generate a list of all tokens in the final header. * This doesn't need to be overridden in theory, but it is for implementation * reasons to prevent potential breakage of attributes. * @return string[] * @access protected */ protected function toTokens($string = null) { $tokens = parent::toTokens(parent::getFieldBody()); //Try creating any parameters foreach ($this->_params as $name => $value) { if (!is_null($value)) { //Add the semi-colon separator $tokens[count($tokens)-1] .= ';'; $tokens = array_merge($tokens, $this->generateTokenLines( ' ' . $this->_createParameter($name, $value) )); } } return $tokens; } // -- Private methods /** * Render a RFC 2047 compliant header parameter from the $name and $value. * @param string $name * @param string $value * @return string * @access private */ private function _createParameter($name, $value) { $origValue = $value; $encoded = false; //Allow room for parameter name, indices, "=" and DQUOTEs $maxValueLength = $this->getMaxLineLength() - strlen($name . '=*N"";') - 1; $firstLineOffset = 0; //If it's not already a valid parameter value... if (!preg_match('/^' . $this->_tokenRe . '$/D', $value)) { //TODO: text, or something else?? //... and it's not ascii if (!preg_match('/^' . $this->getGrammar()->getDefinition('text') . '*$/D', $value)) { $encoded = true; //Allow space for the indices, charset and language $maxValueLength = $this->getMaxLineLength() - strlen($name . '*N*="";') - 1; $firstLineOffset = strlen( $this->getCharset() . "'" . $this->getLanguage() . "'" ); } } //Encode if we need to if ($encoded || strlen($value) > $maxValueLength) { if (isset($this->_paramEncoder)) { $value = $this->_paramEncoder->encodeString( $origValue, $firstLineOffset, $maxValueLength ); } else //We have to go against RFC 2183/2231 in some areas for interoperability { $value = $this->getTokenAsEncodedWord($origValue); $encoded = false; } } $valueLines = isset($this->_paramEncoder) ? explode("\r\n", $value) : array($value); //Need to add indices if (count($valueLines) > 1) { $paramLines = array(); foreach ($valueLines as $i => $line) { $paramLines[] = $name . '*' . $i . $this->_getEndOfParameterValue($line, true, $i == 0); } return implode(";\r\n ", $paramLines); } else { return $name . $this->_getEndOfParameterValue( $valueLines[0], $encoded, true ); } } /** * Returns the parameter value from the "=" and beyond. * @param string $value to append * @param boolean $encoded * @param boolean $firstLine * @return string * @access private */ private function _getEndOfParameterValue($value, $encoded = false, $firstLine = false) { if (!preg_match('/^' . $this->_tokenRe . '$/D', $value)) { $value = '"' . $value . '"'; } $prepend = '='; if ($encoded) { $prepend = '*='; if ($firstLine) { $prepend = '*=' . $this->getCharset() . "'" . $this->getLanguage() . "'"; } } return $prepend . $value; } }