PluginProbe
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress / 10.11.1
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress v10.11.1
11.1.1 11.1.0 11.0.5 11.0.4 11.0.3 11.0.2 11.0.1 11.0.0 10.11.1 10.11.0 10.10.2 10.10.1 10.10.0 10.9.1 trunk 10.0.0 10.0.1 10.1.0 10.1.1 10.1.2 10.1.3 10.1.4 10.2.0 10.2.1 10.2.2 All 62 releases
acymailing / back / Libraries / Imap2 / BodyStructure.php

BodyStructure.php in AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress 10.11.1, at back/Libraries/Imap2/BodyStructure.php

291 lines 8.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /*
4 * This file is part of the PHP IMAP2 package.
5 *
6 * (c) Francesco Bianco <[email protected]>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12 namespace AcyMailing\Libraries\Imap2;
13
14 class BodyStructure
15 {
16 const TYPETEXT = 0; /* unformatted text */
17 const TYPEMULTIPART = 1; /* multiple part */
18 const TYPEMESSAGE = 2; /* encapsulated message */
19 const TYPEAPPLICATION = 3; /* application data */
20 const TYPEAUDIO = 4; /* audio */
21 const TYPEIMAGE = 5; /* static image */
22 const TYPEVIDEO = 6; /* video */
23 const TYPEMODEL = 7; /* model */
24 const TYPEOTHER = 8; /* unknown */
25
26 const ENC7BIT = 0; /* 7 bit SMTP semantic data */
27 const ENC8BIT = 1; /* 8 bit SMTP semantic data */
28 const ENCBINARY = 2; /* 8 bit binary data */
29 const ENCBASE64 = 3; /* base-64 encoded data */
30 const ENCQUOTEDPRINTABLE = 4; /* human-readable 8-as-7 bit data */
31 const ENCOTHER = 5; /* unknown */
32
33 protected static $body_types = [
34 self::TYPETEXT => "TEXT",
35 self::TYPEMULTIPART => "MULTIPART",
36 self::TYPEMESSAGE => "MESSAGE",
37 self::TYPEAPPLICATION => "APPLICATION",
38 self::TYPEAUDIO => "AUDIO",
39 self::TYPEIMAGE => "IMAGE",
40 self::TYPEVIDEO => "VIDEO",
41 self::TYPEMODEL => "MODEL",
42 self::TYPEOTHER => "X-UNKNOWN",
43 ];
44
45 protected static $body_encodings = [
46 self::ENC7BIT => "7BIT",
47 self::ENC8BIT => "8BIT",
48 self::ENCBINARY => "BINARY",
49 self::ENCBASE64 => "BASE64",
50 self::ENCQUOTEDPRINTABLE => "QUOTED-PRINTABLE",
51 self::ENCOTHER => "X-UNKNOWN",
52 ];
53
54 public static function fromMessage($message)
55 {
56 return self::extractBodyStructure($message->bodystructure);
57 }
58
59 protected static function extractBodyStructure($structure)
60 {
61
62 /* if NIL */
63 if (is_null($structure)) {
64 return null;
65 }
66
67 /* body structure list */
68 if (!$length = count($structure)) {
69 return null;
70 }
71
72 $body = (object)[
73 "type" => self::TYPEOTHER,
74 "encoding" => self::ENC7BIT,
75 "ifsubtype" => 0,
76 "subtype" => null,
77 "ifdescription" => 0,
78 "description" => null,
79 "ifid" => 0,
80 "id" => null,
81 "lines" => null,
82 "bytes" => null,
83 "ifdisposition" => 0,
84 "disposition" => null,
85 "ifdparameters" => 0,
86 "dparameters" => null,
87 "ifparameters" => 0,
88 "parameters" => null,
89 ];
90
91 /* multipart body? */
92 if (is_array($structure[0])) {
93
94 /* yes, set its type */
95 $body->type = self::TYPEMULTIPART;
96
97 $index = 0;
98 $parts = [];
99
100 /* for each body part */
101 while (is_array($structure[$index])) {
102 $parts[] = self::extractBodyStructure($structure[$index++]);
103 }
104
105 /* parse subtype */
106 if ($body->subtype = strtoupper($structure[$index++])) {
107 $body->ifsubtype = 1;
108 }
109
110 /* multipart parameters */
111 if ($index < $length) {
112 if (count($body->parameters = self::extractParameters($structure[$index++], []))) {
113 $body->ifparameters = 1;
114 } else {
115 $body->parameters = (object)[];
116 }
117 }
118
119 /* disposition */
120 if ($index < $length) {
121 if (is_array($disposition = $structure[$index++])) {
122 $body->disposition = $disposition[0];
123 $body->ifdisposition = 1;
124
125 if (count($body->dparameters = self::extractParameters($disposition[1], []))) {
126 $body->ifdparameters = 1;
127 } else {
128 $body->dparameters = null;
129 }
130 }
131 }
132
133 /* location */
134 if ($index < $length) {
135 ++$index;
136 }
137
138 while ($index < $length) {
139 //parse_extension
140 ++$index;
141 }
142
143 $body->parts = $parts;
144 } /* not multipart, parse type name */
145 else {
146
147 /* empty body? */
148 if (!$length) return (object)[];
149
150 /* assume unknown type */
151 $body->type = self::TYPEOTHER;
152 /* and unknown encoding */
153 $body->encoding = self::ENCOTHER;
154
155 /* parse type */
156 if (($type = array_search(strtoupper($structure[0]), self::$body_types)) !== false) {
157 $body->type = $type;
158 }
159
160 /* encoding always gets uppercase form */
161 if (($encoding = array_search(strtoupper($structure[5]), self::$body_encodings)) !== false) {
162 $body->encoding = $encoding;
163 }
164
165 /* parse subtype */
166 if ($body->subtype = strtoupper($structure[1])) {
167 $body->ifsubtype = 1;
168 }
169
170 $body->ifdescription = 0;
171 if (!empty($structure[4])) {
172 $body->ifdescription = 1;
173 $body->description = $structure[4];
174 }
175
176 $body->ifid = 0;
177 if (!empty($structure[3])) {
178 $body->ifid = 1;
179 $body->id = $structure[3];
180 }
181
182 /* parse size of contents in bytes */
183 $body->bytes = intval($structure[6]);
184
185 $index = 7;
186
187 /* possible extra stuff */
188 switch ($body->type) {
189
190 /* message envelope and body */
191 case self::TYPEMESSAGE:
192 /* non MESSAGE/RFC822 is basic type */
193 if (strcmp($body->subtype, "RFC822")) break;
194
195 /* make certain server sends an envelope */
196 ++$index;
197
198 $body->parts[] = self::extractBodyStructure($structure[$index++]);
199
200 /* drop into text case */
201
202 /* size in lines */
203 case self::TYPETEXT:
204 $body->lines = intval($structure[$index++]);
205 break;
206
207 /* otherwise nothing special */
208 default:
209 break;
210 }
211
212 /* extension data - md5 */
213 if ($index < $length) {
214 ++$index;
215 }
216
217 /* disposition */
218 if ($index < $length) {
219 if (is_array($disposition = $structure[$index++])) {
220 $body->disposition = $disposition[0];
221 $body->ifdisposition = 1;
222
223 if (count($body->dparameters = self::extractParameters($disposition[1], []))) {
224 $body->ifdparameters = 1;
225 } else {
226 $body->dparameters = null;
227 }
228 }
229 }
230
231 /* language */
232 if ($index < $length) {
233 //parse_language
234 ++$index;
235 }
236
237 /* location */
238 if ($index < $length) {
239 ++$index;
240 }
241
242 while ($index < $length) {
243 //parse_extension
244 ++$index;
245 }
246
247 if (isset($structure[2]) && is_array($structure[2]) && count($body->parameters = self::extractParameters($structure[2], []))) {
248 $body->ifparameters = 1;
249 } else {
250 $body->parameters = (object)[];
251 }
252 }
253
254 if (is_null($body->description)) unset($body->description);
255 if (is_null($body->id)) unset($body->id);
256 if (is_null($body->disposition)) unset($body->disposition);
257 if (is_null($body->dparameters)) unset($body->dparameters);
258 if (is_null($body->parameters)) unset($body->parameters);
259
260 if (!$body->bytes) unset($body->bytes);
261 if (!$body->lines) unset($body->lines);
262
263 return $body;
264 }
265
266 protected static function extractParameters($attributes, $parameters)
267 {
268 if (empty($attributes)) {
269 return [];
270 }
271
272 $attribute = null;
273
274 foreach ($attributes as $value) {
275 if (empty($attribute)) {
276 $attribute = [
277 'attribute' => $value,
278 'value' => null,
279 ];
280 } else {
281 $attribute['value'] = $value;
282 $parameters[] = (object)$attribute;
283 $attribute = null;
284 }
285 }
286
287 return $parameters;
288 }
289
290 }
291