Passed
Push — master ( 17f7bb...ab922f )
by Malte
02:36
created

Structure::findContentType()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 6
c 2
b 0
f 0
dl 0
loc 8
rs 10
cc 3
nc 4
nop 0
1
<?php
2
/*
3
* File: Structure.php
4
* Category: -
5
* Author: M.Goldenbaum
6
* Created: 17.09.20 20:38
7
* Updated: -
8
*
9
* Description:
10
*  -
11
*/
12
13
namespace Webklex\PHPIMAP;
14
15
16
use Webklex\PHPIMAP\Exceptions\InvalidMessageDateException;
17
use Webklex\PHPIMAP\Exceptions\MessageContentFetchingException;
18
19
/**
20
 * Class Structure
21
 *
22
 * @package Webklex\PHPIMAP
23
 */
24
class Structure {
25
26
    /**
27
     * Raw structure
28
     *
29
     * @var string $raw
30
     */
31
    public $raw = "";
32
33
    /**
34
     * @var Header $header
35
     */
36
    private $header = null;
37
38
    /**
39
     * Message type (if multipart or not)
40
     *
41
     * @var int $type
42
     */
43
    public $type = IMAP::MESSAGE_TYPE_TEXT;
44
45
    /**
46
     * All available parts
47
     *
48
     * @var Part[] $parts
49
     */
50
    public $parts = [];
51
52
    /**
53
     * Config holder
54
     *
55
     * @var array $config
56
     */
57
    protected $config = [];
58
59
    /**
60
     * Structure constructor.
61
     * @param $raw_structure
62
     * @param Header $header
63
     *
64
     * @throws MessageContentFetchingException
65
     * @throws InvalidMessageDateException
66
     */
67
    public function __construct($raw_structure, Header $header) {
68
        $this->raw = $raw_structure;
69
        $this->header = $header;
70
        $this->config = ClientManager::get('options');
71
        $this->parse();
72
    }
73
74
    /**
75
     * Parse the given raw structure
76
     *
77
     * @throws MessageContentFetchingException
78
     * @throws InvalidMessageDateException
79
     */
80
    protected function parse(){
81
        $this->findContentType();
82
        $this->parts = $this->find_parts();
83
    }
84
85
    /**
86
     * Determine the message content type
87
     */
88
    public function findContentType(){
89
90
        $content_type = $this->header->get("content_type");
91
        $content_type = (is_array($content_type)) ? implode(' ', $content_type) : $content_type;
92
        if(stripos($content_type, 'multipart') === 0) {
93
            $this->type = IMAP::MESSAGE_TYPE_MULTIPART;
94
        }else{
95
            $this->type = IMAP::MESSAGE_TYPE_TEXT;
96
        }
97
    }
98
99
    /**
100
     * Determine the message content type
101
     *
102
     * @return string|null
103
     */
104
    public function getBoundary(){
105
        $boundary = $this->header->find("/boundary\=(.*)/i");
106
107
        if ($boundary === null) {
108
            return null;
109
        }
110
111
        return $this->clearBoundaryString($boundary);
112
    }
113
114
    /**
115
     * Remove all unwanted chars from a given boundary
116
     * @param string $str
117
     *
118
     * @return string
119
     */
120
    private function clearBoundaryString($str) {
121
        return str_replace(['"', '\r', '\n', "\n", "\r", ";", "\s"], "", $str);
122
    }
123
124
    /**
125
     * Find all available parts
126
     *
127
     * @return array
128
     * @throws MessageContentFetchingException
129
     * @throws InvalidMessageDateException
130
     */
131
    public function find_parts(){
132
        if($this->type === IMAP::MESSAGE_TYPE_MULTIPART) {
133
            if (($boundary = $this->getBoundary()) === null)  {
134
                throw new MessageContentFetchingException("no content found", 0);
135
            }
136
137
            $boundaries = [
138
                $boundary
139
            ];
140
141
            if (preg_match("/boundary\=\"?(.*)\"?/", $this->raw, $match) == 1) {
142
                if(is_array($match[1])){
143
                    foreach($match[1] as $matched){
144
                        $boundaries[] = $this->clearBoundaryString($matched);
145
                    }
146
                }else{
147
                    if(!empty($match[1])) {
148
                        $boundaries[] = $this->clearBoundaryString($match[1]);
149
                    }
150
                }
151
            }
152
153
            $raw_parts = explode( $boundaries[0], str_replace($boundaries, $boundaries[0], $this->raw) );
154
            $parts = [];
155
            $part_number = 0;
156
            foreach($raw_parts as $part) {
157
                $part = trim(rtrim($part));
158
                if ($part !== "--") {
159
                    $parts[] = new Part($part, null, $part_number);
160
                    $part_number++;
161
                }
162
            }
163
            return $parts;
164
        }
165
166
        return [new Part($this->raw, $this->header)];
167
    }
168
}
169