Passed
Push — master ( 84a999...178a27 )
by Peter
02:14
created

Message::fillEntity()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 22
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 12
c 2
b 0
f 0
dl 0
loc 22
rs 9.8666
cc 2
nc 2
nop 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AbterPhp\Contact\Service\Execute;
6
7
use AbterPhp\Contact\Constant\Event;
8
use AbterPhp\Contact\Domain\Entities\Form;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, AbterPhp\Contact\Service\Execute\Form. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
9
use AbterPhp\Contact\Domain\Entities\Message as Entity;
10
use AbterPhp\Contact\Orm\FormRepo;
11
use AbterPhp\Contact\Validation\Factory\Message as ValidatorFactory;
12
use AbterPhp\Framework\Domain\Entities\IStringerEntity;
13
use AbterPhp\Framework\Email\Sender;
14
use AbterPhp\Framework\I18n\ITranslator;
15
use Opulence\Events\Dispatchers\IEventDispatcher;
16
use Opulence\Orm\OrmException;
17
18
class Message
19
{
20
    const FROM_PHONE_LABEL   = 'contact:fromPhone';
21
    const PHONE_NOT_PROVIDED = 'contact:phoneNotProvided';
22
23
    /** @var ValidatorFactory */
24
    protected $validatorFactory;
25
26
    /** @var FormRepo */
27
    protected $formRepo;
28
29
    /** @var Sender */
30
    protected $sender;
31
32
    /** @var IEventDispatcher */
33
    protected $eventDispatcher;
34
35
    /** @var Form[] */
36
    protected $forms = [];
37
38
    /**
39
     * Message constructor.
40
     *
41
     * @param FormRepo         $formRepo
42
     * @param ValidatorFactory $validatorFactory
43
     * @param IEventDispatcher $eventDispatcher
44
     * @param Sender           $sender
45
     * @param ITranslator      $translator
46
     */
47
    public function __construct(
48
        FormRepo $formRepo,
49
        ValidatorFactory $validatorFactory,
50
        IEventDispatcher $eventDispatcher,
51
        Sender $sender,
52
        ITranslator $translator
53
    ) {
54
        $this->formRepo         = $formRepo;
55
        $this->validatorFactory = $validatorFactory;
56
        $this->eventDispatcher  = $eventDispatcher;
57
        $this->sender           = $sender;
58
        $this->translator       = $translator;
0 ignored issues
show
Bug Best Practice introduced by
The property translator does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
59
    }
60
61
    /**
62
     * @param string $formIdentifier
63
     *
64
     * @return Form|null
65
     * @throws \Opulence\Orm\OrmException
66
     */
67
    public function getForm(string $formIdentifier): ?Form
68
    {
69
        if (array_key_exists($formIdentifier, $this->forms)) {
70
            return $this->forms[$formIdentifier];
71
        }
72
73
        try {
74
            $form = $this->formRepo->getByIdentifier($formIdentifier);
75
        } catch (OrmException $e) {
76
            try {
77
                $form = $this->formRepo->getById($formIdentifier);
78
            } catch (OrmException $e) {
79
                return null;
80
            }
81
        }
82
83
        $this->forms[$form->getIdentifier()] = $form;
84
85
        return $form;
86
    }
87
88
    /**
89
     * @param Entity $message
90
     *
91
     * @return int
92
     */
93
    public function send(Entity $message): int
94
    {
95
        $this->eventDispatcher->dispatch(Event::MESSAGE_READY, $message);
96
97
        $form       = $message->getForm();
98
        $recipients = [$form->getToEmail() => $form->getToName()];
99
100
        $replyToAddresses = [$message->getFromEmail() => $message->getFromName()];
101
        $fromAddresses    = $replyToAddresses;
102
103
        $subject = $message->getSubject();
104
        $text    = $this->getText($message);
105
106
        $result = $this->sender->send(
107
            $subject,
108
            $text,
109
            $recipients,
110
            $fromAddresses,
111
            $replyToAddresses
112
        );
113
114
        $this->eventDispatcher->dispatch(Event::MESSAGE_SENT, $message);
115
116
        return $result;
117
    }
118
119
    /**
120
     * @param Entity $message
121
     *
122
     * @return string
123
     */
124
    protected function getText(Entity $message): string
125
    {
126
        if ($message->getFromPhone()) {
127
            return sprintf(
128
                "%s\n\n%s: %s",
129
                $message->getBody(),
130
                $this->translator->translate(static::FROM_PHONE_LABEL),
131
                $message->getFromPhone()
132
            );
133
        }
134
135
        return sprintf(
136
            "%s\n\n%s: %s",
137
            $message->getBody(),
138
            $this->translator->translate(static::FROM_PHONE_LABEL),
139
            $this->translator->translate(static::PHONE_NOT_PROVIDED)
140
        );
141
    }
142
143
    /**
144
     * @return array
145
     */
146
    public function getFailedRecipients(): array
147
    {
148
        return $this->sender->getFailedRecipients();
149
    }
150
151
    /**
152
     * @param string $formIdentifier
153
     * @param array  $postData
154
     *
155
     * @return array errors
156
     * @throws OrmException
157
     */
158
    public function validateForm(string $formIdentifier, array $postData): array
159
    {
160
        /** @var Form $form */
161
        $form = $this->getForm($formIdentifier);
162
        if (null === $form) {
163
            throw new \InvalidArgumentException();
164
        }
165
166
        $validator = $this->validatorFactory
167
            ->setMaxBodyLength($form->getMaxBodyLength())
168
            ->createValidator();
169
170
        if ($validator->isValid($postData)) {
171
            return [];
172
        }
173
174
        return $validator->getErrors()->getAll();
175
    }
176
177
    /**
178
     * @param string $entityId
179
     *
180
     * @return Entity|IStringerEntity
181
     */
182
    public function createEntity(string $entityId): IStringerEntity
183
    {
184
        $form = new Form('', '', '', '', '', '', '', 0);
185
186
        $message = new Entity($entityId, $form, '', '', '', '', '');
187
188
        return $message;
189
    }
190
191
    /**
192
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
193
     *
194
     * @param string          $formIdentifier
195
     * @param IStringerEntity $entity
196
     * @param array           $postData
197
     * @param array           $fileData
198
     *
199
     * @return IStringerEntity|Entity
200
     */
201
    public function fillEntity(
202
        string $formIdentifier,
203
        IStringerEntity $entity,
204
        array $postData,
205
        array $fileData
0 ignored issues
show
Unused Code introduced by
The parameter $fileData is not used and could be removed. ( Ignorable by Annotation )

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

205
        /** @scrutinizer ignore-unused */ array $fileData

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
206
    ): IStringerEntity {
207
        assert($entity instanceof Entity, new \InvalidArgumentException('Invalid entity'));
208
209
        $form = $this->getForm($formIdentifier);
210
        if (null === $form) {
211
            return $entity;
212
        }
213
214
        $entity
215
            ->setForm($form)
216
            ->setSubject($postData['subject'])
217
            ->setBody($postData['body'])
218
            ->setFromName($postData['from_name'])
219
            ->setFromEmail($postData['from_email'])
220
            ->setFromPhone($postData['from_phone']);
221
222
        return $entity;
223
    }
224
}
225