Completed
Branch develop (7eeef6)
by
unknown
23:28
created
htdocs/includes/swiftmailer/lib/classes/Swift/Mime/SimpleHeaderFactory.php 1 patch
Indentation   +175 added lines, -175 removed lines patch added patch discarded remove patch
@@ -17,179 +17,179 @@
 block discarded – undo
17 17
  */
18 18
 class Swift_Mime_SimpleHeaderFactory implements Swift_Mime_CharsetObserver
19 19
 {
20
-    /** The HeaderEncoder used by these headers */
21
-    private $encoder;
22
-
23
-    /** The Encoder used by parameters */
24
-    private $paramEncoder;
25
-
26
-    /** Strict EmailValidator */
27
-    private $emailValidator;
28
-
29
-    /** The charset of created Headers */
30
-    private $charset;
31
-
32
-    /** Swift_AddressEncoder */
33
-    private $addressEncoder;
34
-
35
-    /**
36
-     * Creates a new SimpleHeaderFactory using $encoder and $paramEncoder.
37
-     *
38
-     * @param string|null $charset
39
-     */
40
-    public function __construct(Swift_Mime_HeaderEncoder $encoder, Swift_Encoder $paramEncoder, EmailValidator $emailValidator, $charset = null, Swift_AddressEncoder $addressEncoder = null)
41
-    {
42
-        $this->encoder = $encoder;
43
-        $this->paramEncoder = $paramEncoder;
44
-        $this->emailValidator = $emailValidator;
45
-        $this->charset = $charset;
46
-        $this->addressEncoder = $addressEncoder ?? new Swift_AddressEncoder_IdnAddressEncoder();
47
-    }
48
-
49
-    /**
50
-     * Create a new Mailbox Header with a list of $addresses.
51
-     *
52
-     * @param string            $name
53
-     * @param array|string|null $addresses
54
-     *
55
-     * @return Swift_Mime_Header
56
-     */
57
-    public function createMailboxHeader($name, $addresses = null)
58
-    {
59
-        $header = new Swift_Mime_Headers_MailboxHeader($name, $this->encoder, $this->emailValidator, $this->addressEncoder);
60
-        if (isset($addresses)) {
61
-            $header->setFieldBodyModel($addresses);
62
-        }
63
-        $this->setHeaderCharset($header);
64
-
65
-        return $header;
66
-    }
67
-
68
-    /**
69
-     * Create a new Date header using $dateTime.
70
-     *
71
-     * @param string $name
72
-     *
73
-     * @return Swift_Mime_Header
74
-     */
75
-    public function createDateHeader($name, DateTimeInterface $dateTime = null)
76
-    {
77
-        $header = new Swift_Mime_Headers_DateHeader($name);
78
-        if (isset($dateTime)) {
79
-            $header->setFieldBodyModel($dateTime);
80
-        }
81
-        $this->setHeaderCharset($header);
82
-
83
-        return $header;
84
-    }
85
-
86
-    /**
87
-     * Create a new basic text header with $name and $value.
88
-     *
89
-     * @param string $name
90
-     * @param string $value
91
-     *
92
-     * @return Swift_Mime_Header
93
-     */
94
-    public function createTextHeader($name, $value = null)
95
-    {
96
-        $header = new Swift_Mime_Headers_UnstructuredHeader($name, $this->encoder);
97
-        if (isset($value)) {
98
-            $header->setFieldBodyModel($value);
99
-        }
100
-        $this->setHeaderCharset($header);
101
-
102
-        return $header;
103
-    }
104
-
105
-    /**
106
-     * Create a new ParameterizedHeader with $name, $value and $params.
107
-     *
108
-     * @param string $name
109
-     * @param string $value
110
-     * @param array  $params
111
-     *
112
-     * @return Swift_Mime_Headers_ParameterizedHeader
113
-     */
114
-    public function createParameterizedHeader($name, $value = null, $params = [])
115
-    {
116
-        $header = new Swift_Mime_Headers_ParameterizedHeader($name, $this->encoder, ('content-disposition' == strtolower($name ?? '')) ? $this->paramEncoder : null);
117
-        if (isset($value)) {
118
-            $header->setFieldBodyModel($value);
119
-        }
120
-        foreach ($params as $k => $v) {
121
-            $header->setParameter($k, $v);
122
-        }
123
-        $this->setHeaderCharset($header);
124
-
125
-        return $header;
126
-    }
127
-
128
-    /**
129
-     * Create a new ID header for Message-ID or Content-ID.
130
-     *
131
-     * @param string       $name
132
-     * @param string|array $ids
133
-     *
134
-     * @return Swift_Mime_Header
135
-     */
136
-    public function createIdHeader($name, $ids = null)
137
-    {
138
-        $header = new Swift_Mime_Headers_IdentificationHeader($name, $this->emailValidator);
139
-        if (isset($ids)) {
140
-            $header->setFieldBodyModel($ids);
141
-        }
142
-        $this->setHeaderCharset($header);
143
-
144
-        return $header;
145
-    }
146
-
147
-    /**
148
-     * Create a new Path header with an address (path) in it.
149
-     *
150
-     * @param string $name
151
-     * @param string $path
152
-     *
153
-     * @return Swift_Mime_Header
154
-     */
155
-    public function createPathHeader($name, $path = null)
156
-    {
157
-        $header = new Swift_Mime_Headers_PathHeader($name, $this->emailValidator);
158
-        if (isset($path)) {
159
-            $header->setFieldBodyModel($path);
160
-        }
161
-        $this->setHeaderCharset($header);
162
-
163
-        return $header;
164
-    }
165
-
166
-    /**
167
-     * Notify this observer that the entity's charset has changed.
168
-     *
169
-     * @param string $charset
170
-     */
171
-    public function charsetChanged($charset)
172
-    {
173
-        $this->charset = $charset;
174
-        $this->encoder->charsetChanged($charset);
175
-        $this->paramEncoder->charsetChanged($charset);
176
-    }
177
-
178
-    /**
179
-     * Make a deep copy of object.
180
-     */
181
-    public function __clone()
182
-    {
183
-        $this->encoder = clone $this->encoder;
184
-        $this->paramEncoder = clone $this->paramEncoder;
185
-        $this->addressEncoder = clone $this->addressEncoder;
186
-    }
187
-
188
-    /** Apply the charset to the Header */
189
-    private function setHeaderCharset(Swift_Mime_Header $header)
190
-    {
191
-        if (isset($this->charset)) {
192
-            $header->setCharset($this->charset);
193
-        }
194
-    }
20
+	/** The HeaderEncoder used by these headers */
21
+	private $encoder;
22
+
23
+	/** The Encoder used by parameters */
24
+	private $paramEncoder;
25
+
26
+	/** Strict EmailValidator */
27
+	private $emailValidator;
28
+
29
+	/** The charset of created Headers */
30
+	private $charset;
31
+
32
+	/** Swift_AddressEncoder */
33
+	private $addressEncoder;
34
+
35
+	/**
36
+	 * Creates a new SimpleHeaderFactory using $encoder and $paramEncoder.
37
+	 *
38
+	 * @param string|null $charset
39
+	 */
40
+	public function __construct(Swift_Mime_HeaderEncoder $encoder, Swift_Encoder $paramEncoder, EmailValidator $emailValidator, $charset = null, Swift_AddressEncoder $addressEncoder = null)
41
+	{
42
+		$this->encoder = $encoder;
43
+		$this->paramEncoder = $paramEncoder;
44
+		$this->emailValidator = $emailValidator;
45
+		$this->charset = $charset;
46
+		$this->addressEncoder = $addressEncoder ?? new Swift_AddressEncoder_IdnAddressEncoder();
47
+	}
48
+
49
+	/**
50
+	 * Create a new Mailbox Header with a list of $addresses.
51
+	 *
52
+	 * @param string            $name
53
+	 * @param array|string|null $addresses
54
+	 *
55
+	 * @return Swift_Mime_Header
56
+	 */
57
+	public function createMailboxHeader($name, $addresses = null)
58
+	{
59
+		$header = new Swift_Mime_Headers_MailboxHeader($name, $this->encoder, $this->emailValidator, $this->addressEncoder);
60
+		if (isset($addresses)) {
61
+			$header->setFieldBodyModel($addresses);
62
+		}
63
+		$this->setHeaderCharset($header);
64
+
65
+		return $header;
66
+	}
67
+
68
+	/**
69
+	 * Create a new Date header using $dateTime.
70
+	 *
71
+	 * @param string $name
72
+	 *
73
+	 * @return Swift_Mime_Header
74
+	 */
75
+	public function createDateHeader($name, DateTimeInterface $dateTime = null)
76
+	{
77
+		$header = new Swift_Mime_Headers_DateHeader($name);
78
+		if (isset($dateTime)) {
79
+			$header->setFieldBodyModel($dateTime);
80
+		}
81
+		$this->setHeaderCharset($header);
82
+
83
+		return $header;
84
+	}
85
+
86
+	/**
87
+	 * Create a new basic text header with $name and $value.
88
+	 *
89
+	 * @param string $name
90
+	 * @param string $value
91
+	 *
92
+	 * @return Swift_Mime_Header
93
+	 */
94
+	public function createTextHeader($name, $value = null)
95
+	{
96
+		$header = new Swift_Mime_Headers_UnstructuredHeader($name, $this->encoder);
97
+		if (isset($value)) {
98
+			$header->setFieldBodyModel($value);
99
+		}
100
+		$this->setHeaderCharset($header);
101
+
102
+		return $header;
103
+	}
104
+
105
+	/**
106
+	 * Create a new ParameterizedHeader with $name, $value and $params.
107
+	 *
108
+	 * @param string $name
109
+	 * @param string $value
110
+	 * @param array  $params
111
+	 *
112
+	 * @return Swift_Mime_Headers_ParameterizedHeader
113
+	 */
114
+	public function createParameterizedHeader($name, $value = null, $params = [])
115
+	{
116
+		$header = new Swift_Mime_Headers_ParameterizedHeader($name, $this->encoder, ('content-disposition' == strtolower($name ?? '')) ? $this->paramEncoder : null);
117
+		if (isset($value)) {
118
+			$header->setFieldBodyModel($value);
119
+		}
120
+		foreach ($params as $k => $v) {
121
+			$header->setParameter($k, $v);
122
+		}
123
+		$this->setHeaderCharset($header);
124
+
125
+		return $header;
126
+	}
127
+
128
+	/**
129
+	 * Create a new ID header for Message-ID or Content-ID.
130
+	 *
131
+	 * @param string       $name
132
+	 * @param string|array $ids
133
+	 *
134
+	 * @return Swift_Mime_Header
135
+	 */
136
+	public function createIdHeader($name, $ids = null)
137
+	{
138
+		$header = new Swift_Mime_Headers_IdentificationHeader($name, $this->emailValidator);
139
+		if (isset($ids)) {
140
+			$header->setFieldBodyModel($ids);
141
+		}
142
+		$this->setHeaderCharset($header);
143
+
144
+		return $header;
145
+	}
146
+
147
+	/**
148
+	 * Create a new Path header with an address (path) in it.
149
+	 *
150
+	 * @param string $name
151
+	 * @param string $path
152
+	 *
153
+	 * @return Swift_Mime_Header
154
+	 */
155
+	public function createPathHeader($name, $path = null)
156
+	{
157
+		$header = new Swift_Mime_Headers_PathHeader($name, $this->emailValidator);
158
+		if (isset($path)) {
159
+			$header->setFieldBodyModel($path);
160
+		}
161
+		$this->setHeaderCharset($header);
162
+
163
+		return $header;
164
+	}
165
+
166
+	/**
167
+	 * Notify this observer that the entity's charset has changed.
168
+	 *
169
+	 * @param string $charset
170
+	 */
171
+	public function charsetChanged($charset)
172
+	{
173
+		$this->charset = $charset;
174
+		$this->encoder->charsetChanged($charset);
175
+		$this->paramEncoder->charsetChanged($charset);
176
+	}
177
+
178
+	/**
179
+	 * Make a deep copy of object.
180
+	 */
181
+	public function __clone()
182
+	{
183
+		$this->encoder = clone $this->encoder;
184
+		$this->paramEncoder = clone $this->paramEncoder;
185
+		$this->addressEncoder = clone $this->addressEncoder;
186
+	}
187
+
188
+	/** Apply the charset to the Header */
189
+	private function setHeaderCharset(Swift_Mime_Header $header)
190
+	{
191
+		if (isset($this->charset)) {
192
+			$header->setCharset($this->charset);
193
+		}
194
+	}
195 195
 }
Please login to merge, or discard this patch.
htdocs/includes/swiftmailer/lib/classes/Swift/Mime/SimpleMimeEntity.php 1 patch
Indentation   +808 added lines, -808 removed lines patch added patch discarded remove patch
@@ -15,812 +15,812 @@
 block discarded – undo
15 15
  */
16 16
 class Swift_Mime_SimpleMimeEntity implements Swift_Mime_CharsetObserver, Swift_Mime_EncodingObserver
