Completed
Push — master ( 9c742a...1858b1 )
by Fèvre
14s
created

src/Controller/ConversationsController.php (9 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
namespace App\Controller;
3
4
use App\Event\Notifications;
5
use Cake\Core\Configure;
6
use Cake\Database\Expression\QueryExpression;
7
use Cake\Event\Event;
8
use Cake\I18n\Time;
9
use Cake\Network\Exception\NotFoundException;
10
use Cake\Routing\Router;
11
12
class ConversationsController extends AppController
13
{
14
15
    /**
16
     * Initialization hook method.
17
     *
18
     * @return void
19
     */
20
    public function initialize()
21
    {
22
        parent::initialize();
23
24
        $this->loadComponent('RequestHandler');
25
    }
26
27
    /**
28
     * BeforeFilter handle.
29
     *
30
     * @param Event $event The beforeFilter event that was fired.
31
     *
32
     * @return void
33
     */
34
    public function beforeFilter(Event $event)
35
    {
36
        parent::beforeFilter($event);
37
38
        $this->Auth->deny();
39
40
        if (Configure::read('Conversations.enabled') === false && $this->request->action != 'maintenance') {
41
            $this->redirect(['action' => 'maintenance']);
42
        } elseif (Configure::read('Conversations.enabled') === true && $this->request->action == 'maintenance') {
43
            $this->redirect(['action' => 'index']);
44
        }
45
    }
46
47
    /**
48
     * Display all conversations for the user.
49
     *
50
     * @return void
51
     */
52
    public function index()
53
    {
54
        $this->ConversationsUsers = $this->loadModel('ConversationsUsers');
55
56
        $this->paginate = [
57
            'maxLimit' => Configure::read('Conversations.conversations_per_page')
58
        ];
59
        $conversations = $this->ConversationsUsers
60
            ->find()
61
            ->contain([
62
                'Users',
63
                'Conversations',
64
                'Conversations.Users' => function ($q) {
65
                    return $q->find('medium');
66
                },
67
                'Conversations.LastMessage',
68
                'Conversations.LastMessageUser'
69
            ])
70
            ->where([
71
                'ConversationsUsers.user_id' => $this->Auth->user('id'),
72
                'Conversations.conversation_open <>' => 2
73
            ])
74
            ->order([
75
                'ConversationsUsers.is_read' => 'ASC',
76
                'ConversationsUsers.is_star' => 'DESC',
77
                'Conversations.last_message_date' => 'DESC',
78
            ]);
79
80
        $conversations = $this->paginate($conversations);
81
82
        $this->set(compact('conversations'));
83
    }
84
85
    /**
86
     * Function to do an action when a user select a/many conversations.
87
     *
88
     * Action list :
89
     *      star : Conversations Important
90
     *      normal : Make normal conversation
91
     *      exit : Exit conversations
92
     *
93
     * @return void
94
     *
95
     * @throws NotFoundException
96
     */
97
    public function action()
98
    {
99
        if (!$this->request->is('ajax')) {
100
            throw new NotFoundException();
101
        }
102
103
        $actionAllowed = ['star', 'normal', 'exit'];
104
105
        if (!array_key_exists('action', $this->request->data) || !in_array($this->request->data['action'], $actionAllowed)) {
106
            $json = [];
107
            $json['error'] = '1';
108
            $json['message'] = __d('conversations', 'Action unknown.');
109
110
            $this->set(compact('json'));
111
            $this->set('_serialize', 'json');
112
        }
113
114
        if (!array_key_exists('conversations', $this->request->data)) {
115
            $json = [];
116
            $json['error'] = '1';
117
            $json['message'] = __d('conversations', 'You have not chosen any conversations.');
118
119
            $this->set(compact('json'));
120
            $this->set('_serialize', 'json');
121
        }
122
123
        $this->loadModel('ConversationsUsers');
124
125
        $action = $this->request->data['action'];
126
        $array = $this->request->data['conversations'];
127
128
        switch ($action) {
129 View Code Duplication
            case "star":
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
130
                foreach ($array as $conversationId) {
131
                    $this->ConversationsUsers->updateAll(
132
                        ['is_star' => 1],
133
                        [
134
                            'conversation_id' => $conversationId,
135
                            'user_id' => $this->Auth->user('id')
136
                        ]
137
                    );
138
                }
139
140
                $json['message'] = __d('conversations', 'Your conversation(s) has been Stared.');
141
                $json['error'] = '0';
142
                $json['redirect'] = Router::url(['action' => 'index']);
143
144
                $this->set(compact('json'));
145
146
                break;
147
148 View Code Duplication
            case "normal":
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
149
                foreach ($array as $conversationId) {
150
                    $this->ConversationsUsers->updateAll(
151
                        ['is_star' => 0],
152
                        [
153
                            'conversation_id' => $conversationId,
154
                            'user_id' => $this->Auth->user('id')
155
                        ]
156
                    );
157
                }
158
159
                $json['message'] = __d('conversations', 'Your conversation(s) has been set normal.');
160
                $json['error'] = '0';
161
                $json['redirect'] = Router::url(['action' => 'index']);
162
163
                $this->set(compact('json'));
164
                break;
165
166
            case "exit":
167
                foreach ($array as $conversationId) {
168
                    $user = $this->ConversationsUsers
169
                        ->find()
170
                        ->contain([
171
                            'Conversations'
172
                        ])
173
                        ->where([
174
                            'ConversationsUsers.user_id' => $this->Auth->user('id'),
175
                            'ConversationsUsers.conversation_id' => $conversationId
176
                        ])
177
                        ->first();
178
179
                    //Check if the user is the owner of the conversation.
180
                    if ($user->conversation->user_id == $this->Auth->user('id')) {
181
                        $conversation = $this->Conversations->get($conversationId);
182
                        $conversation->conversation_open = 2;
183
                        $this->Conversations->save($conversation);
184
                    } else {
185
                        $this->ConversationsUsers->delete($user);
186
187
                        $conversation = $this->Conversations->get($conversationId);
188
                        $conversation->recipient_count = $user->conversation->recipient_count - 1;
189
                        $this->Conversations->save($conversation);
190
                    }
191
                }
192
193
                $json['message'] = __d('conversations', 'You have left your conversation(s) successfully.');
194
                $json['error'] = '0';
195
                $json['redirect'] = Router::url(['action' => 'index']);
196
197
                $this->set(compact('json'));
198
                break;
199
200
            default:
201
                $json['message'] = __d('conversations', 'Action unknown.');
202
                $json['error'] = '1';
203
204
                $this->set(compact('json'));
205
                break;
206
        }
207
208
        $this->set('_serialize', 'json');
209
    }
210
211
    /**
212
     * Create a new conversation.
213
     *
214
     * @return void
215
     */
216
    public function create()
217
    {
218
        $this->loadModel('Conversations');
219
        $conversation = $this->Conversations->newEntity($this->request->data, ['validate' => 'create']);
220
221
        if ($this->request->is('post')) {
222
            $users = str_replace(",", "", trim(strtolower($this->request->data['users'])));
223
            $users = explode(" ", $users);
224
225
            //Check max users.
226
            if (!(count($users) <= Configure::read('Conversations.max_users_per_conversation'))) {
227
                $this->Flash->error(__d('conversations', 'You cannot invite more than {0} user(s) in this conversation.', Configure::read('Conversations.max_users_per_conversation')));
228
                $this->set(compact('conversation'));
229
230
                return;
231
            }
232
233
            $userMiniCount = false;
234
            $this->loadModel('Users');
235
236
            //We check if at least one user in all list exist.
237
            foreach ($users as $user) {
238
                $userCheck = $this->Users
239
                    ->find()
240
                    ->where([
241
                        'LOWER(Users.username)' => $user
242
                    ])
243
                    ->first();
244
245
                //If an user exist and if the user is not the own of the conversation.
246
                if ($userCheck && $userCheck->id != $this->Auth->user('id')) {
247
                    $userMiniCount = true;
248
                    break;
249
                }
250
            }
251
252
            if ($userMiniCount === false) {
253
                $this->Flash->error(__d('conversations', 'Please enter at least one valid recipient.'));
254
                $this->set(compact('conversation'));
255
256
                return;
257
            }
258
259
            $conversation->user_id = $this->Auth->user('id');
260
            $conversation->reply_count = 1;
261
            $conversation->recipient_count = 1;
262
            $conversation->last_message_user_id = $this->Auth->user('id');
263
            $conversation->last_message_date = new Time();
264
265
            if ($conversation = $this->Conversations->save($conversation)) {
266
                $this->loadModel('ConversationsMessages');
267
                $this->loadModel('ConversationsUsers');
268
269
                $data = [];
270
                $data['message'] = $this->request->data['message'];
271
                $data['conversation_id'] = $conversation->id;
272
                $data['user_id'] = $this->Auth->user('id');
273
274
                $entity = $this->ConversationsMessages->newEntity($data);
275
                $message = $this->ConversationsMessages->save($entity);
276
277
                $data = [];
278
                $data['conversation_id'] = $conversation->id;
279
                $data['user_id'] = $this->Auth->user('id');
280
281
                $entity = $this->ConversationsUsers->newEntity($data);
282
                $user = $this->ConversationsUsers->save($entity);
283
284
                $this->Conversations->updateAll(
285
                    [
286
                        'first_message_id' => $message->id,
287
                        'last_message_id' => $message->id
288
                    ],
289
                    [
290
                        'id' => $conversation->id
291
                    ]
292
                );
293
294
                //Save all invited users.
295
                foreach ($users as $user) {
296
                    $userExist = $this->Users
297
                        ->find()
298
                        ->where([
299
                            'LOWER(Users.username)' => $user
300
                        ])
301
                        ->first();
302
303
                    //If the user exist.
304
                    if (is_null($userExist)) {
305
                        break;
306
                    }
307
308
                    //Check if the user is not already in the conversation.
309
                    $conversUserCheck = $this->ConversationsUsers
310
                        ->find()
311
                        ->where([
312
                            'ConversationsUsers.conversation_id' => $conversation->id,
313
                            'ConversationsUsers.user_id' => $userExist->id
314
                        ])
315
                        ->first();
316
317
                    if (!is_null($conversUserCheck)) {
318
                        break;
319
                    }
320
321
                    $data = [];
322
                    $data['conversation_id'] = $conversation->id;
323
                    $data['user_id'] = $userExist->id;
324
325
                    $entity = $this->ConversationsUsers->newEntity($data);
326
                    $user = $this->ConversationsUsers->save($entity);
327
328
                    $expression = new QueryExpression('recipient_count = recipient_count + 1');
329
                    $this->Conversations->updateAll(
330
                        [$expression],
331
                        [
332
                            'id' => $conversation->id
333
                        ]
334
                    );
335
336
                    //Notifications Event.
337
                    $this->eventManager()->attach(new Notifications());
338
                    $event = new Event('Model.Notifications.dispatch', $this, [
339
                        'sender_id' => $this->Auth->user('id'),
340
                        'conversation_id' => $conversation->id,
341
                        'type' => 'conversation.reply'
342
                    ]);
343
                    $this->eventManager()->dispatch($event);
344
                }
345
346
                $this->Flash->success(__d('conversations', 'Your conversation has been created successfully !'));
347
                $this->redirect([
348
                    '_name' => 'conversations-view',
349
                    'slug' => $conversation->title,
350
                    'id' => $conversation->id
351
                ]);
352
            }
353
        }
354
355
        $this->set(compact('conversation'));
356
    }
357
358
    /**
359
     * Display a conversation.
360
     *
361
     * @return void|\Cake\Network\Response
362
     */
363
    public function view()
364
    {
365
        $this->loadModel('ConversationsUsers');
366
367
        $conversation = $this->ConversationsUsers
368
            ->find()
369
            ->contain([
370
                'Users',
371
                'Conversations',
372
                'Conversations.LastMessage',
373
                'Conversations.LastMessageUser'
374
            ])
375
            ->where([
376
                'ConversationsUsers.conversation_id' => $this->request->id,
377
                'ConversationsUsers.user_id' => $this->Auth->user('id'),
378
                'Conversations.conversation_open <>' => 2
379
            ])
380
            ->first();
381
382
        if (is_null($conversation)) {
383
            $this->Flash->error(__d('conversations', "This conversation doesn't exist or has been deleted."));
384
385
            return $this->redirect(['action' => 'index']);
386
        }
387
388
        $this->loadModel('ConversationsMessages');
389
390
        $this->paginate = [
391
            'maxLimit' => Configure::read('Conversations.messages_per_page')
392
        ];
393
394
        $messages = $this->ConversationsMessages
395
            ->find()
396
            ->contain([
397
                'Users' => function ($q) {
398
                    return $q->find('full')->formatResults(function ($users) {
399
                        return $users->map(function ($user) {
400
                            $user->online = $this->SessionsActivity->getOnlineStatus($user);
401
402
                            return $user;
403
                        });
404
                    });
405
                },
406
                'Users.Groups',
407
                'LastEditUsers' => function ($q) {
408
                    return $q->find('short');
409
                },
410
            ])
411
            ->where([
412
                'ConversationsMessages.conversation_id' => $this->request->id
413
            ])
414
            ->order([
415
                'ConversationsMessages.created' => 'ASC'
416
            ]);
417
418
        $messages = $this->paginate($messages);
419
420
        //Update "is_read" for the current user.
421
        $user = $this->ConversationsUsers->get($conversation->id);
422
        $user->is_read = 1;
423
        $this->ConversationsUsers->save($user);
424
425
        //Current user.
426
        $this->loadModel('Users');
427
        $currentUser = $this->Users
428
            ->find()
429
            ->contain([
430
                'Groups' => function ($q) {
431
                    return $q->select(['id', 'is_staff']);
432
                }
433
            ])
434
            ->where([
435
                'Users.id' => $this->Auth->user('id')
436
            ])
437
            ->select(['id', 'group_id'])
438
            ->first();
439
440
        //Build the newEntity for the comment form.
441
        $messageForm = $this->ConversationsMessages->newEntity();
442
443
        $this->set(compact('conversation', 'messages', 'currentUser', 'messageForm'));
444
    }
445
446
    /**
447
     * Action to search some users when adding an user in a conversation.
448
     *
449
     * @return void
450
     *
451
     * @throws \Cake\Network\Exception\NotFoundException
452
     */
453
    public function inviteMember()
454
    {
455
        if (!$this->request->is('ajax')) {
456
            throw new NotFoundException();
457
        }
458
        $keyword = strtolower($this->request->data['query']);
459
460
        $this->loadModel('Users');
461
        $users = $this->Users
462
            ->find()
463
            ->where(function ($q) use ($keyword) {
464
                    return $q
465
                        ->like('LOWER(Users.username)', "%$keyword%");
466
            })
467
            ->limit(12)
468
            ->toArray();
469
470
        foreach ($users as $user) {
471
            $json[] = h($user->username);
472
        }
473
474
        $this->set(compact('json'));
475
        $this->set('_serialize', 'json');
476
    }
477
478
    /**
479
     * Quote a post.
480
     *
481
     * @throws \Cake\Network\Exception\NotFoundException
482
     *
483
     * @return mixed
484
     */
485
    public function quote()
486
    {
487
        if (!$this->request->is('ajax')) {
488
            throw new NotFoundException();
489
        }
490
491
        $this->loadModel('ConversationsMessages');
492
493
        $message = $this->ConversationsMessages
494
            ->find()
495
            ->where([
496
                'ConversationsMessages.id' => $this->request->id
497
            ])
498
            ->contain([
499
                'Users' => function ($q) {
500
                        return $q->find('short');
501
                }
502
            ])
503
            ->first();
504
505
        $json = [];
506
507
        if (!is_null($message)) {
508
            $message->toArray();
509
510
            $url = Router::url(['action' => 'go', $message->id]);
511
            $text = __d('conversations', 'has said :');
512
513
            //Build the quote.
514
            $json['message'] = <<<EOT
515
<div>
516
    <div>
517
        <a href="{$url}">
518
            <strong>{$message->user->full_name} {$text}</strong>
519
        </a>
520
    </div>
521
    <blockquote>
522
        $message->message
523
    </blockquote>
524
</div><p>&nbsp;</p><p>&nbsp;</p>
525
EOT;
526
527
            $json['error'] = false;
528
529
            $this->set(compact('json'));
530
        } else {
531
            $json['post'] = __d('conversations', "This message doesn't exist.");
532
            $json['error'] = true;
533
534
            $this->set(compact('json'));
535
        }
536
537
        //Send response in JSON.
538
        $this->set('_serialize', 'json');
539
    }
540
541
    /**
542
     * Get the form to edit a message.
543
     *
544
     * @throws \Cake\Network\Exception\NotFoundException When it's not an AJAX request.
545
     *
546
     * @return void
547
     */
548
    public function getEditMessage()
549
    {
550
        if (!$this->request->is('ajax')) {
551
            throw new NotFoundException();
552
        }
553
554
        $this->loadModel('ConversationsMessages');
555
        $this->viewBuilder()->layout(false);
556
557
        $message = $this->ConversationsMessages
558
            ->find()
559
            ->where([
560
                'ConversationsMessages.id' => $this->request->data['id']
561
            ])
562
            ->first();
563
564
        $json = [
565
            'error' => false,
566
            'errorMessage' => ''
567
        ];
568
569
        if (is_null($message)) {
570
            $json['error'] = true;
571
            $json['errorMessage'] = __d('conversations', "This message doesn't exist or has been deleted !");
572
573
            $this->set(compact('json'));
574
575
            return;
576
        }
577
578
        //Current user.
579
        $this->loadModel('Users');
580
        $currentUser = $this->Users
581
            ->find()
582
            ->contain([
583
                'Groups' => function ($q) {
584
                    return $q->select(['id', 'is_staff']);
585
                }
586
            ])
587
            ->where([
588
                'Users.id' => $this->Auth->user('id')
589
            ])
590
            ->select(['id', 'group_id'])
591
            ->first();
592
593
        if ($message->user_id != $this->Auth->user('id') && !$currentUser->group->is_staff) {
594
            $json['error'] = true;
595
            $json['errorMessage'] = __d('conversations', "You don't have the authorization to edit this message !");
596
597
            $this->set(compact('json'));
598
599
            return;
600
        }
601
602
        $this->set(compact('json', 'message'));
603
    }
604
605
    /**
606
     * Edit a message.
607
     *
608
     * @param int $id Id of the message.
609
     *
610
     * @return \Cake\Network\Response
611
     */
612
    public function messageEdit($id = null)
613
    {
614
        if (!$this->request->is(['post', 'put'])) {
615
            throw new NotFoundException();
616
        }
617
618
        $this->loadModel('ConversationsMessages');
619
620
        $message = $this->ConversationsMessages
621
            ->find()
622
            ->where([
623
                'ConversationsMessages.id' => $id
624
            ])
625
            ->first();
626
627
        if (is_null($message)) {
628
            $this->Flash->error(__d('conversations', "This post doesn't exist or has been deleted !"));
629
630
            return $this->redirect($this->referer());
631
        }
632
633
        //Current user.
634
        $this->loadModel('Users');
635
        $currentUser = $this->Users
636
            ->find()
637
            ->contain([
638
                'Groups' => function ($q) {
639
                    return $q->select(['id', 'is_staff']);
640
                }
641
            ])
642
            ->where([
643
                'Users.id' => $this->Auth->user('id')
644
            ])
645
            ->select(['id', 'group_id'])
646
            ->first();
647
648
        if ($message->user_id != $this->Auth->user('id') && !$currentUser->group->is_staff) {
649
            $this->Flash->error(__d('conversations', "You don't have the authorization to edit this post !"));
650
651
            return $this->redirect($this->referer());
652
        }
653
654
        $this->ConversationsMessages->patchEntity($message, $this->request->data());
655
        $message->last_edit_date = new Time();
656
        $message->last_edit_user_id = $this->Auth->user('id');
657
        $message->edit_count++;
658
659
        if ($this->ConversationsMessages->save($message)) {
660
            $this->Flash->success(__d('conversations', 'This message has been edited successfully !'));
661
        }
662
663
        return $this->redirect(['action' => 'go', $message->id]);
664
    }
665
666
    /**
667
     * Redirect an user to a conversation, page and message.
668
     *
669
     * @param int $messageId Id of the message.
670
     *
671
     * @return \Cake\Network\Response
672
     */
673 View Code Duplication
    public function go($messageId = null)
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
674
    {
675
        $this->loadModel('ConversationsMessages');
676
677
        $message = $this->ConversationsMessages
678
            ->find()
679
            ->contain([
680
                'Conversations'
681
            ])
682
            ->where([
683
                'ConversationsMessages.id' => $messageId
684
            ])
685
            ->first();
686
687
        if (is_null($message)) {
688
            $this->Flash->error(__d('conversations', "This message doesn't exist or has been deleted."));
689
690
            return $this->redirect(['controller' => 'conversations', 'action' => 'index']);
691
        }
692
693
        $message->toArray();
694
695
        //Count the number of messages before this message.
696
        $messagesBefore = $this->ConversationsMessages
697
            ->find()
698
            ->where([
699
                'ConversationsMessages.conversation_id' => $message->conversation_id,
700
                'ConversationsMessages.created <' => $message->created
701
            ])
702
            ->count();
703
704
        //Get the number of messages per page.
705
        $messagesPerPage = Configure::read('Conversations.messages_per_page');
706
707
        //Calculate the page.
708
        $page = ceil($messagesBefore / $messagesPerPage);
709
710
        $page = ($page > 1) ? $page : 1;
711
712
        //Redirect the user.
713
        return $this->redirect([
714
            '_name' => 'conversations-view',
715
            'slug' => $message->conversation->title,
716
            'id' => $message->conversation->id,
717
            '?' => ['page' => $page],
718
            '#' => 'message-' . $messageId
719
        ]);
720
    }
721
722
    /**
723
     * Function to kick an user from a conversation.
724
     *
725
     * @return void
726
     */
727
    public function kick()
728
    {
729
        if (!$this->request->is('ajax')) {
730
            throw new NotFoundException();
731
        }
732
733
        $this->loadModel('ConversationsUsers');
734
735
        $currentUser = $this->ConversationsUsers
736
            ->find()
737
            ->contain([
738
                'Conversations',
739
                'Users' => function ($q) {
740
                    return $q->find('short');
741
                },
742
                'Users.Groups' => function ($q) {
743
                    return $q->select(['id', 'is_staff']);
744
                }
745
            ])
746
            ->where([
747
                'ConversationsUsers.user_id' => $this->Auth->user('id'),
748
                'ConversationsUsers.conversation_id' => $this->request->id
749
            ])
750
            ->first();
751
752
        //Check if the current user is the owner of this conversation or if he is not a staff member.
753
        if ($currentUser->user_id != $currentUser->conversation->user_id && !$currentUser->user->group->is_staff) {
754
            $json['message'] = __d('conversations', 'You cannot kick this user from this conversation.');
755
            $json['error'] = true;
756
757
            $this->set(compact('json'));
758
            $this->set('_serialize', 'json');
759
760
            return;
761
        }
762
763
        $user = $this->ConversationsUsers
764
            ->find()
765
            ->contain([
766
                'Conversations',
767
                'Users' => function ($q) {
768
                    return $q->find('short');
769
                },
770
                'Users.Groups' => function ($q) {
771
                    return $q->select(['id', 'is_staff']);
772
                }
773
            ])
774
            ->where([
775
                'ConversationsUsers.user_id' => $this->request->user_id,
776
                'ConversationsUsers.conversation_id' => $this->request->id
777
            ])
778
            ->first();
779
780
        //Check if the user to kick is in the conversation and if he is not owner of this conversation and if he is not a staff member.
781
        if (is_null($user) || $this->request->user_id == $currentUser->conversation->user_id || $user->user->group->is_staff) {
782
            $json['message'] = __d('conversations', 'You cannot kick this user from this conversation.');
783
            $json['error'] = true;
784
785
            $this->set(compact('json'));
786
            $this->set('_serialize', 'json');
787
788
            return;
789
        }
790
791
        $this->ConversationsUsers->delete($user);
792
793
        $expression = new QueryExpression('recipient_count = recipient_count - 1');
794
        $this->Conversations->updateAll(
795
            [$expression],
796
            [
797
                'id' => $this->request->id
798
            ]
799
        );
800
801
        $json['message'] = __d('conversations', 'This user has been kicked successfully.');
802
        $json['error'] = false;
803
        $json['id'] = $this->request->user_id;
804
        $json['recipients'] = $currentUser->conversation->recipient_count - 1;
805
806
        $this->set(compact('json'));
807
        $this->set('_serialize', 'json');
808
    }
809
810
    /**
811
     * Reply to a conversation.
812
     *
813
     * @return void|\Cake\Network\Response
814
     */
815
    public function reply()
816
    {
817
        $this->loadModel('ConversationsMessages');
818
819
        if ($this->request->is('post')) {
820
            $conversation = $this->Conversations
821
                ->find()
822
                ->where(['Conversations.id' => $this->request->id])
823
                ->first();
824
825
            $this->loadModel('ConversationsUsers');
826
            $user = $this->ConversationsUsers
827
                ->find()
828
                ->where([
829
                    'ConversationsUsers.conversation_id' => $this->request->id,
830
                    'ConversationsUsers.user_id' => $this->Auth->user('id')
831
                ])
832
                ->first();
833
834
            //Check if the conversation is found.
835
            if (is_null($user) || is_null($conversation) || $conversation->conversation_open == 2) {
836
                $this->Flash->error(__d('conversations', "This conversation doesn't exist or has been deleted !"));
837
838
                return $this->redirect($this->referer());
839
            }
840
841
            //Check if the conversation is open.
842 View Code Duplication
            if ($conversation->conversation_open == false) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
843
                $this->Flash->error(__d('conversations', 'This conversation is closed, you cannot reply.'));
844
845
                return $this->redirect($this->referer());
846
            }
847
848
            //Build the newEntity for the post form.
849
            $this->request->data['conversation']['id'] = $this->request->id;
850
            $this->request->data['conversation']['last_post_date'] = new Time();
851
            $this->request->data['conversation']['last_post_user_id'] = $this->Auth->user('id');
852
            $this->request->data['user_id'] = $this->Auth->user('id');
853
            $this->request->data['conversation_id'] = $this->request->id;
854
855
            $message = $this->ConversationsMessages->newEntity($this->request->data, [
856
                'associated' => ['Conversations'],
857
                'validate' => 'create'
858
            ]);
859
860
            //Handle validation errors (Due to the redirect)
861
            if (!empty($message->errors())) {
862
                $this->Flash->conversationsReply('Validation errors', [
863
                    'key' => 'ConversationsReply',
864
                    'params' => [
865
                        'errors' => $message->errors()
866
                    ]
867
                ]);
868
869
                return $this->redirect($this->referer());
870
            }
871
872
            if ($message->conversation->isNew() === true) {
873
                $message->conversation->isNew(false);
874
            }
875
876
            if ($message = $this->ConversationsMessages->save($message)) {
877
                //Update the last message id for the conversation.
878
                $this->loadModel('Conversations');
879
                $conversation = $this->Conversations->get($this->request->id);
880
                $conversation->last_message_id = $message->id;
881
                $conversation->last_message_date = new Time();
882
                $conversation->last_message_user_id = $this->Auth->user('id');
883
                $this->Conversations->save($conversation);
884
885
                //Notifications Event.
886
                $this->eventManager()->attach(new Notifications());
887
                $event = new Event('Model.Notifications.dispatch', $this, [
888
                    'sender_id' => $this->Auth->user('id'),
889
                    'conversation_id' => $conversation->id,
890
                    'type' => 'conversation.reply'
891
                ]);
892
                $this->eventManager()->dispatch($event);
893
894
                $conversationOpen = isset($this->request->data['conversation']['conversation_open']) ? $this->request->data['conversation']['conversation_open'] : true;
895
896
                if ($conversationOpen == false) {
897
                    $this->Flash->success(__d('conversations', 'Your reply has been posted successfully and the conversation has been closed !'));
898
                } else {
899
                    $this->Flash->success(__d('conversations', 'Your reply has been posted successfully !'));
900
                }
901
902
                //Redirect the user to the last page of the article.
903
                return $this->redirect([
904
                    'controller' => 'conversations',
905
                    'action' => 'go',
906
                    $message->id
907
                ]);
908
            }
909
        }
910
911
        $this->redirect($this->referer());
912
    }
913
914
    /**
915
     * Edit a conversation.
916
     *
917
     * @return \Cake\Network\Response
918
     */
919
    public function edit()
920
    {
921
        $this->loadModel('Conversations');
922
923
        if ($this->request->is('put')) {
924
            $conversation = $this->Conversations
925
                ->find()
926
                ->where([
927
                    'Conversations.id' => $this->request->id
928
                ])
929
                ->first();
930
931
            //Check if the conversation is found.
932 View Code Duplication
            if (is_null($conversation)) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
933
                $this->Flash->error(__d('conversations', "This conversation doesn't exist or has been deleted !"));
934
935
                return $this->redirect($this->referer());
936
            }
937
938
            //Check if the user has the permission to edit it.
939 View Code Duplication
            if ($this->Auth->isAuthorized() === false) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
940
                $this->Flash->error(__d('conversations', "You don't have the authorization to edit this conversation !"));
941
942
                return $this->redirect([
943
                    'controller' => 'conversations',
944
                    'action' => 'go',
945
                    $conversation->last_message_id
946
                ]);
947
            }
948
949
950
            $this->Conversations->patchEntity($conversation, $this->request->data, ['validate' => 'edit']);
951
952
            if ($this->Conversations->save($conversation)) {
953
                if ($conversation->conversation_open == false) {
954
                    $this->Flash->success(__d('conversations', 'Your conversation has been edited and closed successfully !'));
955
                } else {
956
                    $this->Flash->success(__d('conversations', 'Your conversation has been edited successfully !'));
957
                }
958
959
                return $this->redirect([
960
                    'controller' => 'conversations',
961
                    'action' => 'go',
962
                    $conversation->last_message_id
963
                ]);
964
            }
965
        }
