AbstractMail::__construct()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 27
rs 9.488
c 0
b 0
f 0
cc 2
nc 2
nop 8

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * @copyright   Copyright (c) 2015 ublaboo <[email protected]>
7
 * @author      Pavel Janda <[email protected]>
8
 * @package     Ublaboo
9
 */
10
11
namespace Ublaboo\Mailing;
12
13
use Latte\Engine;
14
use Nette\Application\LinkGenerator;
15
use Nette\Application\UI\ITemplate;
16
use Nette\Application\UI\ITemplateFactory;
17
use Nette\Bridges\ApplicationLatte\Template;
18
use Nette\Mail\IMailer;
19
use Nette\Mail\Message;
20
use Ublaboo\Mailing\DI\MailingExtension;
21
22
abstract class AbstractMail
23
{
24
25
	/**
26
	 * @var array
27
	 */
28
	protected $mailAddresses;
29
30
	/**
31
	 * @var IMailer
32
	 */
33
	protected $mailer;
34
35
	/**
36
	 * @var Message
37
	 */
38
	protected $message;
39
40
	/**
41
	 * @var LinkGenerator
42
	 */
43
	protected $linkGenerator;
44
45
	/**
46
	 * @var ILogger
47
	 */
48
	protected $logger;
49
50
	/**
51
	 * @var ITemplate
52
	 */
53
	protected $template;
54
55
	/**
56
	 * @var string
57
	 */
58
	protected $mailImagesBasePath;
59
60
	/**
61
	 * @var string
62
	 */
63
	private $config;
64
65
	/**
66
	 * @var IMessageData|null
67
	 */
68
	private $mailData;
69
70
71
	public function __construct(
72
		string $config,
73
		array $mailAddresses,
74
		IMailer $mailer,
75
		Message $message,
76
		LinkGenerator $linkGenerator,
77
		ITemplateFactory $templateFactory,
78
		ILogger $logger,
79
		?IMessageData $mailData
80
	) {
81
		$this->config = $config;
82
		$this->mailAddresses = $mailAddresses;
83
		$this->mailer = $mailer;
84
		$this->message = $message;
85
		$this->linkGenerator = $linkGenerator;
86
		$this->logger = $logger;
87
		$this->mailData = $mailData;
88
89
		$this->template = $templateFactory->createTemplate();
90
91
		/**
92
		 * Initiate mail composing
93
		 */
94
		if ($this instanceof IComposableMail) {
95
			$this->compose($this->message, $this->mailData);
0 ignored issues
show
Bug introduced by Pavel Janda
The method compose() does not seem to exist on object<Ublaboo\Mailing\AbstractMail>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
96
		}
97
	}
98
99
100
	public function setBasePath(string $mailImagesBasePath): void
101
	{
102
		$this->mailImagesBasePath = $mailImagesBasePath;
103
	}
104
105
	
106
	/**
107
	 * Render latte template to string and send (and/or log) mail
108
	 */
109
	public function send(): void
110
	{
111
		$templateName = $this->prepareTemplate();
112
113
		$this->message->setHtmlBody((string) $this->template, $this->mailImagesBasePath);
114
115
		/**
116
		 * In case mail sending in on, send message
117
		 */
118
		if ($this->config === MailingExtension::CONFIG_BOTH || $this->config === MailingExtension::CONFIG_SEND) {
119
			$this->mailer->send($this->message);
120
		}
121
122
		/**
123
		 * In case mail logging is turned on, log message
124
		 */
125
		if ($this->config === MailingExtension::CONFIG_LOG || $this->config === MailingExtension::CONFIG_BOTH) {
126
			$this->logger->log($templateName, $this->message);
127
		}
128
	}
129
	
130
	
131
	/**
132
	 * @return string
133
	 * @throws \ReflectionException
134
	 */
135
	protected function prepareTemplate(): string
136
	{
137
		/**
138
		 * Template variables..
139
		 */
140
		$this->template->mailData = $this->mailData;
0 ignored issues
show
Bug introduced by Pavel Janda
Accessing mailData on the interface Nette\Application\UI\ITemplate suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
141
		
142
		/**
143
		 * Stick to convention that Email:
144
		 * 		/FooMail.php
145
		 *
146
		 * will have template with path of:
147
		 * 		/templates/FooMail.latte
148
		 */
149
		$mailClassReflection = new \ReflectionClass($this);
150
		$templateName = $mailClassReflection->getShortName();
151
		
152
		$this->template->setFile(sprintf(
153
			'%s/templates/%s.latte',
154
			dirname($mailClassReflection->getFilename()),
155
			$templateName
156
		));
157
		
158
		/**
159
		 * Set body/html body
160
		 */
161
		if (version_compare(Engine::VERSION, '2.4.0', '>=')) {
162
			$this->template->getLatte()->addProvider('uiControl', $this->linkGenerator);
163
		} else {
164
			$this->template->_control = $this->linkGenerator;
0 ignored issues
show
Bug introduced by Pavel Janda
Accessing _control on the interface Nette\Application\UI\ITemplate suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
165
		}
166
		
167
		return $templateName;
168
	}
169
}
170