Passed
Push — master ( 9ca29d...a6c5cb )
by Julito
09:10
created

Message::getReceiversCc()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 16
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 5
c 0
b 0
f 0
nc 3
nop 0
dl 0
loc 16
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
/* For licensing terms, see /license.txt */
6
7
namespace Chamilo\CoreBundle\Entity;
8
9
use ApiPlatform\Core\Annotation\ApiFilter;
10
use ApiPlatform\Core\Annotation\ApiProperty;
11
use ApiPlatform\Core\Annotation\ApiResource;
12
use ApiPlatform\Core\Annotation\ApiSubresource;
13
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\OrderFilter;
14
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\SearchFilter;
15
use Chamilo\CourseBundle\Entity\CGroup;
16
use DateTime;
17
use Doctrine\Common\Collections\ArrayCollection;
18
use Doctrine\Common\Collections\Collection;
19
use Doctrine\Common\Collections\Criteria;
20
use Doctrine\ORM\Mapping as ORM;
21
use Gedmo\Mapping\Annotation as Gedmo;
22
use Symfony\Component\Serializer\Annotation\Groups;
23
use Symfony\Component\Validator\Constraints as Assert;
24
25
/**
26
 * Message.
27
 *
28
 * @ORM\Table(name="message", indexes={
29
 *     @ORM\Index(name="idx_message_user_sender", columns={"user_sender_id"}),
30
 *     @ORM\Index(name="idx_message_group", columns={"group_id"}),
31
 *     @ORM\Index(name="idx_message_type", columns={"msg_type"})
32
 * })
33
 * @ORM\Entity(repositoryClass="Chamilo\CoreBundle\Repository\MessageRepository")
34
 * @ORM\EntityListeners({"Chamilo\CoreBundle\Entity\Listener\MessageListener"})
35
 */
36
#[ApiResource(
37
    collectionOperations: [
38
        'get' => [
39
            'security' => "is_granted('ROLE_USER')",  // the get collection is also filtered by MessageExtension.php
40
        ],
41
        'post' => [
42
            //'security' => "is_granted('ROLE_USER')",
43
            /*'messenger' => true,
44
            'output' => false,
45
            'status' => 202,*/
46
            'security_post_denormalize' => "is_granted('CREATE', object)",
47
            //            'deserialize' => false,
48
            //            'controller' => Create::class,
49
            //            'openapi_context' => [
50
            //                'requestBody' => [
51
            //                    'content' => [
52
            //                        'multipart/form-data' => [
53
            //                            'schema' => [
54
            //                                'type' => 'object',
55
            //                                'properties' => [
56
            //                                    'title' => [
57
            //                                        'type' => 'string',
58
            //                                    ],
59
            //                                    'content' => [
60
            //                                        'type' => 'string',
61
            //                                    ],
62
            //                                ],
63
            //                            ],
64
            //                        ],
65
            //                    ],
66
            //                ],
67
            //            ],
68
        ],
69
    ],
70
    itemOperations: [
71
        'get' => [
72
            'security' => "is_granted('VIEW', object)",
73
        ],
74
        'put' => [
75
            'security' => "is_granted('EDIT', object)",
76
        ],
77
        'delete' => [
78
            'security' => "is_granted('DELETE', object)",
79
        ],
80
    ],
81
    attributes: [
82
        'security' => "is_granted('ROLE_USER')",
83
    ],
84
    denormalizationContext: [
85
        'groups' => ['message:write'],
86
    ],
87
    normalizationContext: [
88
        'groups' => ['message:read'],
89
    ],
90
)]
91
#[ApiFilter(OrderFilter::class, properties: ['title', 'sendDate'])]
92
#[ApiFilter(SearchFilter::class, properties: [
93
    'msgType' => 'exact',
94
    'status' => 'exact',
95
    'sender' => 'exact',
96
    'receivers.receiver' => 'exact',
97
    'receivers.tags.tag' => 'exact',
