Typo3   F
last analyzed

Complexity

Total Complexity 61

Size/Duplication

Total Lines 360
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 106
dl 0
loc 360
rs 3.52
c 0
b 0
f 0
wmc 61

16 Methods

Rating   Name   Duplication   Size   Complexity  
A from() 0 14 4
A object() 0 3 1
A subject() 0 14 4
B embed() 0 25 7
B attach() 0 25 7
A send() 0 4 1
A header() 0 14 4
A bcc() 0 17 5
A to() 0 14 4
A sender() 0 14 4
A __clone() 0 3 1
A text() 0 14 5
A cc() 0 14 4
A __construct() 0 4 1
A html() 0 14 5
A replyTo() 0 14 4

How to fix   Complexity   

Complex Class

Complex classes like Typo3 often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Typo3, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Metaways Infosystems GmbH, 2013
6
 * @copyright Aimeos (aimeos.org), 2014-2025
7
 * @package Base
8
 * @subpackage Mail
9
 */
10
11
12
namespace Aimeos\Base\Mail\Message;
13
14
15
/**
16
 * TYPO3 implementation for creating e-mails.
17
 *
18
 * @package Base
19
 * @subpackage Mail
20
 */
21
class Typo3 implements \Aimeos\Base\Mail\Message\Iface
22
{
23
	private \TYPO3\CMS\Core\Mail\MailMessage $object;
24
	private string $charset;
25
26
27
	/**
28
	 * Initializes the message instance.
29
	 *
30
	 * @param \TYPO3\CMS\Core\Mail\MailMessage $object TYPO3 mail object
31
	 * @param string $charset Default charset of the message
32
	 */
33
	public function __construct( \TYPO3\CMS\Core\Mail\MailMessage $object, string $charset )
34
	{
35
		$this->charset = $charset;
36
		$this->object = $object;
37
	}
38
39
40
	/**
41
	 * Adds a source e-mail address of the message.
42
	 *
43
	 * @param string $email Source e-mail address
44
	 * @param string|null $name Name of the user sending the e-mail or null for no name
45
	 * @return \Aimeos\Base\Mail\Message\Iface Message object
46
	 */
47
	public function from( string $email, ?string $name = null ) : Iface
48
	{
49
		if( $email )
50
		{
51
			$class = '\Symfony\Component\Mime\Email';
52
53
			if( class_exists( $class ) && $this->object instanceof $class ) {
54
				$this->object->addFrom( new \Symfony\Component\Mime\Address( $email, (string) $name ) );
55
			} else {
56
				$this->object->addFrom( $email, $name );
57
			}
58
		}
59
60
		return $this;
61
	}
62
63
64
	/**
65
	 * Adds a destination e-mail address of the target user mailbox.
66
	 *
67
	 * @param string $email Destination address of the target mailbox
68
	 * @param string|null $name Name of the user owning the target mailbox or null for no name
69
	 * @return \Aimeos\Base\Mail\Message\Iface Message object
70
	 */
71
	public function to( string $email, ?string $name = null ) : Iface
72
	{
73
		if( $email )
74
		{
75
			$class = '\Symfony\Component\Mime\Email';
76
77
			if( class_exists( $class ) && $this->object instanceof $class ) {
78
				$this->object->addTo( new \Symfony\Component\Mime\Address( $email, (string) $name ) );
79
			} else {
80
				$this->object->addTo( $email, $name );
81
			}
82
		}
83
84
		return $this;
85
	}
86
87
88
	/**
89
	 * Adds a destination e-mail address for a copy of the message.
90
	 *
91
	 * @param string $email Destination address for a copy
92
	 * @param string|null $name Name of the user owning the target mailbox or null for no name
93
	 * @return \Aimeos\Base\Mail\Message\Iface Message object
94
	 */
95
	public function cc( string $email, ?string $name = null ) : Iface
96
	{
97
		if( $email )
98
		{
99
			$class = '\Symfony\Component\Mime\Email';
100
101
			if( class_exists( $class ) && $this->object instanceof $class ) {
102
				$this->object->addCc( new \Symfony\Component\Mime\Address( $email, (string) $name ) );
103
			} else {
104
				$this->object->addCc( $email, $name );
105
			}
106
		}
107
108
		return $this;
109
	}
110
111
112
	/**
113
	 * Adds a destination e-mail address for a hidden copy of the message.
114
	 *
115
	 * @param array|string $email Destination address for a hidden copy
116
	 * @return \Aimeos\Base\Mail\Message\Iface Message object
117
	 */
118
	public function bcc( $email ) : Iface
119
	{
120
		if( !empty( $email ) )
121
		{
122
			$class = '\Symfony\Component\Mime\Email';
123
124
			foreach( (array) $email as $addr )
125
			{
126
				if( class_exists( $class ) && $this->object instanceof $class ) {
127
					$this->object->addBcc( new \Symfony\Component\Mime\Address( $addr ) );
128
				} else {
129
					$this->object->addBcc( $addr );
130
				}
131
			}
132
		}
133
134
		return $this;
135
	}
136
137
138
	/**
139
	 * Adds the return e-mail address for the message.
140
	 *
141
	 * @param string $email E-mail address which should receive all replies
142
	 * @param string|null $name Name of the user which should receive all replies or null for no name
143
	 * @return \Aimeos\Base\Mail\Message\Iface Message object
144
	 */
145
	public function replyTo( string $email, ?string $name = null ) : Iface
146
	{
147
		if( $email )
148
		{
149
			$class = '\Symfony\Component\Mime\Email';
150
151
			if( class_exists( $class ) && $this->object instanceof $class ) {
152
				$this->object->addReplyTo( new \Symfony\Component\Mime\Address( $email, (string) $name ) );
153
			} else {
154
				$this->object->addReplyTo( $email, $name );
155
			}
156
		}
157
158
		return $this;
159
	}
160
161
162
	/**
163
	 * Adds a custom header to the message.
164
	 *
165
	 * @param string $name Name of the custom e-mail header
166
	 * @param string $value Text content of the custom e-mail header
167
	 * @return \Aimeos\Base\Mail\Message\Iface Message object
168
	 */
169
	public function header( string $name, string $value ) : Iface
170
	{
171
		if( $name )
172
		{
173
			$class = '\Symfony\Component\Mime\Email';
174
175
			if( class_exists( $class ) && $this->object instanceof $class ) {
176
				$this->object->getHeaders()->add( new \Symfony\Component\Mime\Header\UnstructuredHeader( $name, $value ) );
177
			} else {
178
				$this->object->getHeaders()->addTextHeader( $name, $value );
179
			}
180
		}
181
182
		return $this;
183
	}
184
185
186
	/**
187
	 * Sends the e-mail message to the mail server.
188
	 *
189
	 * @return \Aimeos\Base\Mail\Message\Iface Message object
190
	 */
191
	public function send() : Iface
192
	{
193
		$this->object->send();
194
		return $this;
195
	}
196
197
198
	/**
199
	 * Sets the e-mail address and name of the sender of the message (higher precedence than "From").
200
	 *
201
	 * @param string $email Source e-mail address
202
	 * @param string|null $name Name of the user who sent the message or null for no name
203
	 * @return \Aimeos\Base\Mail\Message\Iface Message object
204
	 */
205
	public function sender( string $email, ?string $name = null ) : Iface
206
	{
207
		if( $email )
208
		{
209
			$class = '\Symfony\Component\Mime\Email';
210
211
			if( class_exists( $class ) && $this->object instanceof $class ) {
212
				$this->object->setSender( new \Symfony\Component\Mime\Address( $email, (string) $name ) );
0 ignored issues
show
Bug introduced by
new Symfony\Component\Mi...($email, (string)$name) of type Symfony\Component\Mime\Address is incompatible with the type string expected by parameter $address of TYPO3\CMS\Core\Mail\MailMessage::setSender(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

212
				$this->object->setSender( /** @scrutinizer ignore-type */ new \Symfony\Component\Mime\Address( $email, (string) $name ) );
Loading history...
213
			} else {
214
				$this->object->setSender( $email, $name );
215
			}
216
		}
217
218
		return $this;
219
	}
220
221
222
	/**
223
	 * Sets the subject of the message.
224
	 *
225
	 * @param string $subject Subject of the message
226
	 * @return \Aimeos\Base\Mail\Message\Iface Message object
227
	 */
228
	public function subject( string $subject ) : Iface
229
	{
230
		if( $subject )
231
		{
232
			$class = '\Symfony\Component\Mime\Email';
233
234
			if( class_exists( $class ) && $this->object instanceof $class ) {
235
				$this->object->setSubject( $subject );
236
			} else {
237
				$this->object->setSubject( $subject );
238
			}
239
		}
240
241
		return $this;
242
	}
243
244
245
	/**
246
	 * Sets the text body of the message.
247
	 *
248
	 * @param string $message Text body of the message
249
	 * @return \Aimeos\Base\Mail\Message\Iface Message object
250
	 */
251
	public function text( string $message ) : Iface
252
	{
253
		if( $message )
254
		{
255
			$class = '\Symfony\Component\Mime\Email';
256
257
			if( class_exists( $class ) && $this->object instanceof $class ) {
258
				$this->object->text( $message, $this->charset );
259
			} elseif( class_exists( '\Swift_Mailer' ) ) {
260
				$this->object->setBody( $message );
0 ignored issues
show
Bug introduced by
$message of type string is incompatible with the type Symfony\Component\Mime\Part\AbstractPart|null expected by parameter $body of Symfony\Component\Mime\Message::setBody(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

260
				$this->object->setBody( /** @scrutinizer ignore-type */ $message );
Loading history...
261
			}
262
		}
263
264
		return $this;
265
	}
266
267
268
	/**
269
	 * Sets the HTML body of the message.
270
	 *
271
	 * @param string $message HTML body of the message
272
	 * @return \Aimeos\Base\Mail\Message\Iface Message object
273
	 */
274
	public function html( string $message ) : Iface
275
	{
276
		if( $message )
277
		{
278
			$class = '\Symfony\Component\Mime\Email';
279
280
			if( class_exists( $class ) && $this->object instanceof $class ) {
281
				$this->object->html( $message, $this->charset );
282
			} elseif( class_exists( '\Swift_Mailer' ) ) {
283
				$this->object->addPart( $message, 'text/html' );
0 ignored issues
show
Unused Code introduced by
The call to Symfony\Component\Mime\Email::addPart() has too many arguments starting with 'text/html'. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

283
				$this->object->/** @scrutinizer ignore-call */ 
284
                   addPart( $message, 'text/html' );

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
Bug introduced by
$message of type string is incompatible with the type Symfony\Component\Mime\Part\DataPart expected by parameter $part of Symfony\Component\Mime\Email::addPart(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

283
				$this->object->addPart( /** @scrutinizer ignore-type */ $message, 'text/html' );
Loading history...
284
			}
285
		}
286
287
		return $this;
288
	}
289
290
291
	/**
292
	 * Adds an attachment to the message.
293
	 *
294
	 * @param string|null $data Binary or string @author nose
295
	 * @param string|null $filename Name of the attached file (or null if inline disposition is used)
296
	 * @param string|null $mimetype Mime type of the attachment (e.g. "text/plain", "application/octet-stream", etc.)
297
	 * @param string $disposition Type of the disposition ("attachment" or "inline")
298
	 * @return \Aimeos\Base\Mail\Message\Iface Message object
299
	 */
300
	public function attach( ?string $data, ?string $filename = null, ?string $mimetype = null, string $disposition = 'attachment' ) : Iface
301
	{
302
		if( $data )
303
		{
304
			$class = '\Symfony\Component\Mime\Email';
305
			$mimetype = $mimetype ?: (new \finfo( FILEINFO_MIME_TYPE ))->buffer( $data );
306
			$filename = $filename ?: md5( $data );
307
308
			if( class_exists( $class ) && $this->object instanceof $class )
309
			{
310
				$this->object->attach( $data, $filename, $mimetype );
311
			}
312
			elseif( class_exists( '\Swift_Attachment' ) )
313
			{
314
				$part = \Swift_Attachment::newInstance( $data, $filename, $mimetype );
0 ignored issues
show
Bug introduced by
The type Swift_Attachment was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
315
				$part->setDisposition( $disposition );
316
				$this->object->attach( $part );
317
			}
318
			else
319
			{
320
				throw new \RuntimeException( 'Symfony mailer or Swiftmailer package missing' );
321
			}
322
		}
323
324
		return $this;
325
	}
326
327
328
	/**
329
	 * Embeds an attachment into the message and returns its reference.
330
	 *
331
	 * @param string|null $data Binary or string
332
	 * @param string|null $filename Name of the attached file
333
	 * @param string|null $mimetype Mime type of the attachment (e.g. "text/plain", "application/octet-stream", etc.)
334
	 * @return string Content ID for referencing the attachment in the HTML body
335
	 */
336
	public function embed( ?string $data, ?string $filename = null, ?string $mimetype = null ) : string
337
	{
338
		if( $data )
339
		{
340
			$class = '\Symfony\Component\Mime\Email';
341
			$mimetype = $mimetype ?: (new \finfo( FILEINFO_MIME_TYPE ))->buffer( $data );
342
			$filename = $filename ?: md5( $data );
343
344
			if( class_exists( $class ) && $this->object instanceof $class )
345
			{
346
				$this->object->embed( $data, $filename, $mimetype );
347
				return 'cid:' . $filename;
348
			}
349
			elseif( class_exists( '\Swift_EmbeddedFile' ) )
350
			{
351
				$part = \Swift_EmbeddedFile::newInstance( $data, $filename, $mimetype );
0 ignored issues
show
Bug introduced by
The type Swift_EmbeddedFile was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
352
				return $this->object->embed( $part );
353
			}
354
			else
355
			{
356
				throw new \RuntimeException( 'Symfony mailer or Swiftmailer package missing' );
357
			}
358
		}
359
360
		return '';
361
	}
362
363
364
	/**
365
	 * Returns the internal TYPO3 mail message object.
366
	 *
367
	 * @return \TYPO3\CMS\Core\Mail\MailMessage TYPO3 mail message object
368
	 */
369
	public function object() : \TYPO3\CMS\Core\Mail\MailMessage
370
	{
371
		return $this->object;
372
	}
373
374
375
	/**
376
	 * Clones the internal objects.
377
	 */
378
	public function __clone()
379
	{
380
		$this->object = clone $this->object;
381
	}
382
}
383