composer package updates
[openemr.git] / vendor / zendframework / zend-mail / src / Storage / Part / File.php
blob81be4bfd8824452a7df95405c5c9bad86c41f62b
1 <?php
2 /**
3 * @see https://github.com/zendframework/zend-mail for the canonical source repository
4 * @copyright Copyright (c) 2005-2018 Zend Technologies USA Inc. (https://www.zend.com)
5 * @license https://github.com/zendframework/zend-mail/blob/master/LICENSE.md New BSD License
6 */
8 namespace Zend\Mail\Storage\Part;
10 use Zend\Mail\Headers;
11 use Zend\Mail\Storage\Part;
13 class File extends Part
15 protected $contentPos = [];
16 protected $partPos = [];
17 protected $fh;
19 /**
20 * Public constructor
22 * This handler supports the following params:
23 * - file filename or open file handler with message content (required)
24 * - startPos start position of message or part in file (default: current position)
25 * - endPos end position of message or part in file (default: end of file)
26 * - EOL end of Line for messages
28 * @param array $params full message with or without headers
29 * @throws Exception\RuntimeException
30 * @throws Exception\InvalidArgumentException
32 public function __construct(array $params)
34 if (empty($params['file'])) {
35 throw new Exception\InvalidArgumentException('no file given in params');
38 if (! is_resource($params['file'])) {
39 $this->fh = fopen($params['file'], 'r');
40 } else {
41 $this->fh = $params['file'];
43 if (! $this->fh) {
44 throw new Exception\RuntimeException('could not open file');
46 if (isset($params['startPos'])) {
47 fseek($this->fh, $params['startPos']);
49 $header = '';
50 $endPos = isset($params['endPos']) ? $params['endPos'] : null;
51 while (($endPos === null || ftell($this->fh) < $endPos) && trim($line = fgets($this->fh))) {
52 $header .= $line;
55 if (isset($params['EOL'])) {
56 $this->headers = Headers::fromString($header, $params['EOL']);
57 } else {
58 $this->headers = Headers::fromString($header);
61 $this->contentPos[0] = ftell($this->fh);
62 if ($endPos !== null) {
63 $this->contentPos[1] = $endPos;
64 } else {
65 fseek($this->fh, 0, SEEK_END);
66 $this->contentPos[1] = ftell($this->fh);
68 if (! $this->isMultipart()) {
69 return;
72 $boundary = $this->getHeaderField('content-type', 'boundary');
73 if (! $boundary) {
74 throw new Exception\RuntimeException('no boundary found in content type to split message');
77 $part = [];
78 $pos = $this->contentPos[0];
79 fseek($this->fh, $pos);
80 while (! feof($this->fh) && ($endPos === null || $pos < $endPos)) {
81 $line = fgets($this->fh);
82 if ($line === false) {
83 if (feof($this->fh)) {
84 break;
86 throw new Exception\RuntimeException('error reading file');
89 $lastPos = $pos;
90 $pos = ftell($this->fh);
91 $line = trim($line);
93 if ($line == '--' . $boundary) {
94 if ($part) {
95 // not first part
96 $part[1] = $lastPos;
97 $this->partPos[] = $part;
99 $part = [$pos];
100 } elseif ($line == '--' . $boundary . '--') {
101 $part[1] = $lastPos;
102 $this->partPos[] = $part;
103 break;
106 $this->countParts = count($this->partPos);
110 * Body of part
112 * If part is multipart the raw content of this part with all sub parts is returned
114 * @param resource $stream Optional
115 * @return string body
117 public function getContent($stream = null)
119 fseek($this->fh, $this->contentPos[0]);
120 if ($stream !== null) {
121 return stream_copy_to_stream($this->fh, $stream, $this->contentPos[1] - $this->contentPos[0]);
123 $length = $this->contentPos[1] - $this->contentPos[0];
124 return $length < 1 ? '' : fread($this->fh, $length);
128 * Return size of part
130 * Quite simple implemented currently (not decoding). Handle with care.
132 * @return int size
134 public function getSize()
136 return $this->contentPos[1] - $this->contentPos[0];
140 * Get part of multipart message
142 * @param int $num number of part starting with 1 for first part
143 * @throws Exception\RuntimeException
144 * @return Part wanted part
146 public function getPart($num)
148 --$num;
149 if (! isset($this->partPos[$num])) {
150 throw new Exception\RuntimeException('part not found');
153 return new static(['file' => $this->fh, 'startPos' => $this->partPos[$num][0],
154 'endPos' => $this->partPos[$num][1]]);