98
])]
99
class Message
100
{
101
    public const MESSAGE_TYPE_INBOX = 1;
102
    public const MESSAGE_TYPE_OUTBOX = 2;
103
    public const MESSAGE_TYPE_PROMOTED = 3;
104
    public const MESSAGE_TYPE_WALL = 4;
105
    public const MESSAGE_TYPE_GROUP = 5;
106
    public const MESSAGE_TYPE_INVITATION = 6;
107
    public const MESSAGE_TYPE_CONVERSATION = 7;
108
109
    // status
110
    public const MESSAGE_STATUS_DELETED = 3;
111
    public const MESSAGE_STATUS_DRAFT = 4;
112
    public const MESSAGE_STATUS_INVITATION_PENDING = 5;
113
    public const MESSAGE_STATUS_INVITATION_ACCEPTED = 6;
114
    public const MESSAGE_STATUS_INVITATION_DENIED = 7;
115
    public const MESSAGE_STATUS_PROMOTED = 13;
116
117
    /**
118
     * @ORM\Column(name="id", type="bigint")
119
     * @ORM\Id
120
     * @ORM\GeneratedValue()
121
     */
122
    #[ApiProperty(identifier: true)]
123
    #[Groups(['message:read'])]
124
    protected ?int $id = null;
125
126
    /**
127
     * @ORM\ManyToOne(targetEntity="User", inversedBy="sentMessages")
128
     * @ORM\JoinColumn(name="user_sender_id", referencedColumnName="id", nullable=false)
129
     */
130
    #[Assert\NotBlank]
131
    #[Groups(['message:read', 'message:write'])]
132
    protected User $sender;
133
134
    /**
135
     * @var Collection|MessageRelUser[]
136
     *
137
     * @ORM\OneToMany(targetEntity="MessageRelUser", mappedBy="message", cascade={"persist", "remove"})
138
     */
139
    #[Assert\Valid]
140
    #[Groups(['message:read', 'message:write'])]
141
    #[ApiSubresource]
142
    protected array | null | Collection $receivers;
143
144
    /**
145
     * @var Collection|MessageRelUser[]
146
     */
147
    #[Groups(['message:read', 'message:write'])]
148
    protected array | null | Collection $receiversTo;
149
150
    /**
151
     * @var Collection|MessageRelUser[]
152
     */
153
    #[Groups(['message:read', 'message:write'])]
154
    protected array | null | Collection $receiversCc;
155
156
    /**
157
     * @ORM\Column(name="msg_type", type="smallint", nullable=false)
158
     */
159
    #[Assert\NotBlank]
160
    // @todo use enums with PHP 8.1
161
    /*#[Assert\Choice([
162
        self::MESSAGE_TYPE_INBOX,
163
        self::MESSAGE_TYPE_OUTBOX,
164
        self::MESSAGE_TYPE_PROMOTED,
165
    ])]*/
166
    /*#[ApiProperty(attributes: [
167
        'openapi_context' => [
168
            'type' => 'int',
169
            'enum' => [self::MESSAGE_TYPE_INBOX, self::MESSAGE_TYPE_OUTBOX],
170
        ],
171
    ])]*/
172
    #[Groups(['message:read', 'message:write'])]
173
    protected int $msgType;
174
175
    /**
176
     * @ORM\Column(name="status", type="smallint", nullable=false)
177
     */
178
    #[Assert\NotBlank]
179
    #[Groups(['message:read', 'message:write'])]
180
    protected int $status;
181
182
    /**
183
     * @ORM\Column(name="send_date", type="datetime", nullable=false)
184
     */
185
    #[Groups(['message:read'])]
186
    protected DateTime $sendDate;
187
188
    /**
189
     * @ORM\Column(name="title", type="string", length=255, nullable=false)
190
     */
191
    #[Assert\NotBlank]
192
    #[Groups(['message:read', 'message:write'])]
193
    protected string $title;
194
195
    /**
196
     * @ORM\Column(name="content", type="text", nullable=false)
197
     */
198
    #[Assert\NotBlank]
199
    #[Groups(['message:read', 'message:write'])]
200
    protected string $content;
201
202
    #[Groups(['message:read', 'message:write'])]
203
    protected ?MessageRelUser $firstReceiver;
204
205
    /**
206
     * @ORM\ManyToOne(targetEntity="Chamilo\CourseBundle\Entity\CGroup")
207
     * @ORM\JoinColumn(name="group_id", referencedColumnName="iid", nullable=true, onDelete="CASCADE")
208
     */
209
    protected ?CGroup $group = null;
210
211
    /**
212
     * @var Collection|Message[]
213
     * @ORM\OneToMany(targetEntity="Message", mappedBy="parent")
214
     */
215
    protected Collection $children;
216
217
    /**
218
     * @ORM\ManyToOne(targetEntity="Message", inversedBy="children")
219
     * @ORM\JoinColumn(name="parent_id", referencedColumnName="id")
220
     */
221
    protected ?Message $parent = null;
222
223
    /**
224
     * @Gedmo\Timestampable(on="update")
225
     * @ORM\Column(name="update_date", type="datetime", nullable=true)
226
     */
227
    protected ?DateTime $updateDate;
228
229
    /**
230
     * @ORM\Column(name="votes", type="integer", nullable=true)
231
     */
232
    protected ?int $votes;
233
234
    /**
235
     * @var Collection|MessageAttachment[]
236
     *
237
     * @ORM\OneToMany(targetEntity="MessageAttachment", mappedBy="message")
238
     */
239
    protected Collection $attachments;
240
241
    /**
242
     * @var Collection|MessageFeedback[]
243
     *
244
     * @ORM\OneToMany(targetEntity="MessageFeedback", mappedBy="message", orphanRemoval=true)
245
     */
246
    protected Collection $likes;
247
248
    public function __construct()
249
    {
250
        $this->sendDate = new DateTime('now');
251
        $this->updateDate = $this->sendDate;
252
        $this->msgType = self::MESSAGE_TYPE_INBOX;
253
        $this->content = '';
254
        $this->attachments = new ArrayCollection();
255
        $this->children = new ArrayCollection();
256
        $this->likes = new ArrayCollection();
257
        $this->receivers = new ArrayCollection();
258
        $this->receiversCc = new ArrayCollection();
259
        $this->receiversTo = new ArrayCollection();
260
        $this->votes = 0;
261
        $this->status = 0;
262
    }
263
264
    /**
265
     * @return null|Collection|MessageRelUser[]
266
     */
267
    public function getReceivers()
268
    {
269
        return $this->receivers;
270
    }
271
272
    /**
273
     * @return null|Collection|MessageRelUser[]
274
     */
275
    public function getReceiversTo()
276
    {
277
        return $this->getReceivers()->filter(function (MessageRelUser $messageRelUser) {
278
            return MessageRelUser::TYPE_TO === $messageRelUser->getReceiverType();
279
        });
280
    }
281
282
    /**
283
     * @return MessageRelUser[]
284
     */
285
    public function getReceiversCc()
286
    {
287
        $list = [];
288
        foreach ($this->receivers as $receiver) {
289
            if (MessageRelUser::TYPE_CC === $receiver->getReceiverType()) {
290
                $list[] = $receiver;
291
            }
292
        }
293
294
        /*
295
        $result = $this->receivers->filter(function (MessageRelUser $messageRelUser) {
296
            error_log((string)$messageRelUser->getId());
297
            return MessageRelUser::TYPE_CC === $messageRelUser->getReceiverType();
298
        });
299
        */
300
        return $list;
301
    }
302
303
    public function getFirstReceiver(): ?MessageRelUser
304
    {
305
        if ($this->receivers->count() > 0) {
306
            return $this->receivers->first();
307
        }
308
309
        return null;
310
    }
311
312
    public function hasReceiver(User $receiver)
313
    {
314
        if ($this->receivers->count()) {
315
            $criteria = Criteria::create()->where(
316
                Criteria::expr()->eq('receiver', $receiver),
317
            )->andWhere(
318
                Criteria::expr()->eq('message', $this),
319
            );
320
321
            return $this->receivers->matching($criteria)->count() > 0;
322
        }
323
324
        return false;
325
    }
326
327
    public function addReceiver(User $receiver, int $receiverType = MessageRelUser::TYPE_TO): self
328
    {
329
        $messageRelUser = (new MessageRelUser())
330
            ->setReceiver($receiver)
331
            ->setReceiverType($receiverType)
332
            ->setMessage($this)
333
        ;
334
        if (!$this->receivers->contains($messageRelUser)) {
335
            $this->receivers->add($messageRelUser);
336
        }
337
338
        return $this;
339
    }
340
341
    /**
342
     * @param Collection|MessageRelUser $receivers
343
     */
344
    public function setReceivers($receivers): self
345
    {
346
        /** @var MessageRelUser $receiver */
347
        foreach ($receivers as $receiver) {
348
            $receiver->setMessage($this);
349
        }
350
        $this->receivers = $receivers;
0 ignored issues
show
Documentation Bug introduced by
It seems like $receivers can also be of type Chamilo\CoreBundle\Entity\MessageRelUser. However, the property $receivers is declared as type Chamilo\CoreBundle\Entit...\Collections\Collection. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
351
352
        return $this;
353
    }
354
355
    public function setSender(User $sender): self
356
    {
357
        $this->sender = $sender;
358
359
        return $this;
360
    }
361
362
    public function getSender(): User
363
    {
364
        return $this->sender;
365
    }
366
367
    public function setMsgType(int $msgType): self
368
    {
369
        $this->msgType = $msgType;
370
371
        return $this;
372
    }
373
374
    public function getMsgType(): int
375
    {
376
        return $this->msgType;
377
    }
378
379
    public function setSendDate(DateTime $sendDate): self
380
    {
381
        $this->sendDate = $sendDate;
382
383
        return $this;
384
    }
385
386
    /**
387
     * Get sendDate.
388
     *
389
     * @return DateTime
390
     */
391
    public function getSendDate()
392
    {
393
        return $this->sendDate;
394
    }
395
396
    public function setTitle(string $title): self
397
    {
398
        $this->title = $title;
399
400
        return $this;
401
    }
402
403
    public function getTitle(): string
404
    {
405
        return $this->title;
406
    }
407
408
    public function setContent(string $content): self
409
    {
410
        $this->content = $content;
411
412
        return $this;
413
    }
414
415
    public function getContent(): string
416
    {
417
        return $this->content;
418
    }
419
420
    public function setUpdateDate(DateTime $updateDate): self
421
    {
422
        $this->updateDate = $updateDate;
423
424
        return $this;
425
    }
426
427
    /**
428
     * Get updateDate.
429
     *
430
     * @return DateTime
431
     */
432
    public function getUpdateDate()
433
    {
434
        return $this->updateDate;
435
    }
436
437
    /**
438
     * Get id.
439
     *
440
     * @return int
441
     */
442
    public function getId()
443
    {
444
        return $this->id;
445
    }
446
447
    public function setVotes(int $votes): self
448
    {
449
        $this->votes = $votes;
450
451
        return $this;
452
    }
453
454
    public function getVotes(): int
455
    {
456
        return $this->votes;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->votes could return the type null which is incompatible with the type-hinted return integer. Consider adding an additional type-check to rule them out.
Loading history...
457
    }
458
459
    /**
460
     * Get attachments.
461
     *
462
     * @return Collection|MessageAttachment[]
463
     */
464
    public function getAttachments()
465
    {
466
        return $this->attachments;
467
    }
468
469
    public function addAttachment(MessageAttachment $attachment): self
470
    {
471
        $this->attachments->add($attachment);
472
        $attachment->setMessage($this);
473
474
        return $this;
475
    }
476
477
    public function getParent(): ?self
478
    {
479
        return $this->parent;
480
    }
481
482
    /**
483
     * @return Collection|Message[]
484
     */
485
    public function getChildren()
486
    {
487
        return $this->children;
488
    }
489
490
    public function addChild(self $child): self
491
    {
492
        $this->children[] = $child;
493
        $child->setParent($this);
494
495
        return $this;
496
    }
497
498
    public function setParent(self $parent = null): self
499
    {
500
        $this->parent = $parent;
501
502
        return $this;
503
    }
504
505
    /**
506
     * @return MessageFeedback[]|Collection
507
     */
508
    public function getLikes()
509
    {
510
        return $this->likes;
511
    }
512
513
    public function getGroup(): ?CGroup
514
    {
515
        return $this->group;
516
    }
517
518
    public function setGroup(?CGroup $group): self
519
    {
520
//        $this->msgType = self::MESSAGE_TYPE_GROUP;
521
        $this->group = $group;
522
523
        return $this;
524
    }
525
526
    public function getStatus(): int
527
    {
528
        return $this->status;
529
    }
530
531
    public function setStatus(int $status): self
532
    {
533
        $this->status = $status;
534
535
        return $this;
536
    }
537
}
538