Issues (3627)

app/bundles/ChannelBundle/Model/MessageModel.php (6 issues)

1
<?php
2
3
/*
4
 * @copyright   2016 Mautic Contributors. All rights reserved
5
 * @author      Mautic, Inc.
6
 *
7
 * @link        https://mautic.org
8
 *
9
 * @license     GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
10
 */
11
12
namespace Mautic\ChannelBundle\Model;
13
14
use Mautic\CampaignBundle\Model\CampaignModel;
15
use Mautic\ChannelBundle\ChannelEvents;
16
use Mautic\ChannelBundle\Entity\Message;
17
use Mautic\ChannelBundle\Event\MessageEvent;
18
use Mautic\ChannelBundle\Form\Type\MessageType;
19
use Mautic\ChannelBundle\Helper\ChannelListHelper;
20
use Mautic\CoreBundle\Model\AjaxLookupModelInterface;
21
use Mautic\CoreBundle\Model\FormModel;
22
use Symfony\Component\EventDispatcher\Event;
23
use Symfony\Component\Form\FormFactory;
24
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
25
26
/**
27
 * Class MessageModel.
28
 */
29
class MessageModel extends FormModel implements AjaxLookupModelInterface
30
{
31
    const CHANNEL_FEATURE = 'marketing_messages';
32
33
    /**
34
     * @var ChannelListHelper
35
     */
36
    protected $channelListHelper;
37
38
    /**
39
     * @var CampaignModel
40
     */
41
    protected $campaignModel;
42
43
    protected static $channels;
44
45
    /**
46
     * MessageModel constructor.
47
     */
48
    public function __construct(ChannelListHelper $channelListHelper, CampaignModel $campaignModel)
49
    {
50
        $this->channelListHelper = $channelListHelper;
51
        $this->campaignModel     = $campaignModel;
52
    }
53
54
    /**
55
     * @param Message $entity
56
     * @param bool    $unlock
57
     */
58
    public function saveEntity($entity, $unlock = true)
59
    {
60
        $isNew = $entity->isNew();
61
62
        parent::saveEntity($entity, $unlock);
63
64
        if (!$isNew) {
65
            // Update the channels
66
            $channels = $entity->getChannels();
67
            foreach ($channels as $channel) {
68
                $channel->setMessage($entity);
69
            }
70
            $this->getRepository()->saveEntities($channels);
71
        }
72
    }
73
74
    /**
75
     * @return string
76
     */
77
    public function getPermissionBase()
78
    {
79
        return 'channel:messages';
80
    }
81
82
    /**
83
     * @return \Doctrine\ORM\EntityRepository|\Mautic\ChannelBundle\Entity\MessageRepository
84
     */
85
    public function getRepository()
86
    {
87
        return $this->em->getRepository('MauticChannelBundle:Message');
88
    }
89
90
    /**
91
     * @param null $id
92
     *
93
     * @return Form
0 ignored issues
show
The type Mautic\ChannelBundle\Model\Form 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...
94
     */
95
    public function getEntity($id = null)
96
    {
97
        if (null === $id) {
98
            return new Message();
0 ignored issues
show
Bug Best Practice introduced by
The expression return new Mautic\ChannelBundle\Entity\Message() returns the type Mautic\ChannelBundle\Entity\Message which is incompatible with the documented return type Mautic\ChannelBundle\Model\Form.
Loading history...
99
        }
100
101
        return parent::getEntity($id);
102
    }
103
104
    /**
105
     * @param object      $entity
106
     * @param FormFactory $formFactory
107
     * @param null        $action
108
     * @param array       $options
109
     *
110
     * @return \Symfony\Component\Form\FormInterface
111
     */
112
    public function createForm($entity, $formFactory, $action = null, $options = [])
113
    {
114
        if (!empty($action)) {
115
            $options['action'] = $action;
116
        }
117
118
        return $formFactory->create(MessageType::class, $entity, $options);
119
    }
120
121
    /**
122
     * @return array
123
     */
124
    public function getChannels()
125
    {
126
        if (!self::$channels) {
127
            $channels = $this->channelListHelper->getFeatureChannels(self::CHANNEL_FEATURE);
128
129
            // Validate channel configs
130
            foreach ($channels as $channel => $config) {
131
                if (!isset($config['lookupFormType']) && !isset($config['propertiesFormType'])) {
132
                    throw new \InvalidArgumentException('lookupFormType and/or propertiesFormType are required for channel '.$channel);
133
                }
134
135
                switch (true) {
136
                    case $this->translator->hasId('mautic.channel.'.$channel):
137
                        $label = $this->translator->trans('mautic.channel.'.$channel);
138
                        break;
139
                    case $this->translator->hasId('mautic.'.$channel):
140
                        $label = $this->translator->trans('mautic.'.$channel);
141
                        break;
142
                    case $this->translator->hasId('mautic.'.$channel.'.'.$channel):
143
                        $label = $this->translator->trans('mautic.'.$channel.'.'.$channel);
144
                        break;
145
                    default:
146
                        $label = ucfirst($channel);
147
                }
148
                $config['label'] = $label;
149
150
                $channels[$channel] = $config;
151
            }
152
153
            self::$channels = $channels;
154
        }
155
156
        return self::$channels;
157
    }
158
159
    /**
160
     * @param        $type
161
     * @param string $filter
162
     * @param int    $limit
163
     * @param int    $start
164
     * @param array  $options
165
     *
166
     * @return array
167
     */
168
    public function getLookupResults($type, $filter = '', $limit = 10, $start = 0, $options = [])
169
    {
170
        $results = [];
171
        switch ($type) {
172
            case 'channel.message':
173
                $entities = $this->getRepository()->getMessageList(
174
                    $filter,
175
                    $limit,
176
                    $start,
177
                    $this->security->isGranted($this->getPermissionBase().':viewother')
0 ignored issues
show
The call to Mautic\ChannelBundle\Ent...itory::getMessageList() has too many arguments starting with $this->security->isGrant...nBase() . ':viewother'). ( Ignorable by Annotation )

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

177
                $entities = $this->getRepository()->/** @scrutinizer ignore-call */ getMessageList(

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...
178
                );
179
180
                foreach ($entities as $entity) {
181
                    $results[] = [
182
                        'label' => $entity['name'],
183
                        'value' => $entity['id'],
184
                    ];
185
                }
186
187
                break;
188
        }
189
190
        return $results;
191
    }
192
193
    /**
194
     * @param $messageId
195
     *
196
     * @return array
197
     */
198
    public function getMessageChannels($messageId)
199
    {
200
        return $this->getRepository()->getMessageChannels($messageId);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getReposit...ageChannels($messageId) also could return the type integer|object which is incompatible with the documented return type array.
Loading history...
201
    }
202
203
    /**
204
     * @param $channelId
205
     *
206
     * @return array
207
     */
208
    public function getChannelMessageByChannelId($channelId)
209
    {
210
        return $this->getRepository()->getChannelMessageByChannelId($channelId);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getReposit...ByChannelId($channelId) also could return the type integer|object which is incompatible with the documented return type array.
Loading history...
211
    }
212
213
    /**
214
     * @param      $messageId
215
     * @param null $dateFrom
216
     * @param null $dateTo
217
     * @param null $channel
218
     *
219
     * @return array
220
     */
221
    public function getLeadStatsPost($messageId, $dateFrom = null, $dateTo = null, $channel = null)
222
    {
223
        $eventLog = $this->campaignModel->getCampaignLeadEventLogRepository();
224
225
        return $eventLog->getChartQuery(
226
            [
227
                'type'       => 'message.send',
228
                'dateFrom'   => $dateFrom,
229
                'dateTo'     => $dateTo,
230
                'channel'    => 'channel.message',
231
                'channelId'  => $messageId,
232
                'logChannel' => $channel,
233
            ]
234
        );
235
    }
236
237
    /**
238
     * @param      $messageId
239
     * @param null $dateFrom
240
     * @param null $dateTo
241
     *
242
     * @return mixed
243
     */
244
    public function getMarketingMessagesEventLogs($messageId, $dateFrom = null, $dateTo = null)
245
    {
246
        $eventLog = $this->campaignModel->getCampaignLeadEventLogRepository();
247
248
        return $eventLog->getEventLogs(['type' => 'message.send', 'dateFrom' => $dateFrom, 'dateTo' => $dateTo, 'channel' => 'message', 'channelId' => $messageId]);
0 ignored issues
show
The method getEventLogs() does not exist on Mautic\CampaignBundle\En...\LeadEventLogRepository. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

248
        return $eventLog->/** @scrutinizer ignore-call */ getEventLogs(['type' => 'message.send', 'dateFrom' => $dateFrom, 'dateTo' => $dateTo, 'channel' => 'message', 'channelId' => $messageId]);
Loading history...
249
    }
250
251
    /**
252
     * Get the channel name from the database.
253
     *
254
     * @param int    $id
255
     * @param string $entityName
256
     * @param string $nameColumn
257
     *
258
     * @return string|null
259
     */
260
    public function getChannelName($id, $entityName, $nameColumn = 'name')
261
    {
262
        if (!$id || !$entityName || !$nameColumn) {
263
            return null;
264
        }
265
266
        $repo = $this->em->getRepository($entityName);
267
        $qb   = $repo->createQueryBuilder('e')
268
            ->select('e.'.$nameColumn)
269
            ->where('e.id = :id')
270
            ->setParameter('id', (int) $id);
271
        $result = $qb->getQuery()->getOneOrNullResult();
272
273
        if (isset($result[$nameColumn])) {
274
            return $result[$nameColumn];
275
        }
276
277
        return null;
278
    }
279
280
    /**
281
     * {@inheritdoc}
282
     *
283
     * @throws MethodNotAllowedHttpException
284
     */
285
    protected function dispatchEvent($action, &$entity, $isNew = false, Event $event = null)
286
    {
287
        if (!$entity instanceof Message) {
288
            throw new MethodNotAllowedHttpException(['Message']);
289
        }
290
291
        switch ($action) {
292
            case 'pre_save':
293
                $name = ChannelEvents::MESSAGE_PRE_SAVE;
294
                break;
295
            case 'post_save':
296
                $name = ChannelEvents::MESSAGE_POST_SAVE;
297
                break;
298
            case 'pre_delete':
299
                $name = ChannelEvents::MESSAGE_PRE_DELETE;
300
                break;
301
            case 'post_delete':
302
                $name = ChannelEvents::MESSAGE_POST_DELETE;
303
                break;
304
            default:
305
                return null;
306
        }
307
308
        if ($this->dispatcher->hasListeners($name)) {
309
            if (empty($event)) {
310
                $event = new MessageEvent($entity, $isNew);
311
            }
312
            $this->dispatcher->dispatch($name, $event);
313
314
            return $event;
315
        }
316
317
        return null;
318
    }
319
}
320