| 1 |
<?php |
| 2 |
|
| 3 |
|
| 4 |
namespace Javanile\Imap2; |
| 5 |
|
| 6 |
class BodyStructure |
| 7 |
{ |
| 8 |
|
| 9 |
const TYPETEXT = 0; const TYPEMULTIPART = 1; const TYPEMESSAGE = 2; const TYPEAPPLICATION = 3; const TYPEAUDIO = 4; const TYPEIMAGE = 5; const TYPEVIDEO = 6; const TYPEMODEL = 7; const TYPEOTHER = 8; |
| 10 |
const ENC7BIT = 0; const ENC8BIT = 1; const ENCBINARY = 2; const ENCBASE64 = 3; const ENCQUOTEDPRINTABLE = 4; const ENCOTHER = 5; |
| 11 |
protected static $body_types = [ |
| 12 |
self::TYPETEXT => "TEXT", |
| 13 |
self::TYPEMULTIPART => "MULTIPART", |
| 14 |
self::TYPEMESSAGE => "MESSAGE", |
| 15 |
self::TYPEAPPLICATION => "APPLICATION", |
| 16 |
self::TYPEAUDIO => "AUDIO", |
| 17 |
self::TYPEIMAGE => "IMAGE", |
| 18 |
self::TYPEVIDEO => "VIDEO", |
| 19 |
self::TYPEMODEL => "MODEL", |
| 20 |
self::TYPEOTHER => "X-UNKNOWN" |
| 21 |
]; |
| 22 |
|
| 23 |
protected static $body_encodings = [ |
| 24 |
self::ENC7BIT => "7BIT", |
| 25 |
self::ENC8BIT => "8BIT", |
| 26 |
self::ENCBINARY => "BINARY", |
| 27 |
self::ENCBASE64 => "BASE64", |
| 28 |
self::ENCQUOTEDPRINTABLE => "QUOTED-PRINTABLE", |
| 29 |
self::ENCOTHER => "X-UNKNOWN" |
| 30 |
]; |
| 31 |
|
| 32 |
public static function fromMessage($message) |
| 33 |
{ |
| 34 |
return self::extractBodyStructure($message->bodystructure); |
| 35 |
} |
| 36 |
|
| 37 |
protected static function extractBodyStructure($structure) |
| 38 |
{ |
| 39 |
|
| 40 |
if ( is_null($structure) ) |
| 41 |
return null; |
| 42 |
|
| 43 |
if ( ! $length = count($structure) ) |
| 44 |
return null; |
| 45 |
|
| 46 |
$body = (object)[ |
| 47 |
"type" => self::TYPEOTHER, |
| 48 |
"encoding" => self::ENC7BIT, |
| 49 |
"ifsubtype" => 0, |
| 50 |
"subtype" => null, |
| 51 |
"ifdescription" => 0, |
| 52 |
"description" => null, |
| 53 |
"ifid" => 0, |
| 54 |
"id" => null, |
| 55 |
"lines" => null, |
| 56 |
"bytes" => null, |
| 57 |
"ifdisposition" => 0, |
| 58 |
"disposition" => null, |
| 59 |
"ifdparameters" => 0, |
| 60 |
"dparameters" => null, |
| 61 |
"ifparameters" => 0, |
| 62 |
"parameters" => null |
| 63 |
]; |
| 64 |
|
| 65 |
if ( is_array($structure[0]) ) { |
| 66 |
|
| 67 |
$body->type = self::TYPEMULTIPART; |
| 68 |
|
| 69 |
$index = 0; |
| 70 |
$parts = []; |
| 71 |
|
| 72 |
while( is_array($structure[$index]) ) |
| 73 |
$parts[] = self::extractBodyStructure( $structure[$index++] ); |
| 74 |
|
| 75 |
if ( $body->subtype = strtoupper($structure[$index++]) ) |
| 76 |
$body->ifsubtype = 1; |
| 77 |
|
| 78 |
if ( $index < $length ) { |
| 79 |
if ( count( $body->parameters = self::extractParameters($structure[$index++], []) ) ) |
| 80 |
$body->ifparameters = 1; |
| 81 |
else |
| 82 |
$body->parameters = (object)[]; |
| 83 |
} |
| 84 |
|
| 85 |
if ( $index < $length ) { |
| 86 |
if ( is_array($disposition = $structure[$index++]) ) { |
| 87 |
$body->disposition = $disposition[0]; |
| 88 |
$body->ifdisposition = 1; |
| 89 |
|
| 90 |
if ( count( $body->dparameters = self::extractParameters($disposition[1], []) ) ) |
| 91 |
$body->ifdparameters = 1; |
| 92 |
else { |
| 93 |
$body->dparameters = null; |
| 94 |
} |
| 95 |
} |
| 96 |
} |
| 97 |
|
| 98 |
if ( $index < $length ) { |
| 99 |
++$index; |
| 100 |
} |
| 101 |
|
| 102 |
while( $index < $length ) { |
| 103 |
++$index; |
| 104 |
} |
| 105 |
|
| 106 |
$body->parts = $parts; |
| 107 |
|
| 108 |
} |
| 109 |
else { |
| 110 |
|
| 111 |
if ( ! $length ) return (object)[]; |
| 112 |
|
| 113 |
$body->type = self::TYPEOTHER; |
| 114 |
$body->encoding = self::ENCOTHER; |
| 115 |
|
| 116 |
if ( ($type = array_search(strtoupper($structure[0]), self::$body_types)) !== false ) |
| 117 |
$body->type = $type; |
| 118 |
|
| 119 |
if ( ($encoding = array_search(strtoupper($structure[5]), self::$body_encodings)) !== false ) |
| 120 |
$body->encoding = $encoding; |
| 121 |
|
| 122 |
if ( $body->subtype = strtoupper($structure[1]) ) |
| 123 |
$body->ifsubtype = 1; |
| 124 |
|
| 125 |
$body->ifdescription = 0; |
| 126 |
if ( ! empty($structure[4]) ) { |
| 127 |
$body->ifdescription = 1; |
| 128 |
$body->description = $structure[4]; |
| 129 |
} |
| 130 |
|
| 131 |
$body->ifid = 0; |
| 132 |
if ( ! empty($structure[3]) ) { |
| 133 |
$body->ifid = 1; |
| 134 |
$body->id = $structure[3]; |
| 135 |
} |
| 136 |
|
| 137 |
$body->bytes = intval($structure[6]); |
| 138 |
|
| 139 |
$index = 7; |
| 140 |
|
| 141 |
switch ( $body->type ) { |
| 142 |
|
| 143 |
case self::TYPEMESSAGE: |
| 144 |
if ( strcmp($body->subtype, "RFC822") ) break; |
| 145 |
|
| 146 |
++$index; |
| 147 |
|
| 148 |
$body->parts[] = self::extractBodyStructure( $structure[$index++] ); |
| 149 |
|
| 150 |
|
| 151 |
case self::TYPETEXT: |
| 152 |
$body->lines = intval($structure[$index++]); |
| 153 |
break; |
| 154 |
|
| 155 |
default: |
| 156 |
break; |
| 157 |
|
| 158 |
} |
| 159 |
|
| 160 |
if ( $index < $length ) |
| 161 |
++$index; |
| 162 |
|
| 163 |
if ( $index < $length ) { |
| 164 |
if ( is_array($disposition = $structure[$index++]) ) { |
| 165 |
$body->disposition = $disposition[0]; |
| 166 |
$body->ifdisposition = 1; |
| 167 |
|
| 168 |
if ( count( $body->dparameters = self::extractParameters($disposition[1], []) ) ) |
| 169 |
$body->ifdparameters = 1; |
| 170 |
else { |
| 171 |
$body->dparameters = null; |
| 172 |
} |
| 173 |
} |
| 174 |
} |
| 175 |
|
| 176 |
if ( $index < $length ) { |
| 177 |
++$index; |
| 178 |
} |
| 179 |
|
| 180 |
if ( $index < $length ) { |
| 181 |
++$index; |
| 182 |
} |
| 183 |
|
| 184 |
while( $index < $length ) { |
| 185 |
++$index; |
| 186 |
} |
| 187 |
|
| 188 |
if ( count( $body->parameters = self::extractParameters($structure[2], []) ) ) |
| 189 |
$body->ifparameters = 1; |
| 190 |
else |
| 191 |
$body->parameters = (object)[]; |
| 192 |
|
| 193 |
} |
| 194 |
|
| 195 |
if ( is_null($body->description) ) unset($body->description); |
| 196 |
if ( is_null($body->id) ) unset($body->id); |
| 197 |
if ( is_null($body->disposition) ) unset($body->disposition); |
| 198 |
if ( is_null($body->dparameters) ) unset($body->dparameters); |
| 199 |
if ( is_null($body->parameters) ) unset($body->parameters); |
| 200 |
|
| 201 |
if ( ! $body->bytes ) unset($body->bytes); |
| 202 |
if ( ! $body->lines ) unset($body->lines); |
| 203 |
|
| 204 |
return $body; |
| 205 |
|
| 206 |
} |
| 207 |
|
| 208 |
protected static function extractParameters($attributes, $parameters) |
| 209 |
{ |
| 210 |
if (empty($attributes)) { |
| 211 |
return []; |
| 212 |
} |
| 213 |
|
| 214 |
$attribute = null; |
| 215 |
|
| 216 |
foreach ($attributes as $value) { |
| 217 |
if (empty($attribute)) { |
| 218 |
$attribute = [ |
| 219 |
'attribute' => $value, |
| 220 |
'value' => null, |
| 221 |
]; |
| 222 |
} else { |
| 223 |
$attribute['value'] = $value; |
| 224 |
$parameters[] = (object) $attribute; |
| 225 |
$attribute = null; |
| 226 |
} |
| 227 |
} |
| 228 |
|
| 229 |
return $parameters; |
| 230 |
} |
| 231 |
|
| 232 |
} |
| 233 |
|