17 17
 {
18
-    /** Main message document; there can only be one of these */
19
-    const LEVEL_TOP = 16;
20
-
21
-    /** An entity which nests with the same precedence as an attachment */
22
-    const LEVEL_MIXED = 256;
23
-
24
-    /** An entity which nests with the same precedence as a mime part */
25
-    const LEVEL_ALTERNATIVE = 4096;
26
-
27
-    /** An entity which nests with the same precedence as embedded content */
28
-    const LEVEL_RELATED = 65536;
29
-
30
-    /** A collection of Headers for this mime entity */
31
-    private $headers;
32
-
33
-    /** The body as a string, or a stream */
34
-    private $body;
35
-
36
-    /** The encoder that encodes the body into a streamable format */
37
-    private $encoder;
38
-
39
-    /** Message ID generator */
40
-    private $idGenerator;
41
-
42
-    /** A mime boundary, if any is used */
43
-    private $boundary;
44
-
45
-    /** Mime types to be used based on the nesting level */
46
-    private $compositeRanges = [
47
-        'multipart/mixed' => [self::LEVEL_TOP, self::LEVEL_MIXED],
48
-        'multipart/alternative' => [self::LEVEL_MIXED, self::LEVEL_ALTERNATIVE],
49
-        'multipart/related' => [self::LEVEL_ALTERNATIVE, self::LEVEL_RELATED],
50
-    ];
51
-
52
-    /** A set of filter rules to define what level an entity should be nested at */
53
-    private $compoundLevelFilters = [];
54
-
55
-    /** The nesting level of this entity */
56
-    private $nestingLevel = self::LEVEL_ALTERNATIVE;
57
-
58
-    /** A KeyCache instance used during encoding and streaming */
59
-    private $cache;
60
-
61
-    /** Direct descendants of this entity */
62
-    private $immediateChildren = [];
63
-
64
-    /** All descendants of this entity */
65
-    private $children = [];
66
-
67
-    /** The maximum line length of the body of this entity */
68
-    private $maxLineLength = 78;
69
-
70
-    /** The order in which alternative mime types should appear */
71
-    private $alternativePartOrder = [
72
-        'text/plain' => 1,
73
-        'text/html' => 2,
74
-        'multipart/related' => 3,
75
-    ];
76
-
77
-    /** The CID of this entity */
78
-    private $id;
79
-
80
-    /** The key used for accessing the cache */
81
-    private $cacheKey;
82
-
83
-    protected $userContentType;
84
-
85
-    /**
86
-     * Create a new SimpleMimeEntity with $headers, $encoder and $cache.
87
-     */
88
-    public function __construct(Swift_Mime_SimpleHeaderSet $headers, Swift_Mime_ContentEncoder $encoder, Swift_KeyCache $cache, Swift_IdGenerator $idGenerator)
89
-    {
90
-        $this->cacheKey = bin2hex(random_bytes(16)); // set 32 hex values
91
-        $this->cache = $cache;
92
-        $this->headers = $headers;
93
-        $this->idGenerator = $idGenerator;
94
-        $this->setEncoder($encoder);
95
-        $this->headers->defineOrdering(['Content-Type', 'Content-Transfer-Encoding']);
96
-
97
-        // This array specifies that, when the entire MIME document contains
98
-        // $compoundLevel, then for each child within $level, if its Content-Type
99
-        // is $contentType then it should be treated as if it's level is
100
-        // $neededLevel instead.  I tried to write that unambiguously! :-\
101
-        // Data Structure:
102
-        // array (
103
-        //   $compoundLevel => array(
104
-        //     $level => array(
105
-        //       $contentType => $neededLevel
106
-        //     )
107
-        //   )
108
-        // )
109
-
110
-        $this->compoundLevelFilters = [
111
-            (self::LEVEL_ALTERNATIVE + self::LEVEL_RELATED) => [
112
-                self::LEVEL_ALTERNATIVE => [
113
-                    'text/plain' => self::LEVEL_ALTERNATIVE,
114
-                    'text/html' => self::LEVEL_RELATED,
115
-                    ],
116
-                ],
117
-            ];
118
-
119
-        $this->id = $this->idGenerator->generateId();
120
-    }
121
-
122
-    /**
123
-     * Generate a new Content-ID or Message-ID for this MIME entity.
124
-     *
125
-     * @return string
126
-     */
127
-    public function generateId()
128
-    {
129
-        $this->setId($this->idGenerator->generateId());
130
-
131
-        return $this->id;
132
-    }
133
-
134
-    /**
135
-     * Get the {@link Swift_Mime_SimpleHeaderSet} for this entity.
136
-     *
137
-     * @return Swift_Mime_SimpleHeaderSet
138
-     */
139
-    public function getHeaders()
140
-    {
141
-        return $this->headers;
142
-    }
143
-
144
-    /**
145
-     * Get the nesting level of this entity.
146
-     *
147
-     * @see LEVEL_TOP, LEVEL_MIXED, LEVEL_RELATED, LEVEL_ALTERNATIVE
148
-     *
149
-     * @return int
150
-     */
151
-    public function getNestingLevel()
152
-    {
153
-        return $this->nestingLevel;
154
-    }
155
-
156
-    /**
157
-     * Get the Content-type of this entity.
158
-     *
159
-     * @return string
160
-     */
161
-    public function getContentType()
162
-    {
163
-        return $this->getHeaderFieldModel('Content-Type');
164
-    }
165
-
166
-    /**
167
-     * Get the Body Content-type of this entity.
168
-     *
169
-     * @return string
170
-     */
171
-    public function getBodyContentType()
172
-    {
173
-        return $this->userContentType;
174
-    }
175
-
176
-    /**
177
-     * Set the Content-type of this entity.
178
-     *
179
-     * @param string $type
180
-     *
181
-     * @return $this
182
-     */
183
-    public function setContentType($type)
184
-    {
185
-        $this->setContentTypeInHeaders($type);
186
-        // Keep track of the value so that if the content-type changes automatically
187
-        // due to added child entities, it can be restored if they are later removed
188
-        $this->userContentType = $type;
189
-
190
-        return $this;
191
-    }
192
-
193
-    /**
194
-     * Get the CID of this entity.
195
-     *
196
-     * The CID will only be present in headers if a Content-ID header is present.
197
-     *
198
-     * @return string
199
-     */
200
-    public function getId()
201
-    {
202
-        $tmp = (array) $this->getHeaderFieldModel($this->getIdField());
203
-
204
-        return $this->headers->has($this->getIdField()) ? current($tmp) : $this->id;
205
-    }
206
-
207
-    /**
208
-     * Set the CID of this entity.
209
-     *
210
-     * @param string $id
211
-     *
212
-     * @return $this
213
-     */
214
-    public function setId($id)
215
-    {
216
-        if (!$this->setHeaderFieldModel($this->getIdField(), $id)) {
217
-            $this->headers->addIdHeader($this->getIdField(), $id);
218
-        }
219
-        $this->id = $id;
220
-
221
-        return $this;
222
-    }
223
-
224
-    /**
225
-     * Get the description of this entity.
226
-     *
227
-     * This value comes from the Content-Description header if set.
228
-     *
229
-     * @return string
230
-     */
231
-    public function getDescription()
232
-    {
233
-        return $this->getHeaderFieldModel('Content-Description');
234
-    }
235
-
236
-    /**
237
-     * Set the description of this entity.
238
-     *
239
-     * This method sets a value in the Content-ID header.
240
-     *
241
-     * @param string $description
242
-     *
243
-     * @return $this
244
-     */
245
-    public function setDescription($description)
246
-    {
247
-        if (!$this->setHeaderFieldModel('Content-Description', $description)) {
248
-            $this->headers->addTextHeader('Content-Description', $description);
249
-        }
250
-
251
-        return $this;
252
-    }
253
-
254
-    /**
255
-     * Get the maximum line length of the body of this entity.
256
-     *
257
-     * @return int
258
-     */
259
-    public function getMaxLineLength()
260
-    {
261
-        return $this->maxLineLength;
262
-    }
263
-
264
-    /**
265
-     * Set the maximum line length of lines in this body.
266
-     *
267
-     * Though not enforced by the library, lines should not exceed 1000 chars.
268
-     *
269
-     * @param int $length
270
-     *
271
-     * @return $this
272
-     */
273
-    public function setMaxLineLength($length)
274
-    {
275
-        $this->maxLineLength = $length;
276
-
277
-        return $this;
278
-    }
279
-
280
-    /**
281
-     * Get all children added to this entity.
282
-     *
283
-     * @return Swift_Mime_SimpleMimeEntity[]
284
-     */
285
-    public function getChildren()
286
-    {
287
-        return $this->children;
288
-    }
289
-
290
-    /**
291
-     * Set all children of this entity.
292
-     *
293
-     * @param Swift_Mime_SimpleMimeEntity[] $children
294
-     * @param int                           $compoundLevel For internal use only
295
-     *
296
-     * @return $this
297
-     */
298
-    public function setChildren(array $children, $compoundLevel = null)
299
-    {
300
-        // TODO: Try to refactor this logic
301
-        $compoundLevel = $compoundLevel ?? $this->getCompoundLevel($children);
302
-        $immediateChildren = [];
303
-        $grandchildren = [];
304
-        $newContentType = $this->userContentType;
305
-
306
-        foreach ($children as $child) {
307
-            $level = $this->getNeededChildLevel($child, $compoundLevel);
308
-            if (empty($immediateChildren)) {
309
-                //first iteration
310
-                $immediateChildren = [$child];
311
-            } else {
312
-                $nextLevel = $this->getNeededChildLevel($immediateChildren[0], $compoundLevel);
313
-                if ($nextLevel == $level) {
314
-                    $immediateChildren[] = $child;
315
-                } elseif ($level < $nextLevel) {
316
-                    // Re-assign immediateChildren to grandchildren
317
-                    $grandchildren = array_merge($grandchildren, $immediateChildren);
318
-                    // Set new children
319
-                    $immediateChildren = [$child];
320
-                } else {
321
-                    $grandchildren[] = $child;
322
-                }
323
-            }
324
-        }
325
-
326
-        if ($immediateChildren) {
327
-            $lowestLevel = $this->getNeededChildLevel($immediateChildren[0], $compoundLevel);
328
-
329
-            // Determine which composite media type is needed to accommodate the
330
-            // immediate children
331
-            foreach ($this->compositeRanges as $mediaType => $range) {
332
-                if ($lowestLevel > $range[0] && $lowestLevel <= $range[1]) {
333
-                    $newContentType = $mediaType;
334
-
335
-                    break;
336
-                }
337
-            }
338
-
339
-            // Put any grandchildren in a subpart
340
-            if (!empty($grandchildren)) {
341
-                $subentity = $this->createChild();
342
-                $subentity->setNestingLevel($lowestLevel);
343
-                $subentity->setChildren($grandchildren, $compoundLevel);
344
-                array_unshift($immediateChildren, $subentity);
345
-            }
346
-        }
347
-
348
-        $this->immediateChildren = $immediateChildren;
349
-        $this->children = $children;
350
-        $this->setContentTypeInHeaders($newContentType);
351
-        $this->fixHeaders();
352
-        $this->sortChildren();
353
-
354
-        return $this;
355
-    }
356
-
357
-    /**
358
-     * Get the body of this entity as a string.
359
-     *
360
-     * @return string
361
-     */
362
-    public function getBody()
363
-    {
364
-        return $this->body instanceof Swift_OutputByteStream ? $this->readStream($this->body) : $this->body;
365
-    }
366
-
367
-    /**
368
-     * Set the body of this entity, either as a string, or as an instance of
369
-     * {@link Swift_OutputByteStream}.
370
-     *
371
-     * @param mixed  $body
372
-     * @param string $contentType optional
373
-     *
374
-     * @return $this
375
-     */
376
-    public function setBody($body, $contentType = null)
377
-    {
378
-        if ($body !== $this->body) {
379
-            $this->clearCache();
380
-        }
381
-
382
-        $this->body = $body;
383
-        if (null !== $contentType) {
384
-            $this->setContentType($contentType);
385
-        }
386
-
387
-        return $this;
388
-    }
389
-
390
-    /**
391
-     * Get the encoder used for the body of this entity.
392
-     *
393
-     * @return Swift_Mime_ContentEncoder
394
-     */
395
-    public function getEncoder()
396
-    {
397
-        return $this->encoder;
398
-    }
399
-
400
-    /**
401
-     * Set the encoder used for the body of this entity.
402
-     *
403
-     * @return $this
404
-     */
405
-    public function setEncoder(Swift_Mime_ContentEncoder $encoder)
406
-    {
407
-        if ($encoder !== $this->encoder) {
408
-            $this->clearCache();
409
-        }
410
-
411
-        $this->encoder = $encoder;
412
-        $this->setEncoding($encoder->getName());
413
-        $this->notifyEncoderChanged($encoder);
414
-
415
-        return $this;
416
-    }
417
-
418
-    /**
419
-     * Get the boundary used to separate children in this entity.
420
-     *
421
-     * @return string
422
-     */
423
-    public function getBoundary()
424
-    {
425
-        if (!isset($this->boundary)) {
426
-            $this->boundary = '_=_swift_'.time().'_'.bin2hex(random_bytes(16)).'_=_';
427
-        }
428
-
429
-        return $this->boundary;
430
-    }
431
-
432
-    /**
433
-     * Set the boundary used to separate children in this entity.
434
-     *
435
-     * @param string $boundary
436
-     *
437
-     * @throws Swift_RfcComplianceException
438
-     *
439
-     * @return $this
440
-     */
441
-    public function setBoundary($boundary)
442
-    {
443
-        $this->assertValidBoundary($boundary);
444
-        $this->boundary = $boundary;
445
-
446
-        return $this;
447
-    }
448
-
449
-    /**
450
-     * Receive notification that the charset of this entity, or a parent entity
451
-     * has changed.
452
-     *
453
-     * @param string $charset
454
-     */
455
-    public function charsetChanged($charset)
456
-    {
457
-        $this->notifyCharsetChanged($charset);
458
-    }
459
-
460
-    /**
461
-     * Receive notification that the encoder of this entity or a parent entity
462
-     * has changed.
463
-     */
464
-    public function encoderChanged(Swift_Mime_ContentEncoder $encoder)
465
-    {
466
-        $this->notifyEncoderChanged($encoder);
467
-    }
468
-
469
-    /**
470
-     * Get this entire entity as a string.
471
-     *
472
-     * @return string
473
-     */
474
-    public function toString()
475
-    {
476
-        $string = $this->headers->toString();
477
-        $string .= $this->bodyToString();
478
-
479
-        return $string;
480
-    }
481
-
482
-    /**
483
-     * Get this entire entity as a string.
484
-     *
485
-     * @return string
486
-     */
487
-    protected function bodyToString()
488
-    {
489
-        $string = '';
490
-
491
-        if (isset($this->body) && empty($this->immediateChildren)) {
492
-            if ($this->cache->hasKey($this->cacheKey, 'body')) {
493
-                $body = $this->cache->getString($this->cacheKey, 'body');
494
-            } else {
495
-                $body = "\r\n".$this->encoder->encodeString($this->getBody(), 0, $this->getMaxLineLength());
496
-                $this->cache->setString($this->cacheKey, 'body', $body, Swift_KeyCache::MODE_WRITE);
497
-            }
498
-            $string .= $body;
499
-        }
500
-
501
-        if (!empty($this->immediateChildren)) {
502
-            foreach ($this->immediateChildren as $child) {
503
-                $string .= "\r\n\r\n--".$this->getBoundary()."\r\n";
504
-                $string .= $child->toString();
505
-            }
506
-            $string .= "\r\n\r\n--".$this->getBoundary()."--\r\n";
507
-        }
508
-
509
-        return $string;
510
-    }
511
-
512
-    /**
513
-     * Returns a string representation of this object.
514
-     *
515
-     * @see toString()
516
-     *
517
-     * @return string
518
-     */
519
-    public function __toString()
520
-    {
521
-        return $this->toString();
522
-    }
523
-
524
-    /**
525
-     * Write this entire entity to a {@see Swift_InputByteStream}.
526
-     */
527
-    public function toByteStream(Swift_InputByteStream $is)
528
-    {
529
-        $is->write($this->headers->toString());
530
-        $is->commit();
531
-
532
-        $this->bodyToByteStream($is);
533
-    }
534
-
535
-    /**
536
-     * Write this entire entity to a {@link Swift_InputByteStream}.
537
-     */
538
-    protected function bodyToByteStream(Swift_InputByteStream $is)
539
-    {
540
-        if (empty($this->immediateChildren)) {
541
-            if (isset($this->body)) {
542
-                if ($this->cache->hasKey($this->cacheKey, 'body')) {
543
-                    $this->cache->exportToByteStream($this->cacheKey, 'body', $is);
544
-                } else {
545
-                    $cacheIs = $this->cache->getInputByteStream($this->cacheKey, 'body');
546
-                    if ($cacheIs) {
547
-                        $is->bind($cacheIs);
548
-                    }
549
-
550
-                    $is->write("\r\n");
551
-
552
-                    if ($this->body instanceof Swift_OutputByteStream) {
553
-                        $this->body->setReadPointer(0);
554
-
555
-                        $this->encoder->encodeByteStream($this->body, $is, 0, $this->getMaxLineLength());
556
-                    } else {
557
-                        $is->write($this->encoder->encodeString($this->getBody(), 0, $this->getMaxLineLength()));
558
-                    }
559
-
560
-                    if ($cacheIs) {
561
-                        $is->unbind($cacheIs);
562
-                    }
563
-                }
564
-            }
565
-        }
566
-
567
-        if (!empty($this->immediateChildren)) {
568
-            foreach ($this->immediateChildren as $child) {
569
-                $is->write("\r\n\r\n--".$this->getBoundary()."\r\n");
570
-                $child->toByteStream($is);
571
-            }
572
-            $is->write("\r\n\r\n--".$this->getBoundary()."--\r\n");
573
-        }
574
-    }
575
-
576
-    /**
577
-     * Get the name of the header that provides the ID of this entity.
578
-     */
579
-    protected function getIdField()
580
-    {
581
-        return 'Content-ID';
582
-    }
583
-
584
-    /**
585
-     * Get the model data (usually an array or a string) for $field.
586
-     */
587
-    protected function getHeaderFieldModel($field)
588
-    {
589
-        if ($this->headers->has($field)) {
590
-            return $this->headers->get($field)->getFieldBodyModel();
591
-        }
592
-    }
593
-
594
-    /**
595
-     * Set the model data for $field.
596
-     */
597
-    protected function setHeaderFieldModel($field, $model)
598
-    {
599
-        if ($this->headers->has($field)) {
600
-            $this->headers->get($field)->setFieldBodyModel($model);
601
-
602
-            return true;
603
-        }
604
-
605
-        return false;
606
-    }
607
-
608
-    /**
609
-     * Get the parameter value of $parameter on $field header.
610
-     */
611
-    protected function getHeaderParameter($field, $parameter)
612
-    {
613
-        if ($this->headers->has($field)) {
614
-            return $this->headers->get($field)->getParameter($parameter);
615
-        }
616
-    }
617
-
618
-    /**
619
-     * Set the parameter value of $parameter on $field header.
620
-     */
621
-    protected function setHeaderParameter($field, $parameter, $value)
622
-    {
623
-        if ($this->headers->has($field)) {
624
-            $this->headers->get($field)->setParameter($parameter, $value);
625
-
626
-            return true;
627
-        }
628
-
629
-        return false;
630
-    }
631
-
632
-    /**
633
-     * Re-evaluate what content type and encoding should be used on this entity.
634
-     */
635
-    protected function fixHeaders()
636
-    {
637
-        if (\count($this->immediateChildren)) {
638
-            $this->setHeaderParameter('Content-Type', 'boundary',
639
-                $this->getBoundary()
640
-                );
641
-            $this->headers->remove('Content-Transfer-Encoding');
642
-        } else {
643
-            $this->setHeaderParameter('Content-Type', 'boundary', null);
644
-            $this->setEncoding($this->encoder->getName());
645
-        }
646
-    }
647
-
648
-    /**
649
-     * Get the KeyCache used in this entity.
650
-     *
651
-     * @return Swift_KeyCache
652
-     */
653
-    protected function getCache()
654
-    {
655
-        return $this->cache;
656
-    }
657
-
658
-    /**
659
-     * Get the ID generator.
660
-     *
661
-     * @return Swift_IdGenerator
662
-     */
663
-    protected function getIdGenerator()
664
-    {
665
-        return $this->idGenerator;
666
-    }
667
-
668
-    /**
669
-     * Empty the KeyCache for this entity.
670
-     */
671
-    protected function clearCache()
672
-    {
673
-        $this->cache->clearKey($this->cacheKey, 'body');
674
-    }
675
-
676
-    private function readStream(Swift_OutputByteStream $os)
677
-    {
678
-        $string = '';
679
-        while (false !== $bytes = $os->read(8192)) {
680
-            $string .= $bytes;
681
-        }
682
-
683
-        $os->setReadPointer(0);
684
-
685
-        return $string;
686
-    }
687
-
688
-    private function setEncoding($encoding)
689
-    {
690
-        if (!$this->setHeaderFieldModel('Content-Transfer-Encoding', $encoding)) {
691
-            $this->headers->addTextHeader('Content-Transfer-Encoding', $encoding);
692
-        }
693
-    }
694
-
695
-    private function assertValidBoundary($boundary)
696
-    {
697
-        if (!preg_match('/^[a-z0-9\'\(\)\+_\-,\.\/:=\?\ ]{0,69}[a-z0-9\'\(\)\+_\-,\.\/:=\?]$/Di', $boundary)) {
698
-            throw new Swift_RfcComplianceException('Mime boundary set is not RFC 2046 compliant.');
699
-        }
700
-    }
701
-
702
-    private function setContentTypeInHeaders($type)
703
-    {
704
-        if (!$this->setHeaderFieldModel('Content-Type', $type)) {
705
-            $this->headers->addParameterizedHeader('Content-Type', $type);
706
-        }
707
-    }
708
-
709
-    private function setNestingLevel($level)
710
-    {
711
-        $this->nestingLevel = $level;
712
-    }
713
-
714
-    private function getCompoundLevel($children)
715
-    {
716
-        $level = 0;
717
-        foreach ($children as $child) {
718
-            $level |= $child->getNestingLevel();
719
-        }
720
-
721
-        return $level;
722
-    }
723
-
724
-    private function getNeededChildLevel($child, $compoundLevel)
725
-    {
726
-        $filter = [];
727
-        foreach ($this->compoundLevelFilters as $bitmask => $rules) {
728
-            if (($compoundLevel & $bitmask) === $bitmask) {
729
-                $filter = $rules + $filter;
730
-            }
731
-        }
732
-
733
-        $realLevel = $child->getNestingLevel();
734
-        $lowercaseType = strtolower($child->getContentType() ?? '');
735
-
736
-        if (isset($filter[$realLevel]) && isset($filter[$realLevel][$lowercaseType])) {
737
-            return $filter[$realLevel][$lowercaseType];
738
-        }
739
-
740
-        return $realLevel;
741
-    }
742
-
743
-    private function createChild()
744
-    {
745
-        return new self($this->headers->newInstance(), $this->encoder, $this->cache, $this->idGenerator);
746
-    }
747
-
748
-    private function notifyEncoderChanged(Swift_Mime_ContentEncoder $encoder)
749
-    {
750
-        foreach ($this->immediateChildren as $child) {
751
-            $child->encoderChanged($encoder);
752
-        }
753
-    }
754
-
755
-    private function notifyCharsetChanged($charset)
756
-    {
757
-        $this->encoder->charsetChanged($charset);
758
-        $this->headers->charsetChanged($charset);
759
-        foreach ($this->immediateChildren as $child) {
760
-            $child->charsetChanged($charset);
761
-        }
762
-    }
763
-
764
-    private function sortChildren()
765
-    {
766
-        $shouldSort = false;
767
-        foreach ($this->immediateChildren as $child) {
768
-            // NOTE: This include alternative parts moved into a related part
769
-            if (self::LEVEL_ALTERNATIVE == $child->getNestingLevel()) {
770
-                $shouldSort = true;
771
-                break;
772
-            }
773
-        }
774
-
775
-        // Sort in order of preference, if there is one
776
-        if ($shouldSort) {
777
-            // Group the messages by order of preference
778
-            $sorted = [];
779
-            foreach ($this->immediateChildren as $child) {
780
-                $type = $child->getContentType();
781
-                $level = \array_key_exists($type, $this->alternativePartOrder) ? $this->alternativePartOrder[$type] : max($this->alternativePartOrder) + 1;
782
-
783
-                if (empty($sorted[$level])) {
784
-                    $sorted[$level] = [];
785
-                }
786
-
787
-                $sorted[$level][] = $child;
788
-            }
789
-
790
-            ksort($sorted);
791
-
792
-            $this->immediateChildren = array_reduce($sorted, 'array_merge', []);
793
-        }
794
-    }
795
-
796
-    /**
797
-     * Empties it's own contents from the cache.
798
-     */
799
-    public function __destruct()
800
-    {
801
-        if ($this->cache instanceof Swift_KeyCache) {
802
-            $this->cache->clearAll($this->cacheKey);
803
-        }
804
-    }
805
-
806
-    /**
807
-     * Make a deep copy of object.
808
-     */
809
-    public function __clone()
810
-    {
811
-        $this->headers = clone $this->headers;
812
-        $this->encoder = clone $this->encoder;
813
-        $this->cacheKey = bin2hex(random_bytes(16)); // set 32 hex values
814
-        $children = [];
815
-        foreach ($this->children as $pos => $child) {
816
-            $children[$pos] = clone $child;
817
-        }
818
-        $this->setChildren($children);
819
-    }
820
-
821
-    public function __wakeup()
822
-    {
823
-        $this->cacheKey = bin2hex(random_bytes(16)); // set 32 hex values
824
-        $this->cache = new Swift_KeyCache_ArrayKeyCache(new Swift_KeyCache_SimpleKeyCacheInputStream());
825
-    }
18
+	/** Main message document; there can only be one of these */
19
+	const LEVEL_TOP = 16;
20
+
21
+	/** An entity which nests with the same precedence as an attachment */
22
+	const LEVEL_MIXED = 256;
23
+
24
+	/** An entity which nests with the same precedence as a mime part */
25
+	const LEVEL_ALTERNATIVE = 4096;
26
+
27
+	/** An entity which nests with the same precedence as embedded content */
28
+	const LEVEL_RELATED = 65536;
29
+
30
+	/** A collection of Headers for this mime entity */
31
+	private $headers;
32
+
33
+	/** The body as a string, or a stream */
34
+	private $body;
35
+
36
+	/** The encoder that encodes the body into a streamable format */
37
+	private $encoder;
38
+
39
+	/** Message ID generator */
40
+	private $idGenerator;
41
+
42
+	/** A mime boundary, if any is used */
43
+	private $boundary;
44
+
45
+	/** Mime types to be used based on the nesting level */
46
+	private $compositeRanges = [
47
+		'multipart/mixed' => [self::LEVEL_TOP, self::LEVEL_MIXED],
48
+		'multipart/alternative' => [self::LEVEL_MIXED, self::LEVEL_ALTERNATIVE],
49
+		'multipart/related' => [self::LEVEL_ALTERNATIVE, self::LEVEL_RELATED],
50
+	];
51
+
52
+	/** A set of filter rules to define what level an entity should be nested at */
53
+	private $compoundLevelFilters = [];
54
+
55
+	/** The nesting level of this entity */
56
+	private $nestingLevel = self::LEVEL_ALTERNATIVE;
57
+
58
+	/** A KeyCache instance used during encoding and streaming */
59
+	private $cache;
60
+
61
+	/** Direct descendants of this entity */
62
+	private $immediateChildren = [];
63
+
64
+	/** All descendants of this entity */
65
+	private $children = [];
66
+
67
+	/** The maximum line length of the body of this entity */
68
+	private $maxLineLength = 78;
69
+
70
+	/** The order in which alternative mime types should appear */
71
+	private $alternativePartOrder = [
72
+		'text/plain' => 1,
73
+		'text/html' => 2,
74
+		'multipart/related' => 3,
75
+	];
76
+
77
+	/** The CID of this entity */
78
+	private $id;
79
+
80
+	/** The key used for accessing the cache */
81
+	private $cacheKey;
82
+
83
+	protected $userContentType;
84
+
85
+	/**
86
+	 * Create a new SimpleMimeEntity with $headers, $encoder and $cache.
87
+	 */
88
+	public function __construct(Swift_Mime_SimpleHeaderSet $headers, Swift_Mime_ContentEncoder $encoder, Swift_KeyCache $cache, Swift_IdGenerator $idGenerator)
89
+	{
90
+		$this->cacheKey = bin2hex(random_bytes(16)); // set 32 hex values
91
+		$this->cache = $cache;
92
+		$this->headers = $headers;
93
+		$this->idGenerator = $idGenerator;
94
+		$this->setEncoder($encoder);
95
+		$this->headers->defineOrdering(['Content-Type', 'Content-Transfer-Encoding']);
96
+
97
+		// This array specifies that, when the entire MIME document contains
98
+		// $compoundLevel, then for each child within $level, if its Content-Type
99
+		// is $contentType then it should be treated as if it's level is
100
+		// $neededLevel instead.  I tried to write that unambiguously! :-\
101
+		// Data Structure:
102
+		// array (
103
+		//   $compoundLevel => array(
104
+		//     $level => array(
105
+		//       $contentType => $neededLevel
106
+		//     )
107
+		//   )
108
+		// )
109
+
110
+		$this->compoundLevelFilters = [
111
+			(self::LEVEL_ALTERNATIVE + self::LEVEL_RELATED) => [
112
+				self::LEVEL_ALTERNATIVE => [
113
+					'text/plain' => self::LEVEL_ALTERNATIVE,
114
+					'text/html' => self::LEVEL_RELATED,
115
+					],
116
+				],
117
+			];
118
+
119
+		$this->id = $this->idGenerator->generateId();
120
+	}
121
+
122
+	/**
123
+	 * Generate a new Content-ID or Message-ID for this MIME entity.
124
+	 *
125
+	 * @return string
126
+	 */
127
+	public function generateId()
128
+	{
129
+		$this->setId($this->idGenerator->generateId());
130
+
131
+		return $this->id;
132
+	}
133
+
134
+	/**
135
+	 * Get the {@link Swift_Mime_SimpleHeaderSet} for this entity.
136
+	 *
137
+	 * @return Swift_Mime_SimpleHeaderSet
138
+	 */
139
+	public function getHeaders()
140
+	{
141
+		return $this->headers;
142
+	}
143
+
144
+	/**
145
+	 * Get the nesting level of this entity.
146
+	 *
147
+	 * @see LEVEL_TOP, LEVEL_MIXED, LEVEL_RELATED, LEVEL_ALTERNATIVE
148
+	 *
149
+	 * @return int
150
+	 */
151
+	public function getNestingLevel()
152
+	{
153
+		return $this->nestingLevel;
154
+	}
155
+
156
+	/**
157
+	 * Get the Content-type of this entity.
158
+	 *
159
+	 * @return string
160
+	 */
161
+	public function getContentType()
162
+	{
163
+		return $this->getHeaderFieldModel('Content-Type');
164
+	}
165
+
166
+	/**
167
+	 * Get the Body Content-type of this entity.
168
+	 *
169
+	 * @return string
170
+	 */
171
+	public function getBodyContentType()
172
+	{
173
+		return $this->userContentType;
174
+	}
175
+
176
+	/**
177
+	 * Set the Content-type of this entity.
178
+	 *
179
+	 * @param string $type
180
+	 *
181
+	 * @return $this
182
+	 */
183
+	public function setContentType($type)
184
+	{
185
+		$this->setContentTypeInHeaders($type);
186
+		// Keep track of the value so that if the content-type changes automatically
187
+		// due to added child entities, it can be restored if they are later removed
188
+		$this->userContentType = $type;
189
+
190
+		return $this;
191
+	}
192
+
193
+	/**
194
+	 * Get the CID of this entity.
195
+	 *
196
+	 * The CID will only be present in headers if a Content-ID header is present.
197
+	 *
198
+	 * @return string
199
+	 */
200
+	public function getId()
201
+	{
202
+		$tmp = (array) $this->getHeaderFieldModel($this->getIdField());
203
+
204
+		return $this->headers->has($this->getIdField()) ? current($tmp) : $this->id;
205
+	}
206
+
207
+	/**
208
+	 * Set the CID of this entity.
209
+	 *
210
+	 * @param string $id
211
+	 *
212
+	 * @return $this
213
+	 */
214
+	public function setId($id)
215
+	{
216
+		if (!$this->setHeaderFieldModel($this->getIdField(), $id)) {
217
+			$this->headers->addIdHeader($this->getIdField(), $id);
218
+		}
219
+		$this->id = $id;
220
+
221
+		return $this;
222
+	}
223
+
224
+	/**
225
+	 * Get the description of this entity.
226
+	 *
227
+	 * This value comes from the Content-Description header if set.
228
+	 *
229
+	 * @return string
230
+	 */
231
+	public function getDescription()
232
+	{
233
+		return $this->getHeaderFieldModel('Content-Description');
234
+	}
235
+
236
+	/**
237
+	 * Set the description of this entity.
238
+	 *
239
+	 * This method sets a value in the Content-ID header.
240
+	 *
241
+	 * @param string $description
242
+	 *
243
+	 * @return $this
244
+	 */
245
+	public function setDescription($description)
246
+	{
247
+		if (!$this->setHeaderFieldModel('Content-Description', $description)) {
248
+			$this->headers->addTextHeader('Content-Description', $description);
249
+		}
250
+
251
+		return $this;
252
+	}
253
+
254
+	/**
255
+	 * Get the maximum line length of the body of this entity.
256
+	 *
257
+	 * @return int
258
+	 */
259
+	public function getMaxLineLength()
260
+	{
261
+		return $this->maxLineLength;
262
+	}
263
+
264
+	/**
265
+	 * Set the maximum line length of lines in this body.
266
+	 *
267
+	 * Though not enforced by the library, lines should not exceed 1000 chars.
268
+	 *
269
+	 * @param int $length
270
+	 *
271
+	 * @return $this
272
+	 */
273
+	public function setMaxLineLength($length)
274
+	{
275
+		$this->maxLineLength = $length;
276
+
277
+		return $this;
278
+	}
279
+
280
+	/**
281
+	 * Get all children added to this entity.
282
+	 *
283
+	 * @return Swift_Mime_SimpleMimeEntity[]
284
+	 */
285
+	public function getChildren()
286
+	{
287
+		return $this->children;
288
+	}
289
+
290
+	/**
291
+	 * Set all children of this entity.
292
+	 *
293
+	 * @param Swift_Mime_SimpleMimeEntity[] $children
294
+	 * @param int                           $compoundLevel For internal use only
295
+	 *
296
+	 * @return $this
297
+	 */
298
+	public function setChildren(array $children, $compoundLevel = null)
299
+	{
300
+		// TODO: Try to refactor this logic
301
+		$compoundLevel = $compoundLevel ?? $this->getCompoundLevel($children);
302
+		$immediateChildren = [];
303
+		$grandchildren = [];
304
+		$newContentType = $this->userContentType;
305
+
306
+		foreach ($children as $child) {
307
+			$level = $this->getNeededChildLevel($child, $compoundLevel);
308
+			if (empty($immediateChildren)) {
309
+				//first iteration
310
+				$immediateChildren = [$child];
311
+			} else {
312
+				$nextLevel = $this->getNeededChildLevel($immediateChildren[0], $compoundLevel);
313
+				if ($nextLevel == $level) {
314
+					$immediateChildren[] = $child;
315
+				} elseif ($level < $nextLevel) {
316
+					// Re-assign immediateChildren to grandchildren
317
+					$grandchildren = array_merge($grandchildren, $immediateChildren);
318
+					// Set new children
319
+					$immediateChildren = [$child];
320
+				} else {
321
+					$grandchildren[] = $child;
322
+				}
323
+			}
324
+		}
325
+
326
+		if ($immediateChildren) {
327
+			$lowestLevel = $this->getNeededChildLevel($immediateChildren[0], $compoundLevel);
328
+
329
+			// Determine which composite media type is needed to accommodate the
330
+			// immediate children
331
+			foreach ($this->compositeRanges as $mediaType => $range) {
332
+				if ($lowestLevel > $range[0] && $lowestLevel <= $range[1]) {
333
+					$newContentType = $mediaType;
334
+
335
+					break;
336
+				}
337
+			}
338
+
339
+			// Put any grandchildren in a subpart
340
+			if (!empty($grandchildren)) {
341
+				$subentity = $this->createChild();
342
+				$subentity->setNestingLevel($lowestLevel);
343
+				$subentity->setChildren($grandchildren, $compoundLevel);
344
+				array_unshift($immediateChildren, $subentity);
345
+			}
346
+		}
347
+
348
+		$this->immediateChildren = $immediateChildren;
349
+		$this->children = $children;
350
+		$this->setContentTypeInHeaders($newContentType);
351
+		$this->fixHeaders();
352
+		$this->sortChildren();
353
+
354
+		return $this;
355
+	}
356
+
357
+	/**
358
+	 * Get the body of this entity as a string.
359
+	 *
360
+	 * @return string
361
+	 */
362
+	public function getBody()
363
+	{
364
+		return $this->body instanceof Swift_OutputByteStream ? $this->readStream($this->body) : $this->body;
365
+	}
366
+
367
+	/**
368
+	 * Set the body of this entity, either as a string, or as an instance of
369
+	 * {@link Swift_OutputByteStream}.
370
+	 *
371
+	 * @param mixed  $body
372
+	 * @param string $contentType optional
373
+	 *
374
+	 * @return $this
375
+	 */
376
+	public function setBody($body, $contentType = null)
377
+	{
378
+		if ($body !== $this->body) {
379
+			$this->clearCache();
380
+		}
381
+
382
+		$this->body = $body;
383
+		if (null !== $contentType) {
384
+			$this->setContentType($contentType);
385
+		}
386
+
387
+		return $this;
388
+	}
389
+
390
+	/**
391
+	 * Get the encoder used for the body of this entity.
392
+	 *
393
+	 * @return Swift_Mime_ContentEncoder
394
+	 */
395
+	public function getEncoder()
396
+	{
397
+		return $this->encoder;
398
+	}
399
+
400
+	/**
401
+	 * Set the encoder used for the body of this entity.
402
+	 *
403
+	 * @return $this
404
+	 */
405
+	public function setEncoder(Swift_Mime_ContentEncoder $encoder)
406
+	{
407
+		if ($encoder !== $this->encoder) {
408
+			$this->clearCache();
409
+		}
410
+
411
+		$this->encoder = $encoder;
412
+		$this->setEncoding($encoder->getName());
413
+		$this->notifyEncoderChanged($encoder);
414
+
415
+		return $this;
416
+	}
417
+
418
+	/**
419
+	 * Get the boundary used to separate children in this entity.
420
+	 *
421
+	 * @return string
422
+	 */
423
+	public function getBoundary()
424
+	{
425
+		if (!isset($this->boundary)) {
426
+			$this->boundary = '_=_swift_'.time().'_'.bin2hex(random_bytes(16)).'_=_';
427
+		}
428
+
429
+		return $this->boundary;
430
+	}
431
+
432
+	/**
433
+	 * Set the boundary used to separate children in this entity.
434
+	 *
435
+	 * @param string $boundary
436
+	 *
437
+	 * @throws Swift_RfcComplianceException
438
+	 *
439
+	 * @return $this
440
+	 */
441
+	public function setBoundary($boundary)
442
+	{
443
+		$this->assertValidBoundary($boundary);
444
+		$this->boundary = $boundary;
445
+
446
+		return $this;
447
+	}
448
+
449
+	/**
450
+	 * Receive notification that the charset of this entity, or a parent entity
451
+	 * has changed.
452
+	 *
453
+	 * @param string $charset
454
+	 */
455
+	public function charsetChanged($charset)
456
+	{
457
+		$this->notifyCharsetChanged($charset);
458
+	}
459
+
460
+	/**
461
+	 * Receive notification that the encoder of this entity or a parent entity
462
+	 * has changed.
463
+	 */
464
+	public function encoderChanged(Swift_Mime_ContentEncoder $encoder)
465
+	{
466
+		$this->notifyEncoderChanged($encoder);
467
+	}
468
+
469
+	/**
470
+	 * Get this entire entity as a string.
471
+	 *
472
+	 * @return string
473
+	 */
474
+	public function toString()
475
+	{
476
+		$string = $this->headers->toString();
477
+		$string .= $this->bodyToString();
478
+
479
+		return $string;
480
+	}
481
+
482
+	/**
483
+	 * Get this entire entity as a string.
484
+	 *
485
+	 * @return string
486
+	 */
487
+	protected function bodyToString()
488
+	{
489
+		$string = '';
490
+
491
+		if (isset($this->body) && empty($this->immediateChildren)) {
492
+			if ($this->cache->hasKey($this->cacheKey, 'body')) {
493
+				$body = $this->cache->getString($this->cacheKey, 'body');
494
+			} else {
495
+				$body = "\r\n".$this->encoder->encodeString($this->getBody(), 0, $this->getMaxLineLength());
496
+				$this->cache->setString($this->cacheKey, 'body', $body, Swift_KeyCache::MODE_WRITE);
497
+			}
498
+			$string .= $body;
499
+		}
500
+
501
+		if (!empty($this->immediateChildren)) {
502
+			foreach ($this->immediateChildren as $child) {
503
+				$string .= "\r\n\r\n--".$this->getBoundary()."\r\n";
504
+				$string .= $child->toString();
505
+			}
506
+			$string .= "\r\n\r\n--".$this->getBoundary()."--\r\n";
507
+		}
508
+
509
+		return $string;
510
+	}
511
+
512
+	/**
513
+	 * Returns a string representation of this object.
514
+	 *
515
+	 * @see toString()
516
+	 *
517
+	 * @return string
518
+	 */
519
+	public function __toString()
520
+	{
521
+		return $this->toString();
522
+	}
523
+
524
+	/**
525
+	 * Write this entire entity to a {@see Swift_InputByteStream}.
526
+	 */
527
+	public function toByteStream(Swift_InputByteStream $is)
528
+	{
529
+		$is->write($this->headers->toString());
530
+		$is->commit();
531
+
532
+		$this->bodyToByteStream($is);
533
+	}
534
+
535
+	/**
536
+	 * Write this entire entity to a {@link Swift_InputByteStream}.
537
+	 */
538
+	protected function bodyToByteStream(Swift_InputByteStream $is)
539
+	{
540
+		if (empty($this->immediateChildren)) {
541
+			if (isset($this->body)) {
542
+				if ($this->cache->hasKey($this->cacheKey, 'body')) {
543
+					$this->cache->exportToByteStream($this->cacheKey, 'body', $is);
544
+				} else {
545
+					$cacheIs = $this->cache->getInputByteStream($this->cacheKey, 'body');
546
+					if ($cacheIs) {
547
+						$is->bind($cacheIs);
548
+					}
549
+
550
+					$is->write("\r\n");
551
+
552
+					if ($this->body instanceof Swift_OutputByteStream) {
553
+						$this->body->setReadPointer(0);
554
+
555
+						$this->encoder->encodeByteStream($this->body, $is, 0, $this->getMaxLineLength());
556
+					} else {
557
+						$is->write($this->encoder->encodeString($this->getBody(), 0, $this->getMaxLineLength()));
558
+					}
559
+
560
+					if ($cacheIs) {
561
+						$is->unbind($cacheIs);
562
+					}
563
+				}
564
+			}
565
+		}
566
+
567
+		if (!empty($this->immediateChildren)) {
568
+			foreach ($this->immediateChildren as $child) {
569
+				$is->write("\r\n\r\n--".$this->getBoundary()."\r\n");
570
+				$child->toByteStream($is);
571
+			}
572
+			$is->write("\r\n\r\n--".$this->getBoundary()."--\r\n");
573
+		}
574
+	}
575
+
576
+	/**
577
+	 * Get the name of the header that provides the ID of this entity.
578
+	 */
579
+	protected function getIdField()
580
+	{
581
+		return 'Content-ID';
582
+	}
583
+
584
+	/**
585
+	 * Get the model data (usually an array or a string) for $field.
586
+	 */
587
+	protected function getHeaderFieldModel($field)
588
+	{
589
+		if ($this->headers->has($field)) {
590
+			return $this->headers->get($field)->getFieldBodyModel();
591
+		}
592
+	}
593
+
594
+	/**
595
+	 * Set the model data for $field.
596
+	 */
597
+	protected function setHeaderFieldModel($field, $model)
598
+	{
599
+		if ($this->headers->has($field)) {
600
+			$this->headers->get($field)->setFieldBodyModel($model);
601
+
602
+			return true;
603
+		}
604
+
605
+		return false;
606
+	}
607
+
608
+	/**
609
+	 * Get the parameter value of $parameter on $field header.
610
+	 */
611
+	protected function getHeaderParameter($field, $parameter)
612
+	{
613
+		if ($this->headers->has($field)) {
614
+			return $this->headers->get($field)->getParameter($parameter);
615
+		}
616
+	}
617
+
618
+	/**
619
+	 * Set the parameter value of $parameter on $field header.
620
+	 */
621
+	protected function setHeaderParameter($field, $parameter, $value)
622
+	{
623
+		if ($this->headers->has($field)) {
624
+			$this->headers->get($field)->setParameter($parameter, $value);
625
+
626
+			return true;
627
+		}
628
+
629
+		return false;
630
+	}
631
+
632
+	/**
633
+	 * Re-evaluate what content type and encoding should be used on this entity.
634
+	 */
635
+	protected function fixHeaders()
636
+	{
637
+		if (\count($this->immediateChildren)) {
638
+			$this->setHeaderParameter('Content-Type', 'boundary',
639
+				$this->getBoundary()
640
+				);
641
+			$this->headers->remove('Content-Transfer-Encoding');
642
+		} else {
643
+			$this->setHeaderParameter('Content-Type', 'boundary', null);
644
+			$this->setEncoding($this->encoder->getName());
645
+		}
646
+	}
647
+
648
+	/**
649
+	 * Get the KeyCache used in this entity.
650
+	 *
651
+	 * @return Swift_KeyCache
652
+	 */
653
+	protected function getCache()
654
+	{
655
+		return $this->cache;
656
+	}
657
+
658
+	/**
659
+	 * Get the ID generator.
660
+	 *
661
+	 * @return Swift_IdGenerator
662
+	 */
663
+	protected function getIdGenerator()
664
+	{
665
+		return $this->idGenerator;
666
+	}
667
+
668
+	/**
669
+	 * Empty the KeyCache for this entity.
670
+	 */
671
+	protected function clearCache()
672
+	{
673
+		$this->cache->clearKey($this->cacheKey, 'body');
674
+	}
675
+
676
+	private function readStream(Swift_OutputByteStream $os)
677
+	{
678
+		$string = '';
679
+		while (false !== $bytes = $os->read(8192)) {
680
+			$string .= $bytes;
681
+		}
682
+
683
+		$os->setReadPointer(0);
684
+
685
+		return $string;
686
+	}
687
+
688
+	private function setEncoding($encoding)
689
+	{
690
+		if (!$this->setHeaderFieldModel('Content-Transfer-Encoding', $encoding)) {
691
+			$this->headers->addTextHeader('Content-Transfer-Encoding', $encoding);
692
+		}
693
+	}
694
+
695
+	private function assertValidBoundary($boundary)
696
+	{
697
+		if (!preg_match('/^[a-z0-9\'\(\)\+_\-,\.\/:=\?\ ]{0,69}[a-z0-9\'\(\)\+_\-,\.\/:=\?]$/Di', $boundary)) {
698
+			throw new Swift_RfcComplianceException('Mime boundary set is not RFC 2046 compliant.');
699
+		}
700
+	}
701
+
702
+	private function setContentTypeInHeaders($type)
703
+	{
704
+		if (!$this->setHeaderFieldModel('Content-Type', $type)) {
705
+			$this->headers->addParameterizedHeader('Content-Type', $type);
706
+		}
707
+	}
708
+
709
+	private function setNestingLevel($level)
710
+	{
711
+		$this->nestingLevel = $level;
712
+	}
713
+
714
+	private function getCompoundLevel($children)
715
+	{
716
+		$level = 0;
717
+		foreach ($children as $child) {
718
+			$level |= $child->getNestingLevel();
719
+		}
720
+
721
+		return $level;
722
+	}
723
+
724
+	private function getNeededChildLevel($child, $compoundLevel)
725
+	{
726
+		$filter = [];
727
+		foreach ($this->compoundLevelFilters as $bitmask => $rules) {
728
+			if (($compoundLevel & $bitmask) === $bitmask) {
729
+				$filter = $rules + $filter;
730
+			}
731
+		}
732
+
733
+		$realLevel = $child->getNestingLevel();
734
+		$lowercaseType = strtolower($child->getContentType() ?? '');
735
+
736
+		if (isset($filter[$realLevel]) && isset($filter[$realLevel][$lowercaseType])) {
737
+			return $filter[$realLevel][$lowercaseType];
738
+		}
739
+
740
+		return $realLevel;
741
+	}
742
+
743
+	private function createChild()
744
+	{
745
+		return new self($this->headers->newInstance(), $this->encoder, $this->cache, $this->idGenerator);
746
+	}
747
+
748
+	private function notifyEncoderChanged(Swift_Mime_ContentEncoder $encoder)
749
+	{
750
+		foreach ($this->immediateChildren as $child) {
751
+			$child->encoderChanged($encoder);
752
+		}
753
+	}
754
+
755
+	private function notifyCharsetChanged($charset)
756
+	{
757
+		$this->encoder->charsetChanged($charset);
758
+		$this->headers->charsetChanged($charset);
759
+		foreach ($this->immediateChildren as $child) {
760
+			$child->charsetChanged($charset);
761
+		}
762
+	}
763
+
764
+	private function sortChildren()
765
+	{
766
+		$shouldSort = false;
767
+		foreach ($this->immediateChildren as $child) {
768
+			// NOTE: This include alternative parts moved into a related part
769
+			if (self::LEVEL_ALTERNATIVE == $child->getNestingLevel()) {
770
+				$shouldSort = true;
771
+				break;
772
+			}
773
+		}
774
+
775
+		// Sort in order of preference, if there is one
776
+		if ($shouldSort) {
777
+			// Group the messages by order of preference
778
+			$sorted = [];
779
+			foreach ($this->immediateChildren as $child) {
780
+				$type = $child->getContentType();
781
+				$level = \array_key_exists($type, $this->alternativePartOrder) ? $this->alternativePartOrder[$type] : max($this->alternativePartOrder) + 1;
782
+
783
+				if (empty($sorted[$level])) {
784
+					$sorted[$level] = [];
785
+				}
786
+
787
+				$sorted[$level][] = $child;
788
+			}
789
+
790
+			ksort($sorted);
791
+
792
+			$this->immediateChildren = array_reduce($sorted, 'array_merge', []);
793
+		}
794
+	}
795
+
796
+	/**
797
+	 * Empties it's own contents from the cache.
798
+	 */
799
+	public function __destruct()
800
+	{
801
+		if ($this->cache instanceof Swift_KeyCache) {
802
+			$this->cache->clearAll($this->cacheKey);
803
+		}
804
+	}
805
+
806
+	/**
807
+	 * Make a deep copy of object.
808
+	 */
809
+	public function __clone()
810
+	{
811
+		$this->headers = clone $this->headers;
812
+		$this->encoder = clone $this->encoder;
813
+		$this->cacheKey = bin2hex(random_bytes(16)); // set 32 hex values
814
+		$children = [];
815
+		foreach ($this->children as $pos => $child) {
816
+			$children[$pos] = clone $child;
817
+		}
818
+		$this->setChildren($children);
819
+	}
820
+
821
+	public function __wakeup()
822
+	{
823
+		$this->cacheKey = bin2hex(random_bytes(16)); // set 32 hex values
824
+		$this->cache = new Swift_KeyCache_ArrayKeyCache(new Swift_KeyCache_SimpleKeyCacheInputStream());
825
+	}
826 826
 }
