Completed
Push — master ( 65d1c9...433450 )
by
unknown
42:42 queued 02:37
created

Mailer::send()   C

Complexity

Conditions 7
Paths 19

Size

Total Lines 34
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 34
rs 6.7272
c 0
b 0
f 0
cc 7
eloc 18
nc 19
nop 3
1
<?php
2
3
namespace SfCod\EmailEngineBundle\Mailer;
4
5
use Psr\Log\LoggerInterface;
6
use SfCod\EmailEngineBundle\Exception\RepositoryUnavailableException;
7
use SfCod\EmailEngineBundle\Repository\RepositoryInterface;
8
use SfCod\EmailEngineBundle\Sender\MessageOptionsInterface;
9
use SfCod\EmailEngineBundle\Sender\SenderInterface;
10
use SfCod\EmailEngineBundle\Template\ParametersAwareInterface;
11
use SfCod\EmailEngineBundle\Template\Params\ParameterResolverInterface;
12
use SfCod\EmailEngineBundle\Template\RepositoryAwareInterface;
13
use SfCod\EmailEngineBundle\Template\TemplateInterface;
14
use Symfony\Component\DependencyInjection\ContainerInterface;
15
16
/**
17
 * Class Mailer
18
 *
19
 * @author Virchenko Maksim <[email protected]>
20
 *
21
 * @package SfCod\EmailEngineBundle\Sender
22
 */
23
class Mailer
24
{
25
    /**
26
     * Senders for email sending
27
     *
28
     * @var SenderInterface[]
29
     */
30
    private $senders = [];
31
32
    /**
33
     * @var ContainerInterface
34
     */
35
    private $container;
36
37
    /**
38
     * @var LoggerInterface
39
     */
40
    private $logger;
41
42
    /**
43
     * EmailSender constructor.
44
     *
45
     * @param ContainerInterface $container
46
     * @param LoggerInterface $logger
47
     */
48
    public function __construct(ContainerInterface $container, LoggerInterface $logger)
49
    {
50
        $this->container = $container;
51
        $this->logger = $logger;
52
    }
53
54
    /**
55
     * Get senders
56
     *
57
     * @return array
58
     */
59
    public function getSenders(): array
60
    {
61
        return $this->senders;
62
    }
63
64
    /**
65
     * Set senders
66
     *
67
     * @param array $senders
68
     */
69
    public function setSenders(array $senders): void
70
    {
71
        $this->senders = $senders;
72
    }
73
74
    /**
75
     * Send email template
76
     *
77
     * @param TemplateInterface $template
78
     * @param array|string $emails
79
     * @param null|MessageOptionsInterface $options
80
     *
81
     * @return int
82
     */
83
    public function send(TemplateInterface $template, $emails, ?MessageOptionsInterface $options = null): int
84
    {
85
        $sentCount = 0;
86
87
        foreach ($this->senders as $config) {
88
            try {
89
                $concreteTemplate = clone $template;
90
                $sender = array_merge($config['sender'], ['options' => $options]);
91
                $concreteSender = $this->makeSender($sender['class'], $sender['options'] ?? []);
0 ignored issues
show
Documentation introduced by
$sender['class'] is of type null|object<SfCod\EmailE...essageOptionsInterface>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Bug introduced by
It seems like $sender['options'] ?? array() can also be of type object<SfCod\EmailEngine...essageOptionsInterface>; however, SfCod\EmailEngineBundle\...er\Mailer::makeSender() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
92
93
                if ($concreteTemplate instanceof RepositoryAwareInterface) {
94
                    $concreteTemplate->setRepository($this->makeRepository($config['repository']['class'], $concreteTemplate, $config['repository']['arguments']));
95
                }
96
97
                if ($concreteTemplate instanceof ParametersAwareInterface) {
98
                    $concreteTemplate->setParameterResolver($this->container->get(ParameterResolverInterface::class));
99
                }
100
101
                if ($concreteSender->send($concreteTemplate, $emails)) {
102
                    ++$sentCount;
103
104
                    break;
105
                }
106
            } catch (RepositoryUnavailableException $e) {
107
                if ($this->container->get('kernel')->isDebug()) {
108
                    $this->logger->error($e->getMessage(), ['exception' => $e]);
109
                }
110
111
                // Try next sender
112
            }
113
        }
114
115
        return $sentCount;
116
    }
117
118
    /**
119
     * Make email engine sender
120
     *
121
     * @param string $sender
122
     * @param array $options
123
     *
124
     * @return SenderInterface
125
     */
126
    protected function makeSender(string $sender, array $options = []): SenderInterface
127
    {
128
        /** @var SenderInterface $sender */
129
        $sender = $this->container->get($sender);
0 ignored issues
show
Documentation introduced by
$sender is of type object<SfCod\EmailEngine...Sender\SenderInterface>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
130
131
        if (false === empty($options)) {
132
            $sender->setOptions($options);
0 ignored issues
show
Documentation introduced by
$options is of type array, but the function expects a object<SfCod\EmailEngine...essageOptionsInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
133
        }
134
135
        return $sender;
136
    }
137
138
    /**
139
     * Make email engine repository
140
     *
141
     * @param string $repository
142
     * @param TemplateInterface $template
143
     * @param array $arguments
144
     *
145
     * @return RepositoryInterface
146
     */
147
    protected function makeRepository(string $repository, TemplateInterface $template, array $arguments = []): RepositoryInterface
148
    {
149
        /** @var RepositoryInterface $repository */
150
        $repository = $this->container->get($repository);
0 ignored issues
show
Documentation introduced by
$repository is of type object<SfCod\EmailEngine...ry\RepositoryInterface>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
151
        $repository->connect($template, $arguments);
152
153
        return $repository;
154
    }
155
}
156