/library/Zend/Mail/Part/File.php

https://github.com/snippet/zf2 · PHP · 177 lines · 96 code · 16 blank · 65 comment · 25 complexity · a93fd44f89ff62eea2b698bc524bd081 MD5 · raw file

  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-2010 Zend Technologies USA Inc. (http://www.zend.com)
  18. * @license http://framework.zend.com/license/new-bsd New BSD License
  19. * @version $Id$
  20. */
  21. /**
  22. * @namespace
  23. */
  24. namespace Zend\Mail\Part;
  25. use Zend\Mail;
  26. use Zend\Mime;
  27. /**
  28. * @uses \Zend\Mail\Exception
  29. * @uses \Zend\Mail\Part\Part
  30. * @uses \Zend\Mime\Decode
  31. * @category Zend
  32. * @package Zend_Mail
  33. * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  34. * @license http://framework.zend.com/license/new-bsd New BSD License
  35. */
  36. class File extends Part
  37. {
  38. protected $_contentPos = array();
  39. protected $_partPos = array();
  40. protected $_fh;
  41. /**
  42. * Public constructor
  43. *
  44. * This handler supports the following params:
  45. * - file filename or open file handler with message content (required)
  46. * - startPos start position of message or part in file (default: current position)
  47. * - endPos end position of message or part in file (default: end of file)
  48. *
  49. * @param array $params full message with or without headers
  50. * @throws \Zend\Mail\Exception
  51. */
  52. public function __construct(array $params)
  53. {
  54. if (empty($params['file'])) {
  55. throw new Mail\Exception('no file given in params');
  56. }
  57. if (!is_resource($params['file'])) {
  58. $this->_fh = fopen($params['file'], 'r');
  59. } else {
  60. $this->_fh = $params['file'];
  61. }
  62. if (!$this->_fh) {
  63. throw new Mail\Exception('could not open file');
  64. }
  65. if (isset($params['startPos'])) {
  66. fseek($this->_fh, $params['startPos']);
  67. }
  68. $header = '';
  69. $endPos = isset($params['endPos']) ? $params['endPos'] : null;
  70. while (($endPos === null || ftell($this->_fh) < $endPos) && trim($line = fgets($this->_fh))) {
  71. $header .= $line;
  72. }
  73. $body = null; // "Declare" variable since it's passed by reference
  74. Mime\Decode::splitMessage($header, $this->_headers, $body);
  75. $this->_contentPos[0] = ftell($this->_fh);
  76. if ($endPos !== null) {
  77. $this->_contentPos[1] = $endPos;
  78. } else {
  79. fseek($this->_fh, 0, SEEK_END);
  80. $this->_contentPos[1] = ftell($this->_fh);
  81. }
  82. if (!$this->isMultipart()) {
  83. return;
  84. }
  85. $boundary = $this->getHeaderField('content-type', 'boundary');
  86. if (!$boundary) {
  87. throw new Mail\Exception('no boundary found in content type to split message');
  88. }
  89. $part = array();
  90. $pos = $this->_contentPos[0];
  91. fseek($this->_fh, $pos);
  92. while (!feof($this->_fh) && ($endPos === null || $pos < $endPos)) {
  93. $line = fgets($this->_fh);
  94. if ($line === false) {
  95. if (feof($this->_fh)) {
  96. break;
  97. }
  98. throw new Mail\Exception('error reading file');
  99. }
  100. $lastPos = $pos;
  101. $pos = ftell($this->_fh);
  102. $line = trim($line);
  103. if ($line == '--' . $boundary) {
  104. if ($part) {
  105. // not first part
  106. $part[1] = $lastPos;
  107. $this->_partPos[] = $part;
  108. }
  109. $part = array($pos);
  110. } else if ($line == '--' . $boundary . '--') {
  111. $part[1] = $lastPos;
  112. $this->_partPos[] = $part;
  113. break;
  114. }
  115. }
  116. $this->_countParts = count($this->_partPos);
  117. }
  118. /**
  119. * Body of part
  120. *
  121. * If part is multipart the raw content of this part with all sub parts is returned
  122. *
  123. * @return string body
  124. * @throws \Zend\Mail\Exception
  125. */
  126. public function getContent($stream = null)
  127. {
  128. fseek($this->_fh, $this->_contentPos[0]);
  129. if ($stream !== null) {
  130. return stream_copy_to_stream($this->_fh, $stream, $this->_contentPos[1] - $this->_contentPos[0]);
  131. }
  132. $length = $this->_contentPos[1] - $this->_contentPos[0];
  133. return $length < 1 ? '' : fread($this->_fh, $length);
  134. }
  135. /**
  136. * Return size of part
  137. *
  138. * Quite simple implemented currently (not decoding). Handle with care.
  139. *
  140. * @return int size
  141. */
  142. public function getSize() {
  143. return $this->_contentPos[1] - $this->_contentPos[0];
  144. }
  145. /**
  146. * Get part of multipart message
  147. *
  148. * @param int $num number of part starting with 1 for first part
  149. * @return \Zend\Mail\Part\Part wanted part
  150. * @throws \Zend\Mail\Exception
  151. */
  152. public function getPart($num)
  153. {
  154. --$num;
  155. if (!isset($this->_partPos[$num])) {
  156. throw new Mail\Exception('part not found');
  157. }
  158. return new self(array('file' => $this->_fh, 'startPos' => $this->_partPos[$num][0],
  159. 'endPos' => $this->_partPos[$num][1]));
  160. }
  161. }