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

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