Please login to merge, or discard this patch.
htdocs/includes/swiftmailer/lib/classes/Swift/Mime/MimePart.php 1 patch
Indentation   +181 added lines, -181 removed lines patch added patch discarded remove patch
@@ -15,185 +15,185 @@
 block discarded – undo
15 15
  */
16 16
 class Swift_Mime_MimePart extends Swift_Mime_SimpleMimeEntity
17 17
 {
18
-    /** The format parameter last specified by the user */
19
-    protected $userFormat;
20
-
21
-    /** The charset last specified by the user */
22
-    protected $userCharset;
23
-
24
-    /** The delsp parameter last specified by the user */
25
-    protected $userDelSp;
26
-
27
-    /** The nesting level of this MimePart */
28
-    private $nestingLevel = self::LEVEL_ALTERNATIVE;
29
-
30
-    /**
31
-     * Create a new MimePart with $headers, $encoder and $cache.
32
-     *
33
-     * @param string $charset
34
-     */
35
-    public function __construct(Swift_Mime_SimpleHeaderSet $headers, Swift_Mime_ContentEncoder $encoder, Swift_KeyCache $cache, Swift_IdGenerator $idGenerator, $charset = null)
36
-    {
37
-        parent::__construct($headers, $encoder, $cache, $idGenerator);
38
-        $this->setContentType('text/plain');
39
-        if (null !== $charset) {
40
-            $this->setCharset($charset);
41
-        }
42
-    }
43
-
44
-    /**
45
-     * Set the body of this entity, either as a string, or as an instance of
46
-     * {@link Swift_OutputByteStream}.
47
-     *
48
-     * @param mixed  $body
49
-     * @param string $contentType optional
50
-     * @param string $charset     optional
51
-     *
52
-     * @return $this
53
-     */
54
-    public function setBody($body, $contentType = null, $charset = null)
55
-    {
56
-        if (isset($charset)) {
57
-            $this->setCharset($charset);
58
-        }
59
-        $body = $this->convertString($body);
60
-
61
-        parent::setBody($body, $contentType);
62
-
63
-        return $this;
64
-    }
65
-
66
-    /**
67
-     * Get the character set of this entity.
68
-     *
69
-     * @return string
70
-     */
71
-    public function getCharset()
72
-    {
73
-        return $this->getHeaderParameter('Content-Type', 'charset');
74
-    }
75
-
76
-    /**
77
-     * Set the character set of this entity.
78
-     *
79
-     * @param string $charset
80
-     *
81
-     * @return $this
82
-     */
83
-    public function setCharset($charset)
84
-    {
85
-        $this->setHeaderParameter('Content-Type', 'charset', $charset);
86
-        if ($charset !== $this->userCharset) {
87
-            $this->clearCache();
88
-        }
89
-        $this->userCharset = $charset;
90
-        parent::charsetChanged($charset);
91
-
92
-        return $this;
93
-    }
94
-
95
-    /**
96
-     * Get the format of this entity (i.e. flowed or fixed).
97
-     *
98
-     * @return string
99
-     */
100
-    public function getFormat()
101
-    {
102
-        return $this->getHeaderParameter('Content-Type', 'format');
103
-    }
104
-
105
-    /**
106
-     * Set the format of this entity (flowed or fixed).
107
-     *
108
-     * @param string $format
109
-     *
110
-     * @return $this
111
-     */
112
-    public function setFormat($format)
113
-    {
114
-        $this->setHeaderParameter('Content-Type', 'format', $format);
115
-        $this->userFormat = $format;
116
-
117
-        return $this;
118
-    }
119
-
120
-    /**
121
-     * Test if delsp is being used for this entity.
122
-     *
123
-     * @return bool
124
-     */
125
-    public function getDelSp()
126
-    {
127
-        return 'yes' === $this->getHeaderParameter('Content-Type', 'delsp');
128
-    }
129
-
130
-    /**
131
-     * Turn delsp on or off for this entity.
132
-     *
133
-     * @param bool $delsp
134
-     *
135
-     * @return $this
136
-     */
137
-    public function setDelSp($delsp = true)
138
-    {
139
-        $this->setHeaderParameter('Content-Type', 'delsp', $delsp ? 'yes' : null);
140
-        $this->userDelSp = $delsp;
141
-
142
-        return $this;
143
-    }
144
-
145
-    /**
146
-     * Get the nesting level of this entity.
147
-     *
148
-     * @see LEVEL_TOP, LEVEL_ALTERNATIVE, LEVEL_MIXED, LEVEL_RELATED
149
-     *
150
-     * @return int
151
-     */
152
-    public function getNestingLevel()
153
-    {
154
-        return $this->nestingLevel;
155
-    }
156
-
157
-    /**
158
-     * Receive notification that the charset has changed on this document, or a
159
-     * parent document.
160
-     *
161
-     * @param string $charset
162
-     */
163
-    public function charsetChanged($charset)
164
-    {
165
-        $this->setCharset($charset);
166
-    }
167
-
168
-    /** Fix the content-type and encoding of this entity */
169
-    protected function fixHeaders()
170
-    {
171
-        parent::fixHeaders();
172
-        if (\count($this->getChildren())) {
173
-            $this->setHeaderParameter('Content-Type', 'charset', null);
174
-            $this->setHeaderParameter('Content-Type', 'format', null);
175
-            $this->setHeaderParameter('Content-Type', 'delsp', null);
176
-        } else {
177
-            $this->setCharset($this->userCharset);
178
-            $this->setFormat($this->userFormat);
179
-            $this->setDelSp($this->userDelSp);
180
-        }
181
-    }
182
-
183
-    /** Set the nesting level of this entity */
184
-    protected function setNestingLevel($level)
185
-    {
186
-        $this->nestingLevel = $level;
187
-    }
188
-
189
-    /** Encode charset when charset is not utf-8 */
190
-    protected function convertString($string)
191
-    {
192
-        $charset = strtolower($this->getCharset() ?? '');
193
-        if (!\in_array($charset, ['utf-8', 'iso-8859-1', 'iso-8859-15', ''])) {
194
-            return mb_convert_encoding($string, $charset, 'utf-8');
195
-        }
196
-
197
-        return $string;
198
-    }
18
+	/** The format parameter last specified by the user */
19
+	protected $userFormat;
20
+
21
+	/** The charset last specified by the user */
22
+	protected $userCharset;
23
+
24
+	/** The delsp parameter last specified by the user */
25
+	protected $userDelSp;
26
+
27
+	/** The nesting level of this MimePart */
28
+	private $nestingLevel = self::LEVEL_ALTERNATIVE;
29
+
30
+	/**
31
+	 * Create a new MimePart with $headers, $encoder and $cache.
32
+	 *
33
+	 * @param string $charset
34
+	 */
35
+	public function __construct(Swift_Mime_SimpleHeaderSet $headers, Swift_Mime_ContentEncoder $encoder, Swift_KeyCache $cache, Swift_IdGenerator $idGenerator, $charset = null)
36
+	{
37
+		parent::__construct($headers, $encoder, $cache, $idGenerator);
38
+		$this->setContentType('text/plain');
39
+		if (null !== $charset) {
40
+			$this->setCharset($charset);
41
+		}
42
+	}
43
+
44
+	/**
45
+	 * Set the body of this entity, either as a string, or as an instance of
46
+	 * {@link Swift_OutputByteStream}.
47
+	 *
48
+	 * @param mixed  $body
49
+	 * @param string $contentType optional
50
+	 * @param string $charset     optional
51
+	 *
52
+	 * @return $this
53
+	 */
54
+	public function setBody($body, $contentType = null, $charset = null)
55
+	{
56
+		if (isset($charset)) {
57
+			$this->setCharset($charset);
58
+		}
59
+		$body = $this->convertString($body);
60
+
61
+		parent::setBody($body, $contentType);
62
+
63
+		return $this;
64
+	}
65
+
66
+	/**
67
+	 * Get the character set of this entity.
68
+	 *
69
+	 * @return string
70
+	 */
71
+	public function getCharset()
72
+	{
73
+		return $this->getHeaderParameter('Content-Type', 'charset');
74
+	}
75
+
76
+	/**
77
+	 * Set the character set of this entity.
78
+	 *
79
+	 * @param string $charset
80
+	 *
81
+	 * @return $this
82
+	 */
83
+	public function setCharset($charset)
84
+	{
85
+		$this->setHeaderParameter('Content-Type', 'charset', $charset);
86
+		if ($charset !== $this->userCharset) {
87
+			$this->clearCache();
88
+		}
89
+		$this->userCharset = $charset;
90
+		parent::charsetChanged($charset);
91
+
92
+		return $this;
93
+	}
94
+
95
+	/**
96
+	 * Get the format of this entity (i.e. flowed or fixed).
97
+	 *
98
+	 * @return string
99
+	 */
100
+	public function getFormat()
101
+	{
102
+		return $this->getHeaderParameter('Content-Type', 'format');
103
+	}
104
+
105
+	/**
106
+	 * Set the format of this entity (flowed or fixed).
107
+	 *
108
+	 * @param string $format
109
+	 *
110
+	 * @return $this
111
+	 */
112
+	public function setFormat($format)
113
+	{
114
+		$this->setHeaderParameter('Content-Type', 'format', $format);
115
+		$this->userFormat = $format;
116
+
117
+		return $this;
118
+	}
119
+
120
+	/**
121
+	 * Test if delsp is being used for this entity.
122
+	 *
123
+	 * @return bool
124
+	 */
125
+	public function getDelSp()
126
+	{
127
+		return 'yes' === $this->getHeaderParameter('Content-Type', 'delsp');
128
+	}
129
+
130
+	/**
131
+	 * Turn delsp on or off for this entity.
132
+	 *
133
+	 * @param bool $delsp
134
+	 *
135
+	 * @return $this
136
+	 */
137
+	public function setDelSp($delsp = true)
138
+	{
139
+		$this->setHeaderParameter('Content-Type', 'delsp', $delsp ? 'yes' : null);
140
+		$this->userDelSp = $delsp;
141
+
142
+		return $this;
143
+	}
144
+
145
+	/**
146
+	 * Get the nesting level of this entity.
147
+	 *
148
+	 * @see LEVEL_TOP, LEVEL_ALTERNATIVE, LEVEL_MIXED, LEVEL_RELATED
149
+	 *
150
+	 * @return int
151
+	 */
152
+	public function getNestingLevel()
153
+	{
154
+		return $this->nestingLevel;
155
+	}
156
+
157
+	/**
158
+	 * Receive notification that the charset has changed on this document, or a
159
+	 * parent document.
160
+	 *
161
+	 * @param string $charset
162
+	 */
163
+	public function charsetChanged($charset)
164
+	{
165
+		$this->setCharset($charset);
166
+	}
167
+
168
+	/** Fix the content-type and encoding of this entity */
169
+	protected function fixHeaders()
170
+	{
171
+		parent::fixHeaders();
172
+		if (\count($this->getChildren())) {
173
+			$this->setHeaderParameter('Content-Type', 'charset', null);
174
+			$this->setHeaderParameter('Content-Type', 'format', null);
175
+			$this->setHeaderParameter('Content-Type', 'delsp', null);
176
+		} else {
177
+			$this->setCharset($this->userCharset);
178
+			$this->setFormat($this->userFormat);
179
+			$this->setDelSp($this->userDelSp);
180
+		}
181
+	}
182
+
183
+	/** Set the nesting level of this entity */
184
+	protected function setNestingLevel($level)
185
+	{
186
+		$this->nestingLevel = $level;
187
+	}
188
+
189
+	/** Encode charset when charset is not utf-8 */
190
+	protected function convertString($string)
191
+	{
192
+		$charset = strtolower($this->getCharset() ?? '');
193
+		if (!\in_array($charset, ['utf-8', 'iso-8859-1', 'iso-8859-15', ''])) {
194
+			return mb_convert_encoding($string, $charset, 'utf-8');
195
+		}
196
+
197
+		return $string;
198
+	}
199 199
 }