966
967
        $this->redirect($this->referer());
968
    }
969
970
    /**
971
     * Function to invite user(s) in a conversation.
972
     *
973
     * @return void|\Cake\Network\Response
974
     */
975
    public function invite()
976
    {
977
        $this->loadModel('ConversationsUsers');
978
979
        $conversation = $this->ConversationsUsers
980
            ->find()
981
            ->contain([
982
                'Conversations',
983
                'Users',
984
                'Users.Groups'
985
            ])
986
            ->where([
987
                'ConversationsUsers.conversation_id' => $this->request->id,
988
                'ConversationsUsers.user_id' => $this->Auth->user('id')
989
            ])
990
            ->first();
991
992 View Code Duplication
        if (is_null($conversation) || $conversation->conversation->conversation_open != 1) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
993
            $this->Flash->error(__d('conversations', 'This conversation is closed or has been deleted !'));
994
995
            return $this->redirect($this->referer());
996
        }
997
998
        if (!$conversation->conversation->open_invite && $conversation->conversation->user_id != $this->Auth->user('id') && !$conversation->user->group->is_staff) {
999
            $this->Flash->error(__d('conversations', "You don't have the authorization to invite in this conversation !"));
1000
1001
            return $this->redirect($this->referer());
1002
        }
1003
1004
        if ($this->request->is(['post', 'put'])) {
1005
            $users = str_replace(",", "", trim(strtolower($this->request->data['users'])));
1006
            $users = explode(" ", $users);
1007
1008
            $maxUsersCheck = $this->ConversationsUsers
1009
                ->find()
1010
                ->where([
1011
                    'ConversationsUsers.conversation_id' => $this->request->id
1012
                ])
1013
                ->count();
1014
1015
            //Check max users.
1016
            if (count($users) + $maxUsersCheck >= Configure::read('Conversations.max_users_per_conversation')) {
1017
                $this->Flash->error(__d('conversations', 'You cannot invite more than {0} user(s) in this conversation.', Configure::read('Conversations.max_users_per_conversation')));
1018
1019
                return $this->redirect($this->referer());
1020
            }
1021
1022
            $this->loadModel('Users');
1023
            $this->loadModel('Conversations');
1024
1025
            foreach ($users as $user) {
1026
                $user = $this->Users
1027
                    ->find()
1028
                    ->where([
1029
                        'LOWER(Users.username)' => $user
1030
                    ])
1031
                    ->first();
1032
1033
                if (!is_null($user)) {
1034
                    $check = $this->ConversationsUsers
1035
                        ->find()
1036
                        ->where([
1037
                            'ConversationsUsers.conversation_id' => $this->request->id,
1038
                            'ConversationsUsers.user_id' => $user->id
1039
                        ])
1040
                        ->first();
1041
1042
                    if (is_null($check)) {
1043
                        $data = [];
1044
                        $data['conversation_id'] = $this->request->id;
1045
                        $data['user_id'] = $user->id;
1046
1047
                        $entity = $this->ConversationsUsers->newEntity($data);
1048
                        $this->ConversationsUsers->save($entity);
1049
1050
                        $expression = new QueryExpression('recipient_count = recipient_count + 1');
1051
                        $this->Conversations->updateAll(
1052
                            [$expression],
1053
                            [
1054
                                'id' => $this->request->id
1055
                            ]
1056
                        );
1057
                    }
1058
                }
1059
            }
1060
1061
            $this->Flash->success(__d('conversations', 'Your user(s) has been added successfully.'));
1062
        }
