Passed
Push — master ( 89df9c...7f6cde )
by Mihail
04:52
created

Profile   F

Complexity

Total Complexity 79

Size/Duplication

Total Lines 536
Duplicated Lines 5.6 %

Coupling/Cohesion

Components 1
Dependencies 23

Importance

Changes 14
Bugs 4 Features 0
Metric Value
c 14
b 4
f 0
dl 30
loc 536
rs 1.5492
wmc 79
lcom 1
cbo 23

9 Methods

Rating   Name   Duplication   Size   Complexity  
B actionWallanswercount() 0 28 5
C actionShowwallanswers() 0 38 8
C actionSendwallanswer() 0 67 12
C actionDeleteanswerowner() 0 37 8
C actionListmessagedialog() 0 68 13
B actionNotifications() 0 26 2
D actionMessageList() 27 96 13
B actionMessagesend() 0 31 6
C actionChangerating() 3 66 12

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Profile often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Profile, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Apps\Controller\Api;
4
5
use Apps\ActiveRecord\Blacklist;
6
use Apps\ActiveRecord\Message;
7
use Apps\ActiveRecord\ProfileRating;
8
use Apps\ActiveRecord\UserNotification;
9
use Apps\ActiveRecord\WallAnswer;
10
use Apps\ActiveRecord\WallPost;
11
use Apps\Model\Front\Profile\EntityAddNotification;
12
use Extend\Core\Arch\ApiController;
13
use Ffcms\Core\App;
14
use Ffcms\Core\Helper\Text;
15
use Ffcms\Core\Helper\Type\Arr;
16
use Ffcms\Core\Helper\Date;
17
use Ffcms\Core\Helper\Type\Obj;
18
use Ffcms\Core\Helper\Type\Str;
19
use Ffcms\Core\Interfaces\iUser;
20
use Illuminate\Database\Capsule\Manager as Capsule;
21
use Ffcms\Core\Exception\NativeException;
22
use Ffcms\Core\Exception\ForbiddenException;
23
use Ffcms\Core\Exception\NotFoundException;
24
25
class Profile extends ApiController
26
{
27
    const ITEM_PER_PAGE = 10;
28
    const ANSWER_DELAY = 60; // in seconds
29
30
    const MSG_USER_LIST = 10;
31
    const MSG_TEXT_LIST = 20;
32
33
    /**
34
     * Get wall answer's count by post-ids list
35
     * @param int $postIds
36
     * @throws NativeException
37
     * @return string
38
     */
39
    public function actionWallanswercount($postIds)
40
    {
41
        // set header
42
        $this->setJsonHeader();
43
        // check query length
44
        if (Str::likeEmpty($postIds)) {
45
            throw new NativeException('Wrong input count');
46
        }
47
48
        $list = explode(',', $postIds);
49
        $itemCount = count($list);
50
        // empty or is biggest then limit?
51
        if ($itemCount < 1 || $itemCount > self::ITEM_PER_PAGE) {
52
            throw new NativeException('Wrong input count');
53
        }
54
55
        // prepare response
56
        $response = [];
57
        foreach ($list as $post) {
58
            $response[$post] = WallAnswer::where('post_id', '=', $post)->count();
59
        }
60
61
        // display json data
62
        return json_encode([
63
            'status' => 1,
64
            'data' => $response
65
        ]);
66
    }
67
68
    /**
69
     * Show all answers for this post id
70
     * @param int $postId
71
     * @return string
72
     * @throws NativeException
73
     * @return string
74
     */
75
    public function actionShowwallanswers($postId)
76
    {
77
        // check input post id num
78
        if (!Obj::isLikeInt($postId) || $postId < 1) {
79
            throw new NativeException('Wrong input data');
80
        }
81
82
        // try to find this post
83
        $object = WallPost::find($postId);
84
85
        if ($object === null || $object === false) {
86
            throw new NativeException('Wrong input data');
87
        }
88
89
        $result = $object->getAnswer()->orderBy('id', 'DESC')->take(200)->get();
90
        $response = [];
91
92
        foreach ($result as $answer) {
93
            // get user object and profile
94
            $user = $answer->getUser();
95
            $profile = $user->getProfile();
96
            // check if user exist
97
            if ($user === null || $user->id < 1) {
98
                continue;
99
            }
100
            // generate response array
101
            $response[] = [
102
                'answer_id' => $answer->id,
103
                'user_id' => $answer->user_id,
104
                'user_nick' => App::$Security->strip_tags($profile->getNickname()),
105
                'user_avatar' => $profile->getAvatarUrl('small'),
106
                'answer_message' => App::$Security->strip_tags($answer->message),
107
                'answer_date' => Date::humanize($answer->created_at)
108
            ];
109
        }
110
111
        return json_encode(['status' => 1, 'data' => $response]);
112
    }
113
114
    /**
115
     * Add new post answer from AJAX post
116
     * @param int $postId
117
     * @return string
118
     * @throws ForbiddenException
119
     * @throws NativeException
120
     */
121
    public function actionSendwallanswer($postId)
122
    {
123
        // not auth? what are you doing there? ;)
124
        if (!App::$User->isAuth()) {
125
            throw new ForbiddenException('Auth required');
126
        }
127
128
        // no post id? wtf you doing man!
129
        if (!Obj::isLikeInt($postId) || $postId < 1) {
130
            throw new NativeException('Wrong input data');
131
        }
132
133
        // get current(sender) user object
134
        $viewer = App::$User->identity();
135
136
        // get message from post and validate minlength
137
        $message = App::$Request->get('message');
138
        $message = App::$Security->strip_tags($message);
139
        if (!Obj::isString($message) || Str::length($message) < 3) {
0 ignored issues
show
Bug introduced by
It seems like $message defined by \Ffcms\Core\App::$Security->strip_tags($message) on line 138 can also be of type array; however, Ffcms\Core\Helper\Type\Str::length() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
140
            throw new ForbiddenException('Wrong input data');
141
        }
142
143
        // try to find this post
144
        $wallPost = WallPost::where('id', '=', $postId);
145
        if ($wallPost->count() < 1) {
146
            throw new NativeException('Wrong input data');
147
        }
148
149
        $wallRow = $wallPost->first();
150
        $target_id = $wallRow->target_id;
151
        // check if in blacklist
152
        if (!Blacklist::check($viewer->id, $target_id)) {
0 ignored issues
show
Bug introduced by
Accessing id on the interface Ffcms\Core\Interfaces\iUser suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
153
            throw new ForbiddenException('User is blocked!');
154
        }
155
156
        // check delay between user last post and current
157
        $lastAnswer = WallAnswer::where('user_id', '=', App::$User->identity()->getId())->orderBy('created_at', 'DESC')->first();
158
        if (null !== $lastAnswer && false !== $lastAnswer) {
159
            $now = time();
160
            $answerTime = Date::convertToTimestamp($lastAnswer->created_at);
161
            $cfgs = \Apps\ActiveRecord\App::getConfigs('app', 'Profile');
162
            // hmm, maybe past less then delay required?
163
            if ($now - (int)$cfgs['delayBetweenPost'] < $answerTime) {
164
                throw new ForbiddenException('Delay between answers not pass');
165
            }
166
        }
167
168
        // make new row ;)
169
        $answers = new WallAnswer();
170
        $answers->post_id = $postId;
171
        $answers->user_id = $viewer->id;
0 ignored issues
show
Bug introduced by
Accessing id on the interface Ffcms\Core\Interfaces\iUser suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
172
        $answers->message = $message;
173
        $answers->save();
174
175
        // add notification for target user
176
        if ($viewer->id !== $target_id) {
0 ignored issues
show
Bug introduced by
Accessing id on the interface Ffcms\Core\Interfaces\iUser suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
177
            $notify = new EntityAddNotification($target_id);
178
            $notify->add('/profile/show/' . $target_id . '#wall-post-' . $wallRow->id, EntityAddNotification::MSG_ADD_WALLANSWER, [
179
                'snippet' => Text::snippet($message, 50),
0 ignored issues
show
Bug introduced by
It seems like $message defined by \Ffcms\Core\App::$Security->strip_tags($message) on line 138 can also be of type array; however, Ffcms\Core\Helper\Text::snippet() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
180
                'post' => $wallRow->message
181
            ]);
182
        }
183
184
        // send "ok" response
185
        $this->setJsonHeader();
186
        return json_encode(['status' => 1, 'message' => 'ok']);
187
    }
188
189
    /**
190
     * Delete answer by answer owner or wall owner
191
     * @param $answerId
192
     * @return string
193
     * @throws ForbiddenException
194
     * @throws NativeException
195
     * @throws NotFoundException
196
     */
197
    public function actionDeleteanswerowner($answerId)
198
    {
199
        $this->setJsonHeader();
200
        // hello script kiddy, you must be auth ;)
201
        if (!App::$User->isAuth()) {
202
            throw new ForbiddenException('Auth required');
203
        }
204
        // answer id must be an unsigned integer
205
        if (!Obj::isLikeInt($answerId) || $answerId < 1) {
206
            throw new NativeException('Wrong input data');
207
        }
208
209
        $findAnswer = WallAnswer::find($answerId);
210
211
        // check if this answer id exist
212
        if (null === $findAnswer || false === $findAnswer) {
213
            throw new NotFoundException('Wrong input data');
214
        }
215
216
        // get current viewer
217
        $viewer = App::$User->identity();
218
        // get post info
219
        $postInfo = $findAnswer->getWallPost();
220
221
        // if not a target user of answer and not answer owner - lets throw exception
222
        if($postInfo->target_id !== $viewer->id && $findAnswer->user_id !== $viewer->id) {
0 ignored issues
show
Bug introduced by
Accessing id on the interface Ffcms\Core\Interfaces\iUser suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
223
            throw new ForbiddenException('Access declined!');
224
        }
225
226
        // all is ok, lets remove this answer ;)
227
        $findAnswer->delete();
228
229
        return json_encode([
230
           'status' => 1,
231
            'message' => 'ok'
232
        ]);
233
    }
234
235
    /**
236
     * Load user dialog list based on offset
237
     * @param int $offset
238
     * @param int $new
239
     * @return string
240
     * @throws ForbiddenException
241
     */
242
    public function actionListmessagedialog($offset = 0, $new = 0)
243
    {
244
        // check is user auth
245
        if (!App::$User->isAuth()) {
246
            throw new ForbiddenException('Auth required');
247
        }
248
        $this->setJsonHeader();
249
250
        // check is offset is int
251
        if ($offset !== 0 && !Obj::isLikeInt($offset)) {
252
            $offset = 0;
253
        }
254
        ++$offset;
255
256
        // get user person
257
        $user = App::$User->identity();
258
259
        $records = Message::select('*', Capsule::raw('max(created_at) as cmax'), Capsule::raw('min(readed) as tread'))
260
            ->where('target_id', '=', $user->id)
0 ignored issues
show
Bug introduced by
Accessing id on the interface Ffcms\Core\Interfaces\iUser suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
261
            ->orWhere('sender_id', '=', $user->id)
0 ignored issues
show
Bug introduced by
Accessing id on the interface Ffcms\Core\Interfaces\iUser suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
262
            ->orderBy('cmax', 'DESC')
263
            ->groupBy(['target_id', 'sender_id']) // group by ignore orderBy ... make some shit
264
            ->take($offset * self::MSG_USER_LIST)
265
            ->get();
266
267
        $userList = [];
268
        $unreadList = [];
269
270
        if (Obj::isLikeInt($new) && $new > 0 && App::$User->isExist($new)) {
271
            $userList[] = $new;
272
        }
273
        // there is 2 way of messages: me->user; user->me, try to parse it
274
        foreach ($records as $row) {
275
            // target is not myself? then i'm - sender (remote user is target: my->to_user)
276
            if ($row->target_id !== $user->id) {
0 ignored issues
show
Bug introduced by
Accessing id on the interface Ffcms\Core\Interfaces\iUser suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
277
                $userList[] = $row->target_id;
278
            }
279
280
            // sender is not myself? then i'm - target (remote user is sender user->to_me)
281
            if ($row->sender_id !== $user->id) {
0 ignored issues
show
Bug introduced by
Accessing id on the interface Ffcms\Core\Interfaces\iUser suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
282
                $userList[] = $row->sender_id;
283
                if ((int)$row->tread === 0) {
284
                    $unreadList[] = $row->sender_id;
285
                }
286
            }
287
        }
288
289
        // store only unique users in dialog
290
        $userList = array_unique($userList, SORT_NUMERIC);
291
        // generate json response based on userList and unreadList
292
        $response = [];
293
        foreach ($userList as $user_id) {
294
            $identity = App::$User->identity($user_id);
295
            if (null === $identity) {
296
                continue;
297
            }
298
299
            $response[] = [
300
                'user_id' => $user_id,
301
                'user_nick' => App::$Security->strip_tags($identity->getProfile()->getNickname()),
302
                'user_avatar' => $identity->getProfile()->getAvatarUrl('small'),
303
                'message_new' => Arr::in($user_id, $unreadList),
304
                'user_block' => !Blacklist::check($user->id, $identity->id)
0 ignored issues
show
Bug introduced by
Accessing id on the interface Ffcms\Core\Interfaces\iUser suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
305
            ];
306
        }
307
308
        return json_encode(['status' => 1, 'data' => $response]);
309
    }
310
311
    /**
312
     * Get user p.m and notifications count
313
     * @return string
314
     * @throws ForbiddenException
315
     */
316
    public function actionNotifications()
317
    {
318
        // check if authed
319
        if (!App::$User->isAuth()) {
320
            throw new ForbiddenException('Auth required');
321
        }
322
        $this->setJsonHeader();
323
324
        // get user object
325
        $user = App::$User->identity();
326
327
        // get messages count
328
        $messagesCount = Message::where('target_id', '=', $user->id)
0 ignored issues
show
Bug introduced by
Accessing id on the interface Ffcms\Core\Interfaces\iUser suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
329
            ->where('readed', '=', 0)->count();
330
331
        // get notifications count
332
        $notificationsCount = UserNotification::where('user_id', '=', $user->id)
0 ignored issues
show
Bug introduced by
Accessing id on the interface Ffcms\Core\Interfaces\iUser suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
333
            ->where('readed', '=', 0)->count();
334
335
        return json_encode([
336
            'status' => 1,
337
            'notify' => $notificationsCount,
338
            'messages' => $messagesCount,
339
            'summary' => $notificationsCount + $messagesCount
340
        ]);
341
    }
342
343
    /**
344
     * List messages with correspondent
345
     * @param $cor_id
346
     * @return string
347
     * @throws ForbiddenException
348
     * @throws NotFoundException
349
     * @throws NativeException
350
     */
351
    public function actionMessageList($cor_id)
352
    {
353
        if (!App::$User->isAuth()) {
354
            throw new ForbiddenException('Auth required');
355
        }
356
357
        if (!Obj::isLikeInt($cor_id) || $cor_id < 1) {
358
            throw new NotFoundException('Corresponded id is wrong');
359
        }
360
361
        // get special types for this action
362
        $queryType = App::$Request->get('type');
363
        $queryId = (int)App::$Request->get('id');
364
        // get current user object
365
        $user = App::$User->identity();
366
367 View Code Duplication
        if (Arr::in($queryType, ['before', 'after']) && (!Obj::isLikeInt($queryId) || $queryId < 1)) {
0 ignored issues
show
Duplication introduced by
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...
368
            throw new NativeException('Bad input data');
369
        }
370
371
        $messages = null;
0 ignored issues
show
Unused Code introduced by
$messages is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
372
        // sounds like a Hindi code, but we need more closures to organize where conditions
373
        // after raw: select * from `ffcms_messages` where `id` > ? and ((`target_id` = ? and `sender_id` = ?) or (`target_id` = ? and `sender_id` = ?)) order by `created_at` desc
0 ignored issues
show
Unused Code Comprehensibility introduced by
37% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
374
        // before raw: select * from `ffcms_messages` where (`target_id` = ? and `sender_id` = ?) or (`target_id` = ? and `sender_id` = ?) order by `created_at` desc
375
        // default raw: select * from `ffcms_messages` where `id` < ? and ((`target_id` = ? and `sender_id` = ?) or (`target_id` = ? and `sender_id` = ?)) order by `created_at` desc
0 ignored issues
show
Unused Code Comprehensibility introduced by
38% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
376
        switch ($queryType) {
377 View Code Duplication
            case 'after':
0 ignored issues
show
Duplication introduced by
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...
378
                $messages = Message::where('id', '>', $queryId)
379
                    ->where(function ($query) use ($cor_id, $user) {
380
                        $query->where(function ($q) use ($cor_id, $user){
381
                            $q->where('target_id', '=', $user->getId())
382
                                ->where('sender_id', '=', $cor_id);
383
                        })->orWhere(function ($q) use ($cor_id, $user){
384
                            $q->where('target_id', '=', $cor_id)
385
                                ->where('sender_id', '=', $user->getId());
386
                        });
387
                    });
388
                break;
389 View Code Duplication
            case 'before':
0 ignored issues
show
Duplication introduced by
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...
390
                $messages = Message::where('id', '<', $queryId)
391
                    ->where(function ($query) use ($cor_id, $user) {
392
                        $query->where(function ($q) use ($cor_id, $user){
393
                            $q->where('target_id', '=', $user->getId())
394
                                ->where('sender_id', '=', $cor_id);
395
                        })->orWhere(function ($q) use ($cor_id, $user){
396
                            $q->where('target_id', '=', $cor_id)
397
                                ->where('sender_id', '=', $user->getId());
398
                        });
399
                    });
400
                break;
401
            default:
402
                $messages = Message::where(function($query) use ($cor_id, $user) {
403
                    $query->where('target_id', '=', $user->getId())
404
                        ->where('sender_id', '=', $cor_id);
405
                })->orWhere(function($query) use ($cor_id, $user) {
406
                    $query->where('target_id', '=', $cor_id)
407
                        ->where('sender_id', '=', $user->getId());
408
                });
409
                break;
410
        }
411
412
        // set response header
413
        $this->setJsonHeader();
414
415
        $messages->orderBy('created_at', 'DESC')
416
            ->take(self::MSG_TEXT_LIST);
417
418
        // check if messages exist
419
        if ($messages->count() < 1) {
420
            return json_encode(['status' => 0, 'text' => 'No messages']);
421
            return;
0 ignored issues
show
Unused Code introduced by
return; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
422
        }
423
424
        // build response
425
        $response = null;
426
        foreach ($messages->get() as $msg) {
427
            $response[] = [
428
                'id' => $msg->id,
429
                'my' => $msg->sender_id === $user->id,
0 ignored issues
show
Bug introduced by
Accessing id on the interface Ffcms\Core\Interfaces\iUser suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
430
                'message' => App::$Security->strip_tags($msg->message),
431
                'date' => Date::convertToDatetime($msg->created_at, Date::FORMAT_TO_SECONDS),
432
                'readed' => $msg->readed
433
            ];
434
            // update status to readed
435
            if ($msg->readed !== 1 && $msg->sender_id !== $user->id) {
0 ignored issues
show
Bug introduced by
Accessing id on the interface Ffcms\Core\Interfaces\iUser suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
436
                $msg->readed = 1;
437
                $msg->save();
438
            }
439
        }
440
441
        return json_encode([
442
            'status' => 1,
443
            'data' => array_reverse($response),
444
            'blocked' => !Blacklist::check($user->id, $cor_id)
0 ignored issues
show
Bug introduced by
Accessing id on the interface Ffcms\Core\Interfaces\iUser suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
445
        ]);
446
    }
447
448
    /**
449
     * Send message via AJAX
450
     * @param $target_id
451
     * @return string
452
     * @throws ForbiddenException
453
     * @throws NativeException
454
     */
455
    public function actionMessagesend($target_id)
456
    {
457
        // check if user is auth
458
        if (!App::$User->isAuth()) {
459
            throw new ForbiddenException('Auth required');
460
        }
461
462
        // get current user object
463
        $user = App::$User->identity();
464
465
        if (!Blacklist::check($user->id, $target_id)) {
0 ignored issues
show
Bug introduced by
Accessing id on the interface Ffcms\Core\Interfaces\iUser suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
466
            throw new ForbiddenException('In blacklist');
467
        }
468
469
        // check input params
470
        $msg = App::$Security->strip_tags(App::$Request->get('message'));
471
        if (!Obj::isLikeInt($target_id) || $target_id < 1 || Str::length($msg) < 1) {
0 ignored issues
show
Bug introduced by
It seems like $msg defined by \Ffcms\Core\App::$Securi...equest->get('message')) on line 470 can also be of type array; however, Ffcms\Core\Helper\Type\Str::length() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
472
            throw new NativeException('Wrong input data');
473
        }
474
475
        $this->setJsonHeader();
476
477
        // try to save message
478
        $message = new Message();
479
        $message->target_id = $target_id;
480
        $message->sender_id = $user->id;
0 ignored issues
show
Bug introduced by
Accessing id on the interface Ffcms\Core\Interfaces\iUser suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
481
        $message->message = $msg;
482
        $message->save();
483
484
        return json_encode(['status' => 1]);
485
    }