Please login to merge, or discard this patch.
htdocs/includes/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder.php 1 patch
Indentation   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -15,10 +15,10 @@
 block discarded – undo
15 15
  */
16 16
 interface Swift_Mime_HeaderEncoder extends Swift_Encoder
17 17
 {
18
-    /**
19
-     * Get the MIME name of this content encoding scheme.
20
-     *
21
-     * @return string
22
-     */
23
-    public function getName();
18
+	/**
19
+	 * Get the MIME name of this content encoding scheme.
20
+	 *
21
+	 * @return string
22
+	 */
23
+	public function getName();
24 24
 }
Please login to merge, or discard this patch.
htdocs/includes/swiftmailer/lib/classes/Swift/Mime/Attachment.php 1 patch
Indentation   +126 added lines, -126 removed lines patch added patch discarded remove patch
@@ -15,130 +15,130 @@
 block discarded – undo
15 15
  */
16 16
 class Swift_Mime_Attachment extends Swift_Mime_SimpleMimeEntity
17 17
 {
18
-    /** Recognized MIME types */
19
-    private $mimeTypes = [];
20
-
21
-    /**
22
-     * Create a new Attachment with $headers, $encoder and $cache.
23
-     *
24
-     * @param array $mimeTypes
25
-     */
26
-    public function __construct(Swift_Mime_SimpleHeaderSet $headers, Swift_Mime_ContentEncoder $encoder, Swift_KeyCache $cache, Swift_IdGenerator $idGenerator, $mimeTypes = [])
27
-    {
28
-        parent::__construct($headers, $encoder, $cache, $idGenerator);
29
-        $this->setDisposition('attachment');
30
-        $this->setContentType('application/octet-stream');
31
-        $this->mimeTypes = $mimeTypes;
32
-    }
33
-
34
-    /**
35
-     * Get the nesting level used for this attachment.
36
-     *
37
-     * Always returns {@link LEVEL_MIXED}.
38
-     *
39
-     * @return int
40
-     */
41
-    public function getNestingLevel()
42
-    {
43
-        return self::LEVEL_MIXED;
44
-    }
45
-
46
-    /**
47
-     * Get the Content-Disposition of this attachment.
48
-     *
49
-     * By default attachments have a disposition of "attachment".
50
-     *
51
-     * @return string
52
-     */
53
-    public function getDisposition()
54
-    {
55
-        return $this->getHeaderFieldModel('Content-Disposition');
56
-    }
57
-
58
-    /**
59
-     * Set the Content-Disposition of this attachment.
60
-     *
61
-     * @param string $disposition
62
-     *
63
-     * @return $this
64
-     */
65
-    public function setDisposition($disposition)
66
-    {
67
-        if (!$this->setHeaderFieldModel('Content-Disposition', $disposition)) {
68
-            $this->getHeaders()->addParameterizedHeader('Content-Disposition', $disposition);
69
-        }
70
-
71
-        return $this;
72
-    }
73
-
74
-    /**
75
-     * Get the filename of this attachment when downloaded.
76
-     *
77
-     * @return string
78
-     */
79
-    public function getFilename()
80
-    {
81
-        return $this->getHeaderParameter('Content-Disposition', 'filename');
82
-    }
83
-
84
-    /**
85
-     * Set the filename of this attachment.
86
-     *
87
-     * @param string $filename
88
-     *
89
-     * @return $this
90
-     */
91
-    public function setFilename($filename)
92
-    {
93
-        $this->setHeaderParameter('Content-Disposition', 'filename', $filename);
94
-        $this->setHeaderParameter('Content-Type', 'name', $filename);
95
-
96
-        return $this;
97
-    }
98
-
99
-    /**
100
-     * Get the file size of this attachment.
101
-     *
102
-     * @return int
103
-     */
104
-    public function getSize()
105
-    {
106
-        return $this->getHeaderParameter('Content-Disposition', 'size');
107
-    }
108
-
109
-    /**
110
-     * Set the file size of this attachment.
111
-     *
112
-     * @param int $size
113
-     *
114
-     * @return $this
115
-     */
116
-    public function setSize($size)
117
-    {
118
-        $this->setHeaderParameter('Content-Disposition', 'size', $size);
119
-
120
-        return $this;
121
-    }
122
-
123
-    /**
124
-     * Set the file that this attachment is for.
125
-     *
126
-     * @param string $contentType optional
127
-     *
128
-     * @return $this
129
-     */
130
-    public function setFile(Swift_FileStream $file, $contentType = null)
131
-    {
132
-        $this->setFilename(basename($file->getPath()));
133
-        $this->setBody($file, $contentType);
134
-        if (!isset($contentType)) {
135
-            $extension = strtolower(substr($file->getPath(), strrpos($file->getPath(), '.') + 1));
136
-
137
-            if (\array_key_exists($extension, $this->mimeTypes)) {
138
-                $this->setContentType($this->mimeTypes[$extension]);
139
-            }
140
-        }
141
-
142
-        return $this;
143
-    }
18
+	/** Recognized MIME types */
19
+	private $mimeTypes = [];
20
+
21
+	/**
22
+	 * Create a new Attachment with $headers, $encoder and $cache.
23
+	 *
24
+	 * @param array $mimeTypes
25
+	 */
26
+	public function __construct(Swift_Mime_SimpleHeaderSet $headers, Swift_Mime_ContentEncoder $encoder, Swift_KeyCache $cache, Swift_IdGenerator $idGenerator, $mimeTypes = [])
27
+	{
28
+		parent::__construct($headers, $encoder, $cache, $idGenerator);
29
+		$this->setDisposition('attachment');
30
+		$this->setContentType('application/octet-stream');
31
+		$this->mimeTypes = $mimeTypes;
32
+	}
33
+
34
+	/**
35
+	 * Get the nesting level used for this attachment.
36
+	 *
37
+	 * Always returns {@link LEVEL_MIXED}.
38
+	 *
39
+	 * @return int
40
+	 */
41
+	public function getNestingLevel()
42
+	{
43
+		return self::LEVEL_MIXED;
44
+	}
45
+
46
+	/**
47
+	 * Get the Content-Disposition of this attachment.
48
+	 *
49
+	 * By default attachments have a disposition of "attachment".
50
+	 *
51
+	 * @return string
52
+	 */
53
+	public function getDisposition()
54
+	{
55
+		return $this->getHeaderFieldModel('Content-Disposition');
56
+	}
57
+
58
+	/**
59
+	 * Set the Content-Disposition of this attachment.
60
+	 *
61
+	 * @param string $disposition
62
+	 *
63
+	 * @return $this
64
+	 */
65
+	public function setDisposition($disposition)
66
+	{
67
+		if (!$this->setHeaderFieldModel('Content-Disposition', $disposition)) {
68
+			$this->getHeaders()->addParameterizedHeader('Content-Disposition', $disposition);
69
+		}
70
+
71
+		return $this;
72
+	}
73
+
74
+	/**
75
+	 * Get the filename of this attachment when downloaded.
76
+	 *
77
+	 * @return string
78
+	 */
79
+	public function getFilename()
80
+	{
81
+		return $this->getHeaderParameter('Content-Disposition', 'filename');
82
+	}
83
+
84
+	/**
85
+	 * Set the filename of this attachment.
86
+	 *
87
+	 * @param string $filename
88
+	 *
89
+	 * @return $this
90
+	 */
91
+	public function setFilename($filename)
92
+	{
93
+		$this->setHeaderParameter('Content-Disposition', 'filename', $filename);
94
+		$this->setHeaderParameter('Content-Type', 'name', $filename);
95
+
96
+		return $this;
97
+	}
98
+
99
+	/**
100
+	 * Get the file size of this attachment.
101
+	 *
102
+	 * @return int
103
+	 */
104
+	public function getSize()
105
+	{
106
+		return $this->getHeaderParameter('Content-Disposition', 'size');
107
+	}
108
+
109
+	/**
110
+	 * Set the file size of this attachment.
111
+	 *
112
+	 * @param int $size
113
+	 *
114
+	 * @return $this
115
+	 */
116
+	public function setSize($size)
117
+	{
118
+		$this->setHeaderParameter('Content-Disposition', 'size', $size);
119
+
120
+		return $this;
121
+	}
122
+
123
+	/**
124
+	 * Set the file that this attachment is for.
125
+	 *
126
+	 * @param string $contentType optional
127
+	 *
128
+	 * @return $this
129
+	 */
130
+	public function setFile(Swift_FileStream $file, $contentType = null)
131
+	{
132
+		$this->setFilename(basename($file->getPath()));
133
+		$this->setBody($file, $contentType);
134
+		if (!isset($contentType)) {
135
+			$extension = strtolower(substr($file->getPath(), strrpos($file->getPath(), '.') + 1));
136
+
137
+			if (\array_key_exists($extension, $this->mimeTypes)) {
138
+				$this->setContentType($this->mimeTypes[$extension]);
139
+			}
140
+		}
141
+
142
+		return $this;
143
+	}
144 144
 }