1063
1064
        return $this->redirect([
1065
            'controller' => 'conversations',
1066
            'action' => 'go',
1067
            $conversation->conversation->last_message_id
1068
        ]);
1069
    }
1070
1071
    /**
1072
     * Function to leave a conversation.
1073
     *
1074
     * @return void|\Cake\Network\Response
1075
     */
1076
    public function leave()
1077
    {
1078
        $this->loadModel('ConversationsUsers');
1079
1080
        $user = $this->ConversationsUsers
1081
            ->find()
1082
            ->contain([
1083
                'Conversations'
1084
            ])
1085
            ->where([
1086
                'ConversationsUsers.conversation_id' => $this->request->id,
1087
                'ConversationsUsers.user_id' => $this->Auth->user('id')
1088
            ])
1089
            ->first();
1090
1091
        if (is_null($user)) {
1092
            $this->Flash->error(__d('conversations', 'You are not in this conversation.'));
1093
1094
            return $this->redirect($this->referer());
1095
        }
1096
1097
        if ($user->conversation->user_id != $this->Auth->user('id')) {
1098
            $this->loadModel('Conversations');
1099
1100
            $this->ConversationsUsers->delete($user);
1101
1102
            $expression = new QueryExpression('recipient_count = recipient_count - 1');
1103
            $this->Conversations->updateAll(
1104
                [$expression],
1105
                [
1106
                    'id' => $this->request->id
1107
                ]
1108
            );
1109
1110
            $this->Flash->success(__d('conversations', 'You have left the conversation successfully.'));
1111
1112
            return $this->redirect(['controller' => 'conversations', 'action' => 'index']);
1113 View Code Duplication
        } else {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1114
            $this->Flash->error(__d('conversations', 'You can not leave your own conversation.'));
1115
1116
            return $this->redirect([
1117
                'controller' => 'conversations',
1118
                'action' => 'go',
1119
                $user->conversation->last_message_id
1120
            ]);
1121
        }
1122
    }