486
487
    /**
488
     * Change user rating action
489
     * @throws ForbiddenException
490
     * @throws NativeException
491
     * @throws NotFoundException
492
     * @return string
493
     */
494
    public function actionChangerating()
495
    {
496
        if (!App::$User->isAuth()) {
497
            throw new ForbiddenException('Auth required');
498
        }
499
500
        $this->setJsonHeader();
501
502
        // get operation type and target user id
503
        $target_id = (int)App::$Request->get('target');
504
        $type = App::$Request->get('type');
505
506
        // check type of query
507
        if ($type !== '+' && $type !== '-') {
508
            throw new NativeException('Wrong data');
509
        }
510
511
        // check if passed user id is exist
512 View Code Duplication
        if (!Obj::isLikeInt($target_id) || $target_id < 1 || !App::$User->isExist($target_id)) {
0 ignored issues
show
Duplication introduced by
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...
513
            throw new NotFoundException('Wrong user info');
514
        }
515
516
        $cfg = \Apps\ActiveRecord\App::getConfigs('app', 'Profile');
517
        // check if rating is enabled for website
518
        if ((int)$cfg['rating'] !== 1) {
519
            throw new NativeException('Rating is disabled');
520
        }
521
522
        // get target and sender objects
523
        $target = App::$User->identity($target_id);
524
        $sender = App::$User->identity();
525
526
        // disable self-based changes ;)
527
        if ($target->getId() === $sender->getId()) {
528
            throw new ForbiddenException('Self change prevented');
529
        }
530
531
        // check delay
532
        $diff = Date::convertToTimestamp(time() - $cfg['ratingDelay'], Date::FORMAT_SQL_TIMESTAMP);
0 ignored issues
show
Unused Code introduced by
The call to Date::convertToTimestamp() has too many arguments starting with \Ffcms\Core\Helper\Date::FORMAT_SQL_TIMESTAMP.

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.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
533
534
        $query = ProfileRating::where('target_id', '=', $target->getId())
535
            ->where('sender_id', '=', $sender->getId())
536
            ->where('created_at', '>=', $diff)
537
            ->orderBy('id', 'DESC');
538
        if ($query !== null && $query->count() > 0) {
539
            throw new ForbiddenException('Delay required');
540
        }
541
542
        // delay is ok, lets insert a row
543
        $record = new ProfileRating();
544
        $record->target_id = $target->getId();
545
        $record->sender_id = $sender->getId();
546
        $record->type = $type;
547
        $record->save();
548
549
        // update target profile
550
        $profile = $target->getProfile();
551
        if ($type === '+') {
552
            $profile->rating += 1;
553
        } else {
554
            $profile->rating -= 1;
555
        }
556
        $profile->save();
557
558
        return json_encode(['status' => 1, 'data' => 'ok']);
559
    }
560
}