PluginProbe
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress / 11.1.0
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress v11.1.0
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
← All changes | back/Libraries/Imap2/BodyStructure.php +290 -0 10.10.1 → 11.1.0 View file →
@@ -1,0 +1,290 @@
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 +}