1123
1124
    /**
1125
     * Search conversations.
1126
     *
1127
     * @return void
1128
     */
1129
    public function search()
1130
    {
1131
        $this->loadModel('ConversationsUsers');
1132
1133
        //Check the keyword to search. (For pagination)
1134 View Code Duplication
        if (!empty($this->request->data['search'])) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1135
            $keyword = $this->request->data['search'];
1136
            $this->request->session()->write('Search.Conversations.Keyword', $keyword);
1137
        } else {
1138
            if ($this->request->session()->read('Search.Conversations.Keyword')) {
1139
                $keyword = $this->request->session()->read('Search.Conversations.Keyword');
1140
            } else {
1141
                $keyword = '';
1142
            }
1143
        }
1144
1145
        //Pagination
1146
        $this->paginate = [
1147
            'maxLimit' => Configure::read('Conversations.conversations_per_page')
1148
        ];
1149
1150
        $conversations = $this->ConversationsUsers
1151
            ->find()
1152
            ->contain([
1153
                'Users',
1154
                'Conversations',
1155
                'Conversations.Users' => function ($q) {
1156
                    return $q->find('medium');
1157
                },
1158
                'Conversations.LastMessage',
1159
                'Conversations.LastMessageUser'
1160
            ])
1161
            ->where([
1162
                'ConversationsUsers.user_id' => $this->Auth->user('id'),
1163
                'Conversations.conversation_open <>' => 2
1164
            ])
1165
            ->andWhere(function ($q) use ($keyword) {
1166
                    return $q
1167
                        ->like('Conversations.title', "%$keyword%");
1168
            })
1169
            ->order([
1170
                'ConversationsUsers.is_read' => 'ASC',
1171
                'ConversationsUsers.is_star' => 'DESC',
1172
                'Conversations.last_message_date' => 'DESC',
1173
            ]);
1174
1175
        $conversations = $this->paginate($conversations);
1176
1177
        $this->set(compact('conversations', 'keyword'));
1178
    }
1179
1180
    /**
1181
     * Action to rendre the maintenance page.
1182
     *
1183
     * @return void
1184
     */
1185
    public function maintenance()
1186
    {
1187
    }
1188
}
1189