Please login to merge, or discard this patch.
swiftmailer/lib/classes/Swift/Mime/ContentEncoder/RawContentEncoder.php 1 patch
Indentation   +40 added lines, -40 removed lines patch added patch discarded remove patch
@@ -19,47 +19,47 @@
 block discarded – undo
19 19
  */
20 20
 class Swift_Mime_ContentEncoder_RawContentEncoder implements Swift_Mime_ContentEncoder
21 21
 {
22
-    /**
23
-     * Encode a given string to produce an encoded string.
24
-     *
25
-     * @param string $string
26
-     * @param int    $firstLineOffset ignored
27
-     * @param int    $maxLineLength   ignored
28
-     *
29
-     * @return string
30
-     */
31
-    public function encodeString($string, $firstLineOffset = 0, $maxLineLength = 0)
32
-    {
33
-        return $string;
34
-    }
22
+	/**
23
+	 * Encode a given string to produce an encoded string.
24
+	 *
25
+	 * @param string $string
26
+	 * @param int    $firstLineOffset ignored
27
+	 * @param int    $maxLineLength   ignored
28
+	 *
29
+	 * @return string
30
+	 */
31
+	public function encodeString($string, $firstLineOffset = 0, $maxLineLength = 0)
32
+	{
33
+		return $string;
34
+	}
35 35
 
36
-    /**
37
-     * Encode stream $in to stream $out.
38
-     *
39
-     * @param int $firstLineOffset ignored
40
-     * @param int $maxLineLength   ignored
41
-     */
42
-    public function encodeByteStream(Swift_OutputByteStream $os, Swift_InputByteStream $is, $firstLineOffset = 0, $maxLineLength = 0)
43
-    {
44
-        while (false !== ($bytes = $os->read(8192))) {
45
-            $is->write($bytes);
46
-        }
47
-    }
36
+	/**
37
+	 * Encode stream $in to stream $out.
38
+	 *
39
+	 * @param int $firstLineOffset ignored
40
+	 * @param int $maxLineLength   ignored
41
+	 */
42
+	public function encodeByteStream(Swift_OutputByteStream $os, Swift_InputByteStream $is, $firstLineOffset = 0, $maxLineLength = 0)
43
+	{
44
+		while (false !== ($bytes = $os->read(8192))) {
45
+			$is->write($bytes);
46
+		}
47
+	}
48 48
 
49
-    /**
50
-     * Get the name of this encoding scheme.
51
-     *
52
-     * @return string
53
-     */
54
-    public function getName()
55
-    {
56
-        return 'raw';
57
-    }
49
+	/**
50
+	 * Get the name of this encoding scheme.
51
+	 *
52
+	 * @return string
53
+	 */
54
+	public function getName()
55
+	{
56
+		return 'raw';
57
+	}
58 58
 
59
-    /**
60
-     * Not used.
61
-     */
62
-    public function charsetChanged($charset)
63
-    {
64
-    }
59
+	/**
60
+	 * Not used.
61
+	 */
62
+	public function charsetChanged($charset)
63
+	{
64
+	}
65 65
 }
