[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Copyright 2008-2014 Horde LLC (http://www.horde.org/) 4 * 5 * getBaseSubject() code adapted from imap-base-subject.c (Dovecot 1.2) 6 * Original code released under the LGPL-2.1 7 * Copyright (c) 2002-2008 Timo Sirainen <tss@iki.fi> 8 * 9 * See the enclosed file COPYING for license information (LGPL). If you 10 * did not receive this file, see http://www.horde.org/licenses/lgpl21. 11 * 12 * @category Horde 13 * @copyright 2002-2008 Timo Sirainen 14 * @copyright 2008-2014 Horde LLC 15 * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 16 * @package Imap_Client 17 */ 18 19 /** 20 * Determines the "base subject" of a string (RFC 5256 [2.1]). 21 * 22 * @author Timo Sirainen <tss@iki.fi> 23 * @author Michael Slusarz <slusarz@horde.org> 24 * @category Horde 25 * @copyright 2002-2008 Timo Sirainen 26 * @copyright 2011-2014 Horde LLC 27 * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 28 * @package Imap_Client 29 */ 30 class Horde_Imap_Client_Data_BaseSubject 31 { 32 /** 33 * The base subject. 34 * 35 * @var string 36 */ 37 protected $_subject; 38 39 /** 40 * Constructor. 41 * 42 * @param string $str The subject string. 43 * @param array $opts Additional options: 44 * - keepblob: (boolean) Don't remove any "blob" information (i.e. text 45 * leading text between square brackets) from string. 46 * 47 * @return string The cleaned up subject string. 48 */ 49 public function __construct($str, array $opts = array()) 50 { 51 // Rule 1a: MIME decode. 52 $str = Horde_Mime::decode($str); 53 54 // Rule 1b: Remove superfluous whitespace. 55 $str = preg_replace("/[\t\r\n ]+/", ' ', $str); 56 57 do { 58 /* (2) Remove all trailing text of the subject that matches the 59 * the subj-trailer ABNF, repeat until no more matches are 60 * possible. */ 61 $str = preg_replace("/(?:\s*\(fwd\)\s*)+$/i", '', $str); 62 63 do { 64 /* (3) Remove all prefix text of the subject that matches the 65 * subj-leader ABNF. */ 66 $found = $this->_removeSubjLeader($str, !empty($opts['keepblob'])); 67 68 /* (4) If there is prefix text of the subject that matches 69 * the subj-blob ABNF, and removing that prefix leaves a 70 * non-empty subj-base, then remove the prefix text. */ 71 $found = (empty($opts['keepblob']) && $this->_removeBlobWhenNonempty($str)) || $found; 72 73 /* (5) Repeat (3) and (4) until no matches remain. */ 74 } while ($found); 75 76 /* (6) If the resulting text begins with the subj-fwd-hdr ABNF and 77 * ends with the subj-fwd-trl ABNF, remove the subj-fwd-hdr and 78 * subj-fwd-trl and repeat from step (2). */ 79 } while ($this->_removeSubjFwdHdr($str)); 80 81 $this->_subject = strval($str); 82 } 83 84 /** 85 * Return the "base subject" defined in RFC 5256 [2.1]. 86 * 87 * @return string The base subject. 88 */ 89 public function __toString() 90 { 91 return $this->_subject; 92 } 93 94 /** 95 * Remove all prefix text of the subject that matches the subj-leader 96 * ABNF. 97 * 98 * @param string &$str The subject string. 99 * @param boolean $keepblob Remove blob information? 100 * 101 * @return boolean True if string was altered. 102 */ 103 protected function _removeSubjLeader(&$str, $keepblob = false) 104 { 105 $ret = false; 106 107 if (!strlen($str)) { 108 return $ret; 109 } 110 111 if ($len = strspn($str, " \t")) { 112 $str = substr($str, $len); 113 $ret = true; 114 } 115 116 $i = 0; 117 118 if (!$keepblob) { 119 while (isset($str[$i]) && ($str[$i] === '[')) { 120 if (($i = $this->_removeBlob($str, $i)) === false) { 121 return $ret; 122 } 123 } 124 } 125 126 if (stripos($str, 're', $i) === 0) { 127 $i += 2; 128 } elseif (stripos($str, 'fwd', $i) === 0) { 129 $i += 3; 130 } elseif (stripos($str, 'fw', $i) === 0) { 131 $i += 2; 132 } else { 133 return $ret; 134 } 135 136 $i += strspn($str, " \t", $i); 137 138 if (!$keepblob) { 139 while (isset($str[$i]) && ($str[$i] === '[')) { 140 if (($i = $this->_removeBlob($str, $i)) === false) { 141 return $ret; 142 } 143 } 144 } 145 146 if (!isset($str[$i]) || ($str[$i] !== ':')) { 147 return $ret; 148 } 149 150 $str = substr($str, ++$i); 151 152 return true; 153 } 154 155 /** 156 * Remove "[...]" text. 157 * 158 * @param string $str The subject string. 159 * @param integer $i Current position. 160 * 161 * @return boolean|integer False if blob was not found, otherwise the 162 * string position of the first non-blob char. 163 */ 164 protected function _removeBlob($str, $i) 165 { 166 if ($str[$i] !== '[') { 167 return false; 168 } 169 170 ++$i; 171 172 for ($cnt = strlen($str); $i < $cnt; ++$i) { 173 if ($str[$i] === ']') { 174 break; 175 } 176 177 if ($str[$i] === '[') { 178 return false; 179 } 180 } 181 182 if ($i === ($cnt - 1)) { 183 return false; 184 } 185 186 ++$i; 187 188 if ($str[$i] === ' ') { 189 ++$i; 190 } 191 192 return $i; 193 } 194 195 /** 196 * Remove "[...]" text if it doesn't result in the subject becoming 197 * empty. 198 * 199 * @param string &$str The subject string. 200 * 201 * @return boolean True if string was altered. 202 */ 203 protected function _removeBlobWhenNonempty(&$str) 204 { 205 if ($str && 206 ($str[0] === '[') && 207 (($i = $this->_removeBlob($str, 0)) !== false) && 208 ($i !== strlen($str))) { 209 $str = substr($str, $i); 210 return true; 211 } 212 213 return false; 214 } 215 216 /** 217 * Remove a "[fwd: ... ]" string. 218 * 219 * @param string &$str The subject string. 220 * 221 * @return boolean True if string was altered. 222 */ 223 protected function _removeSubjFwdHdr(&$str) 224 { 225 if ((stripos($str, '[fwd:') !== 0) || (substr($str, -1) !== ']')) { 226 return false; 227 } 228 229 $str = substr($str, 5, -1); 230 return true; 231 } 232 233 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |