From f87b1b613de28099bdb44f8f741aec344bd93bdb Mon Sep 17 00:00:00 2001 From: Michael M Slusarz Date: Fri, 10 Sep 2010 12:22:15 -0600 Subject: [PATCH] Have Horde_Mime_Headers implement Serializable Make the internal representation of the header data a bit smaller to aid in making serialized representation as small as possible. --- framework/Mime/lib/Horde/Mime/Headers.php | 89 ++++++++++++++++++++------ framework/Mime/package.xml | 1 + framework/Mime/test/Horde/Mime/HeadersTest.php | 41 ++++++++++++ 3 files changed, 112 insertions(+), 19 deletions(-) create mode 100644 framework/Mime/test/Horde/Mime/HeadersTest.php diff --git a/framework/Mime/lib/Horde/Mime/Headers.php b/framework/Mime/lib/Horde/Mime/Headers.php index 24af6b0d5..c202df983 100644 --- a/framework/Mime/lib/Horde/Mime/Headers.php +++ b/framework/Mime/lib/Horde/Mime/Headers.php @@ -13,8 +13,11 @@ * @license http://www.fsf.org/copyleft/lgpl.html LGPL * @package Mime */ -class Horde_Mime_Headers +class Horde_Mime_Headers implements Serializable { + /* Serialized version. */ + const VERSION = 1; + /* Constants for getValue(). */ const VALUE_STRING = 1; const VALUE_BASE = 2; @@ -31,6 +34,14 @@ class Horde_Mime_Headers /** * The internal headers array. * + * Keys are the lowercase header name. + * Values are: + *
+     * 'h' - The case-sensitive header name.
+     * 'p' - Parameters for this header.
+     * 'v' - The value of the header.
+     * 
+ * * @var array */ protected $_headers = array(); @@ -76,7 +87,7 @@ class Horde_Mime_Headers $ret = array(); foreach ($this->_headers as $header => $ob) { - $val = is_array($ob['value']) ? $ob['value'] : array($ob['value']); + $val = is_array($ob['v']) ? $ob['v'] : array($ob['v']); foreach (array_keys($val) as $key) { if (in_array($header, $address_keys) ) { @@ -86,10 +97,10 @@ class Horde_Mime_Headers } catch (Horde_Mime_Exception $e) { $text = $val[$key]; } - } elseif (in_array($header, $mime) && !empty($ob['params'])) { + } elseif (in_array($header, $mime) && !empty($ob['p'])) { /* MIME encoded headers (RFC 2231). */ $text = $val[$key]; - foreach ($ob['params'] as $name => $param) { + foreach ($ob['p'] as $name => $param) { foreach (Horde_Mime::encodeParam($name, $param, $charset, array('escape' => true)) as $name2 => $param2) { $text .= '; ' . $name2 . '=' . $param2; } @@ -102,14 +113,14 @@ class Horde_Mime_Headers if (empty($options['nowrap'])) { /* Remove any existing linebreaks and wrap the line. */ - $header_text = $ob['header'] . ': '; + $header_text = $ob['h'] . ': '; $text = ltrim(substr(wordwrap($header_text . strtr(trim($text), array("\r" => '', "\n" => '')), 76, $this->_eol . ' '), strlen($header_text))); } $val[$key] = $text; } - $ret[$ob['header']] = (count($val) == 1) ? reset($val) : $val; + $ret[$ob['h']] = (count($val) == 1) ? reset($val) : $val; } return $ret; @@ -284,8 +295,9 @@ class Horde_Mime_Headers $lcHeader = Horde_String::lower($header); if (!isset($this->_headers[$lcHeader])) { - $this->_headers[$lcHeader] = array(); - $this->_headers[$lcHeader]['header'] = $header; + $this->_headers[$lcHeader] = array( + 'h' => $header + ); } $ptr = &$this->_headers[$lcHeader]; @@ -302,17 +314,17 @@ class Horde_Mime_Headers } } - if (isset($ptr['value'])) { - if (!is_array($ptr['value'])) { - $ptr['value'] = array($ptr['value']); + if (isset($ptr['v'])) { + if (!is_array($ptr['v'])) { + $ptr['v'] = array($ptr['v']); } - $ptr['value'][] = $value; + $ptr['v'][] = $value; } else { - $ptr['value'] = $value; + $ptr['v'] = $value; } if (!empty($options['params'])) { - $ptr['params'] = $options['params']; + $ptr['p'] = $options['params']; } } @@ -380,7 +392,7 @@ class Horde_Mime_Headers { $lcHeader = Horde_String::lower($header); return (isset($this->_headers[$lcHeader])) - ? $this->_headers[$lcHeader]['header'] + ? $this->_headers[$lcHeader]['h'] : null; } @@ -417,10 +429,10 @@ class Horde_Mime_Headers } $ptr = &$this->_headers[$header]; - $base = (is_array($ptr['value']) && in_array($header, $this->singleFields(true))) - ? $ptr['value'][0] - : $ptr['value']; - $params = isset($ptr['params']) ? $ptr['params'] : array(); + $base = (is_array($ptr['v']) && in_array($header, $this->singleFields(true))) + ? $ptr['v'][0] + : $ptr['v']; + $params = isset($ptr['p']) ? $ptr['p'] : array(); switch ($type) { case self::VALUE_BASE: @@ -615,4 +627,43 @@ class Horde_Mime_Headers return $headers; } + /* Serializable methods. */ + + /** + * Serialization. + * + * @return string Serialized data. + */ + public function serialize() + { + return serialize(array( + // Serialized data ID. + self::VERSION, + $this->_headers, + $this->_eol, + $this->_agent + )); + } + + /** + * Unserialization. + * + * @param string $data Serialized data. + * + * @throws Exception + */ + public function unserialize($data) + { + $data = @unserialize($data); + if (!is_array($data) || + !isset($data[0]) || + ($data[0] != self::VERSION)) { + throw new Exception('Cache version change'); + } + + $this->_headers = $data[1]; + $this->_eol = $data[2]; + $this->_agent = $data[3]; + } + } diff --git a/framework/Mime/package.xml b/framework/Mime/package.xml index 39c83f2ef..6aa706dac 100644 --- a/framework/Mime/package.xml +++ b/framework/Mime/package.xml @@ -75,6 +75,7 @@ http://pear.php.net/dtd/package-2.0.xsd"> + diff --git a/framework/Mime/test/Horde/Mime/HeadersTest.php b/framework/Mime/test/Horde/Mime/HeadersTest.php new file mode 100644 index 000000000..d438a5254 --- /dev/null +++ b/framework/Mime/test/Horde/Mime/HeadersTest.php @@ -0,0 +1,41 @@ + + * @category Horde + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @package Mime + * @subpackage UnitTests + */ + +/** + * @author Michael Slusarz + * @category Horde + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @package Mime + * @subpackage UnitTests + */ +class Horde_Mime_HeadersTest extends PHPUnit_Framework_TestCase +{ + public function testSerialize() + { + $hdrs = new Horde_Mime_Headers(); + $hdrs->addHeader('Subject', 'My Subject'); + $hdrs->addHeader('To', 'recipient@example.com'); + $hdrs->addHeader('Cc', 'null@example.com'); + $hdrs->addHeader('Bcc', 'invisible@example.com'); + $hdrs->addHeader('From', 'sender@example.com'); + + $stored = serialize($hdrs); + $hdrs2 = unserialize($stored); + + $this->assertEquals( + 'null@example.com', + $hdrs2->getValue('cc') + ); + } + +} -- 2.11.0