Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
Decode.php
Go to the documentation of this file.
1 <?php
25 #require_once 'Zend/Mime.php';
26 
34 {
45  public static function splitMime($body, $boundary)
46  {
47  // TODO: we're ignoring \r for now - is this function fast enough and is it safe to asume noone needs \r?
48  $body = str_replace("\r", '', $body);
49 
50  $start = 0;
51  $res = array();
52  // find every mime part limiter and cut out the
53  // string before it.
54  // the part before the first boundary string is discarded:
55  $p = strpos($body, '--' . $boundary . "\n", $start);
56  if ($p === false) {
57  // no parts found!
58  return array();
59  }
60 
61  // position after first boundary line
62  $start = $p + 3 + strlen($boundary);
63 
64  while (($p = strpos($body, '--' . $boundary . "\n", $start)) !== false) {
65  $res[] = substr($body, $start, $p-$start);
66  $start = $p + 3 + strlen($boundary);
67  }
68 
69  // no more parts, find end boundary
70  $p = strpos($body, '--' . $boundary . '--', $start);
71  if ($p === false) {
72  throw new Zend_Exception('Not a valid Mime Message: End Missing');
73  }
74 
75  // the remaining part also needs to be parsed:
76  $res[] = substr($body, $start, $p - $start);
77 
78  return $res;
79  }
80 
91  public static function splitMessageStruct(
92  $message, $boundary, $EOL = Zend_Mime::LINEEND
93  )
94  {
95  $parts = self::splitMime($message, $boundary);
96  if (count($parts) <= 0) {
97  return null;
98  }
99  $result = array();
100  foreach ($parts as $part) {
101  self::splitMessage($part, $headers, $body, $EOL);
102  $result[] = array(
103  'header' => $headers,
104  'body' => $body
105  );
106  }
107 
108  return $result;
109  }
110 
123  public static function splitMessage(
124  $message, &$headers, &$body, $EOL = Zend_Mime::LINEEND
125  )
126  {
127  // check for valid header at first line
128  $firstline = strtok($message, "\n");
129  if (!preg_match('%^[^\s]+[^:]*:%', $firstline)) {
130  $headers = array();
131  // TODO: we're ignoring \r for now - is this function fast enough and is it safe to asume noone needs \r?
132  $body = str_replace(
133  array(
134  "\r",
135  "\n"
136  ), array(
137  '',
138  $EOL
139  ), $message
140  );
141 
142  return;
143  }
144 
145  // find an empty line between headers and body
146  // default is set new line
147  if (strpos($message, $EOL . $EOL)) {
148  list($headers, $body) = explode($EOL . $EOL, $message, 2);
149  // next is the standard new line
150  } else {
151  if ($EOL != "\r\n" && strpos($message, "\r\n\r\n")) {
152  list($headers, $body) = explode("\r\n\r\n", $message, 2);
153  // next is the other "standard" new line
154  } else {
155  if ($EOL != "\n" && strpos($message, "\n\n")) {
156  list($headers, $body) = explode("\n\n", $message, 2);
157  // at last resort find anything that looks like a new line
158  } else {
159  @list($headers, $body) =
160  @preg_split("%([\r\n]+)\\1%U", $message, 2);
161  }
162  }
163  }
164 
165  $headers = iconv_mime_decode_headers(
166  $headers, ICONV_MIME_DECODE_CONTINUE_ON_ERROR
167  );
168 
169  if ($headers === false) {
170  // an error occurs during the decoding
171  return;
172  }
173 
174  // normalize header names
175  foreach ($headers as $name => $header) {
176  $lower = strtolower($name);
177  if ($lower == $name) {
178  continue;
179  }
180  unset($headers[$name]);
181  if (!isset($headers[$lower])) {
182  $headers[$lower] = $header;
183  continue;
184  }
185  if (is_array($headers[$lower])) {
186  $headers[$lower][] = $header;
187  continue;
188  }
189  $headers[$lower] = array(
190  $headers[$lower],
191  $header
192  );
193  }
194  }
195 
203  public static function splitContentType($type, $wantedPart = null)
204  {
205  return self::splitHeaderField($type, $wantedPart, 'type');
206  }
207 
217  public static function splitHeaderField(
218  $field, $wantedPart = null, $firstName = 0
219  )
220  {
221  $wantedPart = strtolower($wantedPart);
222  $firstName = strtolower($firstName);
223 
224  // special case - a bit optimized
225  if ($firstName === $wantedPart) {
226  $field = strtok($field, ';');
227 
228  return $field[0] == '"' ? substr($field, 1, -1) : $field;
229  }
230 
231  $field = $firstName . '=' . $field;
232  if (!preg_match_all('%([^=\s]+)\s*=\s*("[^"]+"|[^;]+)(;\s*|$)%', $field, $matches)) {
233  throw new Zend_Exception('not a valid header field');
234  }
235 
236  if ($wantedPart) {
237  foreach ($matches[1] as $key => $name) {
238  if (strcasecmp($name, $wantedPart)) {
239  continue;
240  }
241  if ($matches[2][$key][0] != '"') {
242  return $matches[2][$key];
243  }
244 
245  return substr($matches[2][$key], 1, -1);
246  }
247 
248  return null;
249  }
250 
251  $split = array();
252  foreach ($matches[1] as $key => $name) {
253  $name = strtolower($name);
254  if ($matches[2][$key][0] == '"') {
255  $split[$name] = substr($matches[2][$key], 1, -1);
256  } else {
257  $split[$name] = $matches[2][$key];
258  }
259  }
260 
261  return $split;
262  }
263 
272  public static function decodeQuotedPrintable($string)
273  {
274  return quoted_printable_decode($string);
275  }
276 }
static splitMessage( $message, &$headers, &$body, $EOL=Zend_Mime::LINEEND)
Definition: Decode.php:123
$start
Definition: listing.phtml:18
$message
$type
Definition: item.phtml:13
const LINEEND
Definition: Mime.php:42
static splitMessageStruct( $message, $boundary, $EOL=Zend_Mime::LINEEND)
Definition: Decode.php:91
static splitMime($body, $boundary)
Definition: Decode.php:45
static splitHeaderField( $field, $wantedPart=null, $firstName=0)
Definition: Decode.php:217
static splitContentType($type, $wantedPart=null)
Definition: Decode.php:203
static decodeQuotedPrintable($string)
Definition: Decode.php:272
if(!isset($_GET['name'])) $name
Definition: log.php:14