Please login to merge, or discard this patch.
swiftmailer/lib/classes/Swift/Mime/ContentEncoder/Base64ContentEncoder.php 1 patch
Indentation   +72 added lines, -72 removed lines patch added patch discarded remove patch
@@ -15,87 +15,87 @@
 block discarded – undo
15 15
  */
16 16
 class Swift_Mime_ContentEncoder_Base64ContentEncoder extends Swift_Encoder_Base64Encoder implements Swift_Mime_ContentEncoder
17 17
 {
18
-    /**
19
-     * Encode stream $in to stream $out.
20
-     *
21
-     * @param int $firstLineOffset
22
-     */
23
-    public function encodeByteStream(Swift_OutputByteStream $os, Swift_InputByteStream $is, $firstLineOffset = 0, $maxLineLength = 0)
24
-    {
25
-        if (0 >= $maxLineLength || 76 < $maxLineLength) {
26
-            $maxLineLength = 76;
27
-        }
18
+	/**
19
+	 * Encode stream $in to stream $out.
20
+	 *
21
+	 * @param int $firstLineOffset
22
+	 */
23
+	public function encodeByteStream(Swift_OutputByteStream $os, Swift_InputByteStream $is, $firstLineOffset = 0, $maxLineLength = 0)
24
+	{
25
+		if (0 >= $maxLineLength || 76 < $maxLineLength) {
26
+			$maxLineLength = 76;
27
+		}
28 28
 
29
-        $remainder = 0;
30
-        $base64ReadBufferRemainderBytes = '';
29
+		$remainder = 0;
30
+		$base64ReadBufferRemainderBytes = '';
31 31
 
32
-        // To reduce memory usage, the output buffer is streamed to the input buffer like so:
33
-        //   Output Stream => base64encode => wrap line length => Input Stream
34
-        // HOWEVER it's important to note that base64_encode() should only be passed whole triplets of data (except for the final chunk of data)
35
-        // otherwise it will assume the input data has *ended* and it will incorrectly pad/terminate the base64 data mid-stream.
36
-        // We use $base64ReadBufferRemainderBytes to carry over 1-2 "remainder" bytes from the each chunk from OutputStream and pre-pend those onto the
37
-        // chunk of bytes read in the next iteration.
38
-        // When the OutputStream is empty, we must flush any remainder bytes.
39
-        while (true) {
40
-            $readBytes = $os->read(8192);
41
-            $atEOF = (false === $readBytes);
32
+		// To reduce memory usage, the output buffer is streamed to the input buffer like so:
33
+		//   Output Stream => base64encode => wrap line length => Input Stream
34
+		// HOWEVER it's important to note that base64_encode() should only be passed whole triplets of data (except for the final chunk of data)
35
+		// otherwise it will assume the input data has *ended* and it will incorrectly pad/terminate the base64 data mid-stream.
36
+		// We use $base64ReadBufferRemainderBytes to carry over 1-2 "remainder" bytes from the each chunk from OutputStream and pre-pend those onto the
37
+		// chunk of bytes read in the next iteration.
38
+		// When the OutputStream is empty, we must flush any remainder bytes.
39
+		while (true) {
40
+			$readBytes = $os->read(8192);
41
+			$atEOF = (false === $readBytes);
42 42
 
43
-            if ($atEOF) {
44
-                $streamTheseBytes = $base64ReadBufferRemainderBytes;
45
-            } else {
46
-                $streamTheseBytes = $base64ReadBufferRemainderBytes.$readBytes;
47
-            }
48
-            $base64ReadBufferRemainderBytes = '';
49
-            $bytesLength = \strlen($streamTheseBytes);
43
+			if ($atEOF) {
44
+				$streamTheseBytes = $base64ReadBufferRemainderBytes;
45
+			} else {
46
+				$streamTheseBytes = $base64ReadBufferRemainderBytes.$readBytes;
47
+			}
48
+			$base64ReadBufferRemainderBytes = '';
49
+			$bytesLength = \strlen($streamTheseBytes);
50 50
 
51
-            if (0 === $bytesLength) { // no data left to encode
52
-                break;
53
-            }
51
+			if (0 === $bytesLength) { // no data left to encode
52
+				break;
53
+			}
54 54
 
55
-            // if we're not on the last block of the ouput stream, make sure $streamTheseBytes ends with a complete triplet of data
56
-            // and carry over remainder 1-2 bytes to the next loop iteration
57
-            if (!$atEOF) {
58
-                $excessBytes = $bytesLength % 3;
59
-                if (0 !== $excessBytes) {
60
-                    $base64ReadBufferRemainderBytes = substr($streamTheseBytes, -$excessBytes);
61
-                    $streamTheseBytes = substr($streamTheseBytes, 0, $bytesLength - $excessBytes);
62
-                }
63
-            }
55
+			// if we're not on the last block of the ouput stream, make sure $streamTheseBytes ends with a complete triplet of data
56
+			// and carry over remainder 1-2 bytes to the next loop iteration
57
+			if (!$atEOF) {
58
+				$excessBytes = $bytesLength % 3;
59
+				if (0 !== $excessBytes) {
60
+					$base64ReadBufferRemainderBytes = substr($streamTheseBytes, -$excessBytes);
61
+					$streamTheseBytes = substr($streamTheseBytes, 0, $bytesLength - $excessBytes);
62
+				}
63
+			}
64 64
 
65
-            $encoded = base64_encode($streamTheseBytes);
66
-            $encodedTransformed = '';
67
-            $thisMaxLineLength = $maxLineLength - $remainder - $firstLineOffset;
65
+			$encoded = base64_encode($streamTheseBytes);
66
+			$encodedTransformed = '';
67
+			$thisMaxLineLength = $maxLineLength - $remainder - $firstLineOffset;
68 68
 
69
-            while ($thisMaxLineLength < \strlen($encoded)) {
70
-                $encodedTransformed .= substr($encoded, 0, $thisMaxLineLength)."\r\n";
71
-                $firstLineOffset = 0;
72
-                $encoded = substr($encoded, $thisMaxLineLength);
73
-                $thisMaxLineLength = $maxLineLength;
74
-                $remainder = 0;
75
-            }
69
+			while ($thisMaxLineLength < \strlen($encoded)) {
70
+				$encodedTransformed .= substr($encoded, 0, $thisMaxLineLength)."\r\n";
71
+				$firstLineOffset = 0;
72
+				$encoded = substr($encoded, $thisMaxLineLength);
73
+				$thisMaxLineLength = $maxLineLength;
74
+				$remainder = 0;
75
+			}
76 76
 
77
-            if (0 < $remainingLength = \strlen($encoded)) {
78
-                $remainder += $remainingLength;
79
-                $encodedTransformed .= $encoded;
80
-                $encoded = null;
81
-            }
77
+			if (0 < $remainingLength = \strlen($encoded)) {
78
+				$remainder += $remainingLength;
79
+				$encodedTransformed .= $encoded;
80
+				$encoded = null;
81
+			}
82 82
 
83
-            $is->write($encodedTransformed);
83
+			$is->write($encodedTransformed);
84 84
 
85
-            if ($atEOF) {
86
-                break;
87
-            }
88
-        }
89
-    }
85
+			if ($atEOF) {
86
+				break;
87
+			}
88
+		}
89
+	}
90 90
 
91
-    /**
92
-     * Get the name of this encoding scheme.
93
-     * Returns the string 'base64'.
94
-     *
95
-     * @return string
96
-     */
97
-    public function getName()
98
-    {
99
-        return 'base64';
100
-    }
91
+	/**
92
+	 * Get the name of this encoding scheme.
93
+	 * Returns the string 'base64'.
94
+	 *
95
+	 * @return string
96
+	 */
97
+	public function getName()
98
+	{
99
+		return 'base64';
100
+	}
101 101
 }
