PageRenderTime 79ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/app/vendors/Zend/Mail/Part.php

https://github.com/rogerwu99/randomizr
PHP | 520 lines | 219 code | 57 blank | 244 comment | 45 complexity | aa73d3a230cafaf6cc55d6cce2726f51 MD5 | raw file
Possible License(s): MIT, LGPL-3.0
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Mail
  17. * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
  18. * @license http://framework.zend.com/license/new-bsd New BSD License
  19. * @version $Id: Part.php 13591 2009-01-11 09:04:09Z beberlei $
  20. */
  21. /**
  22. * @see Zend_Mime_Decode
  23. */
  24. require_once 'Zend/Mime/Decode.php';
  25. /**
  26. * @see Zend_Mail_Part_Interface
  27. */
  28. require_once 'Zend/Mail/Part/Interface.php';
  29. /**
  30. * @category Zend
  31. * @package Zend_Mail
  32. * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
  33. * @license http://framework.zend.com/license/new-bsd New BSD License
  34. */
  35. class Zend_Mail_Part implements RecursiveIterator, Zend_Mail_Part_Interface
  36. {
  37. /**
  38. * headers of part as array
  39. * @var null|array
  40. */
  41. protected $_headers;
  42. /**
  43. * raw part body
  44. * @var null|string
  45. */
  46. protected $_content;
  47. /**
  48. * toplines as fetched with headers
  49. * @var string
  50. */
  51. protected $_topLines = '';
  52. /**
  53. * parts of multipart message
  54. * @var array
  55. */
  56. protected $_parts = array();
  57. /**
  58. * count of parts of a multipart message
  59. * @var null|int
  60. */
  61. protected $_countParts;
  62. /**
  63. * current position of iterator
  64. * @var int
  65. */
  66. protected $_iterationPos = 1;
  67. /**
  68. * mail handler, if late fetch is active
  69. * @var null|Zend_Mail_Storage_Abstract
  70. */
  71. protected $_mail;
  72. /**
  73. * message number for mail handler
  74. * @var int
  75. */
  76. protected $_messageNum = 0;
  77. /**
  78. * Public constructor
  79. *
  80. * Zend_Mail_Part supports different sources for content. The possible params are:
  81. * - handler a instance of Zend_Mail_Storage_Abstract for late fetch
  82. * - id number of message for handler
  83. * - raw raw content with header and body as string
  84. * - headers headers as array (name => value) or string, if a content part is found it's used as toplines
  85. * - noToplines ignore content found after headers in param 'headers'
  86. * - content content as string
  87. *
  88. * @param array $params full message with or without headers
  89. * @throws Zend_Mail_Exception
  90. */
  91. public function __construct(array $params)
  92. {
  93. if (isset($params['handler'])) {
  94. if (!$params['handler'] instanceof Zend_Mail_Storage_Abstract) {
  95. /**
  96. * @see Zend_Mail_Exception
  97. */
  98. require_once 'Zend/Mail/Exception.php';
  99. throw new Zend_Mail_Exception('handler is not a valid mail handler');
  100. }
  101. if (!isset($params['id'])) {
  102. /**
  103. * @see Zend_Mail_Exception
  104. */
  105. require_once 'Zend/Mail/Exception.php';
  106. throw new Zend_Mail_Exception('need a message id with a handler');
  107. }
  108. $this->_mail = $params['handler'];
  109. $this->_messageNum = $params['id'];
  110. }
  111. if (isset($params['raw'])) {
  112. Zend_Mime_Decode::splitMessage($params['raw'], $this->_headers, $this->_content);
  113. } else if (isset($params['headers'])) {
  114. if (is_array($params['headers'])) {
  115. $this->_headers = $params['headers'];
  116. } else {
  117. if (!empty($params['noToplines'])) {
  118. Zend_Mime_Decode::splitMessage($params['headers'], $this->_headers, $null);
  119. } else {
  120. Zend_Mime_Decode::splitMessage($params['headers'], $this->_headers, $this->_topLines);
  121. }
  122. }
  123. if (isset($params['content'])) {
  124. $this->_content = $params['content'];
  125. }
  126. }
  127. }
  128. /**
  129. * Check if part is a multipart message
  130. *
  131. * @return bool if part is multipart
  132. */
  133. public function isMultipart()
  134. {
  135. try {
  136. return stripos($this->contentType, 'multipart/') === 0;
  137. } catch(Zend_Mail_Exception $e) {
  138. return false;
  139. }
  140. }
  141. /**
  142. * Body of part
  143. *
  144. * If part is multipart the raw content of this part with all sub parts is returned
  145. *
  146. * @return string body
  147. * @throws Zend_Mail_Exception
  148. */
  149. public function getContent()
  150. {
  151. if ($this->_content !== null) {
  152. return $this->_content;
  153. }
  154. if ($this->_mail) {
  155. return $this->_mail->getRawContent($this->_messageNum);
  156. } else {
  157. /**
  158. * @see Zend_Mail_Exception
  159. */
  160. require_once 'Zend/Mail/Exception.php';
  161. throw new Zend_Mail_Exception('no content');
  162. }
  163. }
  164. /**
  165. * Return size of part
  166. *
  167. * Quite simple implemented currently (not decoding). Handle with care.
  168. *
  169. * @return int size
  170. */
  171. public function getSize() {
  172. return strlen($this->getContent());
  173. }
  174. /**
  175. * Cache content and split in parts if multipart
  176. *
  177. * @return null
  178. * @throws Zend_Mail_Exception
  179. */
  180. protected function _cacheContent()
  181. {
  182. // caching content if we can't fetch parts
  183. if ($this->_content === null && $this->_mail) {
  184. $this->_content = $this->_mail->getRawContent($this->_messageNum);
  185. }
  186. if (!$this->isMultipart()) {
  187. return;
  188. }
  189. // split content in parts
  190. $boundary = $this->getHeaderField('content-type', 'boundary');
  191. if (!$boundary) {
  192. /**
  193. * @see Zend_Mail_Exception
  194. */
  195. require_once 'Zend/Mail/Exception.php';
  196. throw new Zend_Mail_Exception('no boundary found in content type to split message');
  197. }
  198. $parts = Zend_Mime_Decode::splitMessageStruct($this->_content, $boundary);
  199. if ($parts === null) {
  200. return;
  201. }
  202. $counter = 1;
  203. foreach ($parts as $part) {
  204. $this->_parts[$counter++] = new self(array('headers' => $part['header'], 'content' => $part['body']));
  205. }
  206. }
  207. /**
  208. * Get part of multipart message
  209. *
  210. * @param int $num number of part starting with 1 for first part
  211. * @return Zend_Mail_Part wanted part
  212. * @throws Zend_Mail_Exception
  213. */
  214. public function getPart($num)
  215. {
  216. if (isset($this->_parts[$num])) {
  217. return $this->_parts[$num];
  218. }
  219. if (!$this->_mail && $this->_content === null) {
  220. /**
  221. * @see Zend_Mail_Exception
  222. */
  223. require_once 'Zend/Mail/Exception.php';
  224. throw new Zend_Mail_Exception('part not found');
  225. }
  226. if ($this->_mail && $this->_mail->hasFetchPart) {
  227. // TODO: fetch part
  228. // return
  229. }
  230. $this->_cacheContent();
  231. if (!isset($this->_parts[$num])) {
  232. /**
  233. * @see Zend_Mail_Exception
  234. */
  235. require_once 'Zend/Mail/Exception.php';
  236. throw new Zend_Mail_Exception('part not found');
  237. }
  238. return $this->_parts[$num];
  239. }
  240. /**
  241. * Count parts of a multipart part
  242. *
  243. * @return int number of sub-parts
  244. */
  245. public function countParts()
  246. {
  247. if ($this->_countParts) {
  248. return $this->_countParts;
  249. }
  250. $this->_countParts = count($this->_parts);
  251. if ($this->_countParts) {
  252. return $this->_countParts;
  253. }
  254. if ($this->_mail && $this->_mail->hasFetchPart) {
  255. // TODO: fetch part
  256. // return
  257. }
  258. $this->_cacheContent();
  259. $this->_countParts = count($this->_parts);
  260. return $this->_countParts;
  261. }
  262. /**
  263. * Get all headers
  264. *
  265. * The returned headers are as saved internally. All names are lowercased. The value is a string or an array
  266. * if a header with the same name occurs more than once.
  267. *
  268. * @return array headers as array(name => value)
  269. */
  270. public function getHeaders()
  271. {
  272. if ($this->_headers === null) {
  273. if (!$this->_mail) {
  274. $this->_headers = array();
  275. } else {
  276. $part = $this->_mail->getRawHeader($this->_messageNum);
  277. Zend_Mime_Decode::splitMessage($part, $this->_headers, $null);
  278. }
  279. }
  280. return $this->_headers;
  281. }
  282. /**
  283. * Get a header in specificed format
  284. *
  285. * Internally headers that occur more than once are saved as array, all other as string. If $format
  286. * is set to string implode is used to concat the values (with Zend_Mime::LINEEND as delim).
  287. *
  288. * @param string $name name of header, matches case-insensitive, but camel-case is replaced with dashes
  289. * @param string $format change type of return value to 'string' or 'array'
  290. * @return string|array value of header in wanted or internal format
  291. * @throws Zend_Mail_Exception
  292. */
  293. public function getHeader($name, $format = null)
  294. {
  295. if ($this->_headers === null) {
  296. $this->getHeaders();
  297. }
  298. $lowerName = strtolower($name);
  299. if ($this->headerExists($name) == false) {
  300. $lowerName = strtolower(preg_replace('%([a-z])([A-Z])%', '\1-\2', $name));
  301. if($this->headerExists($lowerName) == false) {
  302. /**
  303. * @see Zend_Mail_Exception
  304. */
  305. require_once 'Zend/Mail/Exception.php';
  306. throw new Zend_Mail_Exception("no Header with Name $name or $lowerName found");
  307. }
  308. }
  309. $name = $lowerName;
  310. $header = $this->_headers[$name];
  311. switch ($format) {
  312. case 'string':
  313. if (is_array($header)) {
  314. $header = implode(Zend_Mime::LINEEND, $header);
  315. }
  316. break;
  317. case 'array':
  318. $header = (array)$header;
  319. default:
  320. // do nothing
  321. }
  322. return $header;
  323. }
  324. /**
  325. * Check wheater the Mail part has a specific header.
  326. *
  327. * @param string $name
  328. * @return boolean
  329. */
  330. public function headerExists($name)
  331. {
  332. $name = strtolower($name);
  333. if(isset($this->_headers[$name])) {
  334. return true;
  335. } else {
  336. return false;
  337. }
  338. }
  339. /**
  340. * Get a specific field from a header like content type or all fields as array
  341. *
  342. * If the header occurs more than once, only the value from the first header
  343. * is returned.
  344. *
  345. * Throws a Zend_Mail_Exception if the requested header does not exist. If
  346. * the specific header field does not exist, returns null.
  347. *
  348. * @param string $name name of header, like in getHeader()
  349. * @param string $wantedPart the wanted part, default is first, if null an array with all parts is returned
  350. * @param string $firstName key name for the first part
  351. * @return string|array wanted part or all parts as array($firstName => firstPart, partname => value)
  352. * @throws Zend_Exception, Zend_Mail_Exception
  353. */
  354. public function getHeaderField($name, $wantedPart = 0, $firstName = 0) {
  355. return Zend_Mime_Decode::splitHeaderField(current($this->getHeader($name, 'array')), $wantedPart, $firstName);
  356. }
  357. /**
  358. * Getter for mail headers - name is matched in lowercase
  359. *
  360. * This getter is short for Zend_Mail_Part::getHeader($name, 'string')
  361. *
  362. * @see Zend_Mail_Part::getHeader()
  363. *
  364. * @param string $name header name
  365. * @return string value of header
  366. * @throws Zend_Mail_Exception
  367. */
  368. public function __get($name)
  369. {
  370. return $this->getHeader($name, 'string');
  371. }
  372. /**
  373. * Isset magic method proxy to hasHeader
  374. *
  375. * This method is short syntax for Zend_Mail_Part::hasHeader($name);
  376. *
  377. * @see Zend_Mail_Part::hasHeader
  378. *
  379. * @param string
  380. * @return boolean
  381. */
  382. public function __isset($name)
  383. {
  384. return $this->headerExists($name);
  385. }
  386. /**
  387. * magic method to get content of part
  388. *
  389. * @return string content
  390. */
  391. public function __toString()
  392. {
  393. return $this->getContent();
  394. }
  395. /**
  396. * implements RecursiveIterator::hasChildren()
  397. *
  398. * @return bool current element has children/is multipart
  399. */
  400. public function hasChildren()
  401. {
  402. $current = $this->current();
  403. return $current && $current instanceof Zend_Mail_Part && $current->isMultipart();
  404. }
  405. /**
  406. * implements RecursiveIterator::getChildren()
  407. *
  408. * @return Zend_Mail_Part same as self::current()
  409. */
  410. public function getChildren()
  411. {
  412. return $this->current();
  413. }
  414. /**
  415. * implements Iterator::valid()
  416. *
  417. * @return bool check if there's a current element
  418. */
  419. public function valid()
  420. {
  421. if ($this->_countParts === null) {
  422. $this->countParts();
  423. }
  424. return $this->_iterationPos && $this->_iterationPos <= $this->_countParts;
  425. }
  426. /**
  427. * implements Iterator::next()
  428. *
  429. * @return null
  430. */
  431. public function next()
  432. {
  433. ++$this->_iterationPos;
  434. }
  435. /**
  436. * implements Iterator::key()
  437. *
  438. * @return string key/number of current part
  439. */
  440. public function key()
  441. {
  442. return $this->_iterationPos;
  443. }
  444. /**
  445. * implements Iterator::current()
  446. *
  447. * @return Zend_Mail_Part current part
  448. */
  449. public function current()
  450. {
  451. return $this->getPart($this->_iterationPos);
  452. }
  453. /**
  454. * implements Iterator::rewind()
  455. *
  456. * @return null
  457. */
  458. public function rewind()
  459. {
  460. $this->countParts();
  461. $this->_iterationPos = 1;
  462. }
  463. }