Test Failed
Push — master ( e3c39f...fe570d )
by Mihail
07:20
created

CommentAnswerAdd   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 115
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 58
dl 0
loc 115
rs 10
c 0
b 0
f 0
wmc 25

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A before() 0 5 2
C check() 0 54 16
A buildRecord() 0 26 6
1
<?php
2
3
namespace Apps\Model\Api\Comments;
4
5
use Apps\ActiveRecord\CommentAnswer;
6
use Apps\ActiveRecord\CommentPost;
7
use Apps\Model\Front\Profile\EntityAddNotification;
8
use Ffcms\Core\App;
9
use Ffcms\Core\Arch\Model;
10
use Ffcms\Core\Exception\JsonException;
11
use Ffcms\Core\Helper\Date;
12
use Ffcms\Core\Helper\Text;
13
use Ffcms\Core\Helper\Type\Str;
14
15
/**
16
 * Class CommentAnswerAdd. Model to add comment answer to database and build response active record row.
17
 * @package Apps\Model\Api\Comments
18
 */
19
class CommentAnswerAdd extends Model
20
{
21
    public $message;
22
    public $replayTo = 0;
23
    public $guestName;
24
    public $ip;
25
26
    private $_configs;
27
    private $_userId = 0;
28
29
    public function __construct(array $configs)
30
    {
31
        $this->_configs = $configs;
32
        parent::__construct();
33
    }
34
35
    public function before()
36
    {
37
        $this->ip = App::$Request->getClientIp();
38
        if (App::$User->isAuth()) {
39
            $this->_userId = App::$User->identity()->getId();
40
        }
41
    }
42
43
    /**
44
     * Check if comment answer conditions is ok. Will throw exception if not.
45
     * @return bool
46
     * @throws JsonException
47
     */
48
    public function check()
49
    {
50
        // check if user is auth'd or guest name is defined
51
        if (!App::$User->isAuth() && ((int)$this->_configs['guestAdd'] !== 1 || Str::length($this->guestName) < 2)) {
52
            throw new JsonException(__('Guest name is not defined'));
53
        }
54
55
        // guest moderation
56
        if (!App::$User->isAuth() && (bool)$this->_configs['guestModerate']) {
57
            $captcha = App::$Request->request->get('captcha');
58
            if (!App::$Captcha->validate($captcha)) {
59
                throw new JsonException(__('Captcha is incorrect! Click on image to refresh and try again'));
60
            }
61
        }
62
63
        // check if replayTo is defined
64
        if ($this->replayTo < 1) {
65
            throw new JsonException(__('Comment post thread is not founded'));
66
        }
67
68
        // check if message length is correct
69
        if (Str::length($this->message) < (int)$this->_configs['minLength'] || Str::length($this->message) > (int)$this->_configs['maxLength']) {
70
            throw new JsonException(__('Message length is incorrect. Current: %cur%, min - %min%, max - %max%', [
71
                'cur' => Str::length($this->message),
72
                'min' => $this->_configs['minLength'],
73
                'max' => $this->_configs['maxLength']
74
            ]));
75
        }
76
77
        $count = CommentPost::where('id', '=', $this->replayTo)->count();
78
        if ($count !== 1) {
79
            throw new JsonException(__('Comment post thread is not founded'));
80
        }
81
82
        // check to prevent spam
83
        $query = CommentAnswer::where('user_id', $this->_userId)
84
            ->orWhere('ip', $this->ip)
85
            ->orderBy('created_at', 'DESC')
86
            ->first();
87
88
        // something is founded :D
89
        if ($query) {
90
            $isModerator = false;
91
            if (App::$User->isAuth() && App::$User->identity()->role->can('global/modify')) {
92
                $isModerator = true;
93
            }
94
            $answerTime = Date::convertToTimestamp($query->created_at);
0 ignored issues
show
Bug introduced by zenn
$query->created_at of type DateTime is incompatible with the type string expected by parameter $date of Ffcms\Core\Helper\Date::convertToTimestamp(). ( Ignorable by Annotation )

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

94
            $answerTime = Date::convertToTimestamp(/** @scrutinizer ignore-type */ $query->created_at);
Loading history...
95
            $delay = $answerTime + $this->_configs['delay'] - time();
96
            if ($delay > 0 && !$isModerator) { // sounds like config time is not passed now
97
                throw new JsonException(__('Spam protection: please, wait %sec% seconds', ['sec' => $delay]));
98
            }
99
        }
100
101
        return true;
102
    }
103
104
    /**
105
     * Add comment answer to database and return active record object
106
     * @return CommentAnswer
107
     */
108
    public function buildRecord()
109
    {
110
        $record = new CommentAnswer();
111
        $record->comment_id = $this->replayTo;
112
        $record->user_id = $this->_userId;
113
        $record->guest_name = $this->guestName;
114
        $record->message = $this->message;
115
        $record->lang = App::$Request->getLanguage();
116
        $record->ip = $this->ip;
117
        // check if premoderation is enabled and user is guest
118
        if ((bool)$this->_configs['guestModerate'] && $this->_userId < 1) {
119
            $record->moderate = 1;
0 ignored issues
show
Documentation Bug introduced by zenn
The property $moderate was declared of type boolean, but 1 is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
120
        }
121
        $record->save();
122
123
        // add notification for comment post owner
124
        $commentPost = $record->post;
125
        if ($commentPost !== null && (int)$commentPost->user_id !== 0 && (int)$commentPost->user_id !== $this->_userId) {
126
            $notify = new EntityAddNotification((int)$commentPost->user_id);
0 ignored issues
show
Bug introduced by zenn
(int)$commentPost->user_id of type integer is incompatible with the type boolean expected by parameter $targetId of Apps\Model\Front\Profile...fication::__construct(). ( Ignorable by Annotation )

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

126
            $notify = new EntityAddNotification(/** @scrutinizer ignore-type */ (int)$commentPost->user_id);
Loading history...
127
            $notify->add($commentPost->pathway, EntityAddNotification::MSG_ADD_COMMENTANSWER, [
0 ignored issues
show
Bug introduced by zenn
The property pathway does not seem to exist on Apps\ActiveRecord\CommentPost. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
128
                'snippet' => Text::snippet($this->message, 50),
129
                'post' => Text::snippet($commentPost->message, 50)
130
            ]);
131
        }
132
133
        return $record;
134
    }
135
}
136