Please login to merge, or discard this patch.
swiftmailer/lib/classes/Swift/Mime/ContentEncoder/PlainContentEncoder.php 1 patch
Indentation   +142 added lines, -142 removed lines patch added patch discarded remove patch
@@ -19,146 +19,146 @@
 block discarded – undo
19 19
  */
20 20
 class Swift_Mime_ContentEncoder_PlainContentEncoder implements Swift_Mime_ContentEncoder
21 21
 {
22
-    /**
23
-     * The name of this encoding scheme (probably 7bit or 8bit).
24
-     *
25
-     * @var string
26
-     */
27
-    private $name;
28
-
29
-    /**
30
-     * True if canonical transformations should be done.
31
-     *
32
-     * @var bool
33
-     */
34
-    private $canonical;
35
-
36
-    /**
37
-     * Creates a new PlainContentEncoder with $name (probably 7bit or 8bit).
38
-     *
39
-     * @param string $name
40
-     * @param bool   $canonical if canonicalization transformation should be done
41
-     */
42
-    public function __construct($name, $canonical = false)
43
-    {
44
-        $this->name = $name;
45
-        $this->canonical = $canonical;
46
-    }
47
-
48
-    /**
49
-     * Encode a given string to produce an encoded string.
50
-     *
51
-     * @param string $string
52
-     * @param int    $firstLineOffset ignored
53
-     * @param int    $maxLineLength   - 0 means no wrapping will occur
54
-     *
55
-     * @return string
56
-     */
57
-    public function encodeString($string, $firstLineOffset = 0, $maxLineLength = 0)
58
-    {
59
-        if ($this->canonical) {
60
-            $string = $this->canonicalize($string);
61
-        }
62
-
63
-        return $this->safeWordwrap($string, $maxLineLength, "\r\n");
64
-    }
65
-
66
-    /**
67
-     * Encode stream $in to stream $out.
68
-     *
69
-     * @param int $firstLineOffset ignored
70
-     * @param int $maxLineLength   optional, 0 means no wrapping will occur
71
-     */
72
-    public function encodeByteStream(Swift_OutputByteStream $os, Swift_InputByteStream $is, $firstLineOffset = 0, $maxLineLength = 0)
73
-    {
74
-        $leftOver = '';
75
-        while (false !== $bytes = $os->read(8192)) {
76
-            $toencode = $leftOver.$bytes;
77
-            if ($this->canonical) {
78
-                $toencode = $this->canonicalize($toencode);
79
-            }
80
-            $wrapped = $this->safeWordwrap($toencode, $maxLineLength, "\r\n");
81
-            $lastLinePos = strrpos($wrapped, "\r\n");
82
-            $leftOver = substr($wrapped, $lastLinePos);
83
-            $wrapped = substr($wrapped, 0, $lastLinePos);
84
-
85
-            $is->write($wrapped);
86
-        }
87
-        if (\strlen($leftOver)) {
88
-            $is->write($leftOver);
89
-        }
90
-    }
91
-
92
-    /**
93
-     * Get the name of this encoding scheme.
94
-     *
95
-     * @return string
96
-     */
97
-    public function getName()
98
-    {
99
-        return $this->name;
100
-    }
101
-
102
-    /**
103
-     * Not used.
104
-     */
105
-    public function charsetChanged($charset)
106
-    {
107
-    }
108
-
109
-    /**
110
-     * A safer (but weaker) wordwrap for unicode.
111
-     *
112
-     * @param string $string
113
-     * @param int    $length
114
-     * @param string $le
115
-     *
116
-     * @return string
117
-     */
118
-    private function safeWordwrap($string, $length = 75, $le = "\r\n")
119
-    {
120
-        if (0 >= $length) {
121
-            return $string;
122
-        }
123
-
124
-        $originalLines = explode($le, $string);
125
-
126
-        $lines = [];
127
-        $lineCount = 0;
128
-
129
-        foreach ($originalLines as $originalLine) {
130
-            $lines[] = '';
131
-            $currentLine = &$lines[$lineCount++];
132
-
133
-            //$chunks = preg_split('/(?<=[\ \t,\.!\?\-&\+\/])/', $originalLine);
134
-            $chunks = preg_split('/(?<=\s)/', $originalLine);
135
-
136
-            foreach ($chunks as $chunk) {
137
-                if (0 != \strlen($currentLine)
138
-                    && \strlen($currentLine.$chunk) > $length) {
139
-                    $lines[] = '';
140
-                    $currentLine = &$lines[$lineCount++];
141
-                }
142
-                $currentLine .= $chunk;
143
-            }
144
-        }
145
-
146
-        return implode("\r\n", $lines);
147
-    }
148
-
149
-    /**
150
-     * Canonicalize string input (fix CRLF).
151
-     *
152
-     * @param string $string
153
-     *
154
-     * @return string
155
-     */
156
-    private function canonicalize($string)
157
-    {
158
-        return str_replace(
159
-            ["\r\n", "\r", "\n"],
160
-            ["\n", "\n", "\r\n"],
161
-            $string
162
-            );
163
-    }
22
+	/**
23
+	 * The name of this encoding scheme (probably 7bit or 8bit).
24
+	 *
25
+	 * @var string
26
+	 */
27
+	private $name;
28
+
29
+	/**
30
+	 * True if canonical transformations should be done.
31
+	 *
32
+	 * @var bool
33
+	 */
34
+	private $canonical;
35
+
36
+	/**
37
+	 * Creates a new PlainContentEncoder with $name (probably 7bit or 8bit).
38
+	 *
39
+	 * @param string $name
40
+	 * @param bool   $canonical if canonicalization transformation should be done
41
+	 */
42
+	public function __construct($name, $canonical = false)
43
+	{
44
+		$this->name = $name;
45
+		$this->canonical = $canonical;
46
+	}
47
+
48
+	/**
49
+	 * Encode a given string to produce an encoded string.
50
+	 *
51
+	 * @param string $string
52
+	 * @param int    $firstLineOffset ignored
53
+	 * @param int    $maxLineLength   - 0 means no wrapping will occur
54
+	 *
55
+	 * @return string
56
+	 */
57
+	public function encodeString($string, $firstLineOffset = 0, $maxLineLength = 0)
58
+	{
59
+		if ($this->canonical) {
60
+			$string = $this->canonicalize($string);
61
+		}
62
+
63
+		return $this->safeWordwrap($string, $maxLineLength, "\r\n");
64
+	}
65
+
66
+	/**
67
+	 * Encode stream $in to stream $out.
68
+	 *
69
+	 * @param int $firstLineOffset ignored
70
+	 * @param int $maxLineLength   optional, 0 means no wrapping will occur
71
+	 */
72
+	public function encodeByteStream(Swift_OutputByteStream $os, Swift_InputByteStream $is, $firstLineOffset = 0, $maxLineLength = 0)
73
+	{
74
+		$leftOver = '';
75
+		while (false !== $bytes = $os->read(8192)) {
76
+			$toencode = $leftOver.$bytes;
77
+			if ($this->canonical) {
78
+				$toencode = $this->canonicalize($toencode);
79
+			}
80
+			$wrapped = $this->safeWordwrap($toencode, $maxLineLength, "\r\n");
81
+			$lastLinePos = strrpos($wrapped, "\r\n");
82
+			$leftOver = substr($wrapped, $lastLinePos);
83
+			$wrapped = substr($wrapped, 0, $lastLinePos);
84
+
85
+			$is->write($wrapped);
86
+		}
87
+		if (\strlen($leftOver)) {
88
+			$is->write($leftOver);
89
+		}
90
+	}
91
+
92
+	/**
93
+	 * Get the name of this encoding scheme.
94
+	 *
95
+	 * @return string
96
+	 */
97
+	public function getName()
98
+	{
99
+		return $this->name;
100
+	}
101
+
102
+	/**
103
+	 * Not used.
104
+	 */
105
+	public function charsetChanged($charset)
106
+	{
107
+	}
108
+
109
+	/**
110
+	 * A safer (but weaker) wordwrap for unicode.
111
+	 *
112
+	 * @param string $string
113
+	 * @param int    $length
114
+	 * @param string $le
115
+	 *
116
+	 * @return string
117
+	 */
118
+	private function safeWordwrap($string, $length = 75, $le = "\r\n")
119
+	{
120
+		if (0 >= $length) {
121
+			return $string;
122
+		}
123
+
124
+		$originalLines = explode($le, $string);
125
+
126
+		$lines = [];
127
+		$lineCount = 0;
128
+
129
+		foreach ($originalLines as $originalLine) {
130
+			$lines[] = '';
131
+			$currentLine = &$lines[$lineCount++];
132
+
133
+			//$chunks = preg_split('/(?<=[\ \t,\.!\?\-&\+\/])/', $originalLine);
134
+			$chunks = preg_split('/(?<=\s)/', $originalLine);
135
+
136
+			foreach ($chunks as $chunk) {
137
+				if (0 != \strlen($currentLine)
138
+					&& \strlen($currentLine.$chunk) > $length) {
139
+					$lines[] = '';
140
+					$currentLine = &$lines[$lineCount++];
141
+				}
142
+				$currentLine .= $chunk;
143
+			}
144
+		}
145
+
146
+		return implode("\r\n", $lines);
147
+	}
148
+
149
+	/**
150
+	 * Canonicalize string input (fix CRLF).
151
+	 *
152
+	 * @param string $string
153
+	 *
154
+	 * @return string
155
+	 */
156
+	private function canonicalize($string)
157
+	{
158
+		return str_replace(
159
+			["\r\n", "\r", "\n"],
160
+			["\n", "\n", "\r\n"],
161
+			$string
162
+			);
163
+	}
164 164
 }
Please login to merge, or discard this patch.
swiftmailer/lib/classes/Swift/Mime/ContentEncoder/QpContentEncoder.php 1 patch
Indentation   +116 added lines, -116 removed lines patch added patch discarded remove patch
@@ -15,120 +15,120 @@
 block discarded – undo
15 15
  */
16 16
 class Swift_Mime_ContentEncoder_QpContentEncoder extends Swift_Encoder_QpEncoder implements Swift_Mime_ContentEncoder
17 17
 {
18
-    protected $dotEscape;
19
-
20
-    /**
21
-     * Creates a new QpContentEncoder for the given CharacterStream.
22
-     *
23
-     * @param Swift_CharacterStream $charStream to use for reading characters
24
-     * @param Swift_StreamFilter    $filter     if canonicalization should occur
25
-     * @param bool                  $dotEscape  if dot stuffing workaround must be enabled
26
-     */
27
-    public function __construct(Swift_CharacterStream $charStream, Swift_StreamFilter $filter = null, $dotEscape = false)
28
-    {
29
-        $this->dotEscape = $dotEscape;
30
-        parent::__construct($charStream, $filter);
31
-    }
32
-
33
-    public function __sleep()
34
-    {
35
-        return ['charStream', 'filter', 'dotEscape'];
36
-    }
37
-
38
-    protected function getSafeMapShareId()
39
-    {
40
-        return static::class.($this->dotEscape ? '.dotEscape' : '');
41
-    }
42
-
43
-    protected function initSafeMap()
44
-    {
45
-        parent::initSafeMap();
46
-        if ($this->dotEscape) {
47
-            /* Encode . as =2e for buggy remote servers */
48
-            unset($this->safeMap[0x2e]);
49
-        }
50
-    }
51
-
52
-    /**
53
-     * Encode stream $in to stream $out.
54
-     *
55
-     * QP encoded strings have a maximum line length of 76 characters.
56
-     * If the first line needs to be shorter, indicate the difference with
57
-     * $firstLineOffset.
58
-     *
59
-     * @param Swift_OutputByteStream $os              output stream
60
-     * @param Swift_InputByteStream  $is              input stream
61
-     * @param int                    $firstLineOffset
62
-     * @param int                    $maxLineLength
63
-     */
64
-    public function encodeByteStream(Swift_OutputByteStream $os, Swift_InputByteStream $is, $firstLineOffset = 0, $maxLineLength = 0)
65
-    {
66
-        if ($maxLineLength > 76 || $maxLineLength <= 0) {
67
-            $maxLineLength = 76;
68
-        }
69
-
70
-        $thisLineLength = $maxLineLength - $firstLineOffset;
71
-
72
-        $this->charStream->flushContents();
73
-        $this->charStream->importByteStream($os);
74
-
75
-        $currentLine = '';
76
-        $prepend = '';
77
-        $size = $lineLen = 0;
78
-
79
-        while (false !== $bytes = $this->nextSequence()) {
80
-            // If we're filtering the input
81
-            if (isset($this->filter)) {
82
-                // If we can't filter because we need more bytes
83
-                while ($this->filter->shouldBuffer($bytes)) {
84
-                    // Then collect bytes into the buffer
85
-                    if (false === $moreBytes = $this->nextSequence(1)) {
86
-                        break;
87
-                    }
88
-
89
-                    foreach ($moreBytes as $b) {
90
-                        $bytes[] = $b;
91
-                    }
92
-                }
93
-                // And filter them
94
-                $bytes = $this->filter->filter($bytes);
95
-            }
96
-
97
-            $enc = $this->encodeByteSequence($bytes, $size);
98
-
99
-            $i = strpos($enc, '=0D=0A');
100
-            $newLineLength = $lineLen + (false === $i ? $size : $i);
101
-
102
-            if ($currentLine && $newLineLength >= $thisLineLength) {
103
-                $is->write($prepend.$this->standardize($currentLine));
104
-                $currentLine = '';
105
-                $prepend = "=\r\n";
106
-                $thisLineLength = $maxLineLength;
107
-                $lineLen = 0;
108
-            }
109
-
110
-            $currentLine .= $enc;
111
-
112
-            if (false === $i) {
113
-                $lineLen += $size;
114
-            } else {
115
-                // 6 is the length of '=0D=0A'.
116
-                $lineLen = $size - strrpos($enc, '=0D=0A') - 6;
117
-            }
118
-        }
119
-        if (\strlen($currentLine)) {
120
-            $is->write($prepend.$this->standardize($currentLine));
121
-        }
122
-    }
123
-
124
-    /**
125
-     * Get the name of this encoding scheme.
126
-     * Returns the string 'quoted-printable'.
127
-     *
128
-     * @return string
129
-     */
130
-    public function getName()
131
-    {
132
-        return 'quoted-printable';
133
-    }
18
+	protected $dotEscape;
19
+
20
+	/**
21
+	 * Creates a new QpContentEncoder for the given CharacterStream.
22
+	 *
23
+	 * @param Swift_CharacterStream $charStream to use for reading characters
24
+	 * @param Swift_StreamFilter    $filter     if canonicalization should occur
25
+	 * @param bool                  $dotEscape  if dot stuffing workaround must be enabled
26
+	 */
27
+	public function __construct(Swift_CharacterStream $charStream, Swift_StreamFilter $filter = null, $dotEscape = false)
28
+	{
29
+		$this->dotEscape = $dotEscape;
30
+		parent::__construct($charStream, $filter);
31
+	}
32
+
33
+	public function __sleep()
34
+	{
35
+		return ['charStream', 'filter', 'dotEscape'];
36
+	}
37
+
38
+	protected function getSafeMapShareId()
39
+	{
40
+		return static::class.($this->dotEscape ? '.dotEscape' : '');
41
+	}
42
+
43
+	protected function initSafeMap()
44
+	{
45
+		parent::initSafeMap();
46
+		if ($this->dotEscape) {
47
+			/* Encode . as =2e for buggy remote servers */
48
+			unset($this->safeMap[0x2e]);
49
+		}
50
+	}
51
+
52
+	/**
53
+	 * Encode stream $in to stream $out.
54
+	 *
55
+	 * QP encoded strings have a maximum line length of 76 characters.
56
+	 * If the first line needs to be shorter, indicate the difference with
57
+	 * $firstLineOffset.
58
+	 *
59
+	 * @param Swift_OutputByteStream $os              output stream
60
+	 * @param Swift_InputByteStream  $is              input stream
61
+	 * @param int                    $firstLineOffset
62
+	 * @param int                    $maxLineLength
63
+	 */
64
+	public function encodeByteStream(Swift_OutputByteStream $os, Swift_InputByteStream $is, $firstLineOffset = 0, $maxLineLength = 0)
65
+	{
66
+		if ($maxLineLength > 76 || $maxLineLength <= 0) {
67
+			$maxLineLength = 76;
68
+		}
69
+
70
+		$thisLineLength = $maxLineLength - $firstLineOffset;
71
+
72
+		$this->charStream->flushContents();
73
+		$this->charStream->importByteStream($os);
74
+
75
+		$currentLine = '';
76
+		$prepend = '';
77
+		$size = $lineLen = 0;
78
+
79
+		while (false !== $bytes = $this->nextSequence()) {
80
+			// If we're filtering the input
81
+			if (isset($this->filter)) {
82
+				// If we can't filter because we need more bytes
83
+				while ($this->filter->shouldBuffer($bytes)) {
84
+					// Then collect bytes into the buffer
85
+					if (false === $moreBytes = $this->nextSequence(1)) {
86
+						break;
87
+					}
88
+
89
+					foreach ($moreBytes as $b) {
90
+						$bytes[] = $b;
91
+					}
92
+				}
93
+				// And filter them
94
+				$bytes = $this->filter->filter($bytes);
95
+			}
96
+
97
+			$enc = $this->encodeByteSequence($bytes, $size);
98
+
99
+			$i = strpos($enc, '=0D=0A');
100
+			$newLineLength = $lineLen + (false === $i ? $size : $i);
101
+
102
+			if ($currentLine && $newLineLength >= $thisLineLength) {
103
+				$is->write($prepend.$this->standardize($currentLine));
104
+				$currentLine = '';
105
+				$prepend = "=\r\n";
106
+				$thisLineLength = $maxLineLength;
107
+				$lineLen = 0;
108
+			}
109
+
110
+			$currentLine .= $enc;
111
+
112
+			if (false === $i) {
113
+				$lineLen += $size;
114
+			} else {
115
+				// 6 is the length of '=0D=0A'.
116
+				$lineLen = $size - strrpos($enc, '=0D=0A') - 6;
117
+			}
118
+		}
119
+		if (\strlen($currentLine)) {
120
+			$is->write($prepend.$this->standardize($currentLine));
121
+		}
122
+	}
123
+
124
+	/**
125
+	 * Get the name of this encoding scheme.
126
+	 * Returns the string 'quoted-printable'.
127
+	 *
128
+	 * @return string
129
+	 */
130
+	public function getName()
131
+	{
132
+		return 'quoted-printable';
133
+	}
134 134
 }
Please login to merge, or discard this patch.