GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — master ( c28c6c...173d59 )
by Steeven
02:19
created

Restful::unpublish()   A

Complexity

Conditions 5
Paths 9

Size

Total Lines 21
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 13
c 1
b 0
f 0
nc 9
nop 0
dl 0
loc 21
rs 9.5222
1
<?php
2
/**
3
 * This file is part of the O2System Framework package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 *
8
 * @author         Steeve Andrian Salim
9
 * @copyright      Copyright (c) Steeve Andrian Salim
10
 */
11
12
// ------------------------------------------------------------------------
13
14
namespace O2System\Framework\Http\Controllers;
15
16
// ------------------------------------------------------------------------
17
18
use O2System\Cache\Item;
19
use O2System\Framework\Http\Controller;
20
use O2System\Framework\Models\Sql\Model;
21
use O2System\Psr\Http\Header\ResponseFieldInterface;
22
use O2System\Security\Filters\Rules;
23
use O2System\Spl\Exceptions\Logic\OutOfRangeException;
24
25
/**
26
 * Class Restful
27
 *
28
 * @package O2System\Framework\Http\Controllers
29
 */
30
class Restful extends Controller
31
{
32
    /**
33
     * Push headers flag
34
     *
35
     * Used for push default headers by controller.
36
     * Set to FALSE if you want to set default headers on the web-server configuration.
37
     *
38
     * APACHE via .htaccess
39
     * IIS via .webconfig
40
     * Nginx via config
41
     *
42
     * @type string
43
     */
44
    protected $pushDefaultHeaders = false;
45
46
    /**
47
     * Access-Control-Allow-Origin
48
     *
49
     * Used for indicates whether a resource can be shared based by
50
     * returning the value of the Origin request header, "*", or "null" in the response.
51
     *
52
     * @type string
53
     */
54
    protected $accessControlAllowOrigin = '*';
55
56
    /**
57
     * Access-Control-Allow-Credentials
58
     *
59
     * Used for indicates whether the response to request can be exposed when the omit credentials flag is unset.
60
     * When part of the response to a preflight request it indicates that the actual request can include user
61
     * credentials.
62
     *
63
     * @type bool
64
     */
65
    protected $accessControlAllowCredentials = true;
66
67
    /**
68
     * Access-Control-Method
69
     *
70
     * @var string
71
     */
72
    protected $accessControlMethod = 'GET';
73
74
    /**
75
     * Access-Control-Params
76
     *
77
     * @var array
78
     */
79
    protected $accessControlParams = [];
80
81
    /**
82
     * Access-Control-Allow-Methods
83
     *
84
     * Used for indicates, as part of the response to a preflight request,
85
     * which methods can be used during the actual request.
86
     *
87
     * @type array
88
     */
89
    protected $accessControlAllowMethods = [
90
        'GET', // common request
91
        'POST', // used for create, update request
92
        //'PUT', // used for upload files request
93
        //'DELETE', // used for delete request
94
        'OPTIONS', // used for preflight request
95
    ];
96
97
    /**
98
     * Access-Control-Allow-Headers
99
     *
100
     * Used for indicates, as part of the response to a preflight request,
101
     * which header field names can be used during the actual request.
102
     *
103
     * @type int
104
     */
105
    protected $accessControlAllowHeaders = [
106
        'Origin',
107
        'Access-Control-Request-Method',
108
        'Access-Control-Request-Headers',
109
        'X-Api-Authenticate', // API-Authenticate: api_key="xxx", api_secret="xxx", api_signature="xxx"
110
        'X-Api-Token',
111
        'X-Web-Token', // X-Web-Token: xxx (json-web-token)
112
        'X-Csrf-Token',
113
        'X-Xss-Token',
114
        'X-Request-ID',
115
        'X-Requested-With',
116
        'X-Requested-Result',
117
    ];
118
119
    /**
120
     * Access-Control-Allow-Headers
121
     *
122
     * Used for indicates, as part of the response to a preflight request,
123
     * which header field names can be used during the actual request.
124
     *
125
     * @type array
126
     */
127
    protected $accessControlAllowContentTypes = [
128
        'text/html',
129
        'application/json',
130
        'application/xml',
131
    ];
132
133
    /**
134
     * Access-Control-Max-Age
135
     *
136
     * Used for indicates how long the results of a preflight request can be cached in a preflight result cache
137
     *
138
     * @type int
139
     */
140
    protected $accessControlMaxAge = 86400;
141
142
    /**
143
     * Restful::$ajaxOnly
144
     *
145
     * @var bool
146
     */
147
    protected $ajaxOnly = false;
148
149
    /**
150
     * Restful::$model
151
     *
152
     * @var \O2System\Framework\Models\Sql\Model|\O2System\Framework\Models\NoSql\Model|\O2System\Framework\Models\Files\Model
153
     */
154
    public $model;
155
156
    /**
157
     * Restful::$params
158
     *
159
     * @var array
160
     */
161
    public $params = [];
162
163
    /**
164
     * Restful::$fillableColumns
165
     *
166
     * @var array
167
     */
168
    public $fillableColumns = [];
169
170
    /**
171
     * Restful::$fillableColumnsWithRules
172
     *
173
     * @var array
174
     */
175
    public $fillableColumnsWithRules = [];
176
177
    // ------------------------------------------------------------------------
178
179
    /**
180
     * Restful::__construct
181
     */
182
    public function __construct()
183
    {
184
        if (services()->has('presenter')) {
185
            presenter()->setTheme(false);
0 ignored issues
show
Bug introduced by
false of type false is incompatible with the type string expected by parameter $theme of O2System\Framework\Http\Presenter::setTheme(). ( Ignorable by Annotation )

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

185
            presenter()->setTheme(/** @scrutinizer ignore-type */ false);
Loading history...
186
        }
187
188
        if (is_ajax()) {
189
            output()->setContentType('application/json');
0 ignored issues
show
Bug introduced by
The method setContentType() does not exist on O2System\Kernel\Cli\Output. ( Ignorable by Annotation )

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

189
            output()->/** @scrutinizer ignore-call */ setContentType('application/json');

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
190
        } elseif ($this->ajaxOnly === false) {
191
            output()->setContentType('application/json');
192
        } else {
193
            output()->setContentType('text/html');
194
        }
195
196
        if ($contentType = input()->server('HTTP_X_REQUESTED_CONTENT_TYPE')) {
197
            if (in_array($contentType, $this->accessControlAllowContentTypes)) {
198
                output()->setContentType($contentType);
199
            }
200
        }
201
202
        if ($this->pushDefaultHeaders) {
203
204
            $origin = input()->server('HTTP_ORIGIN');
205
206
            /**
207
             * Prepare for preflight modern browser request
208
             *
209
             * Since some server cannot use 'Access-Control-Allow-Origin: *'
210
             * the Access-Control-Allow-Origin will be defined based on requested origin
211
             */
212
            if ($this->accessControlAllowOrigin === '*') {
213
                output()->addHeader(ResponseFieldInterface::RESPONSE_ACCESS_CONTROL_ALLOW_ORIGIN, $origin);
0 ignored issues
show
Bug introduced by
The method addHeader() does not exist on O2System\Kernel\Cli\Output. ( Ignorable by Annotation )

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

213
                output()->/** @scrutinizer ignore-call */ addHeader(ResponseFieldInterface::RESPONSE_ACCESS_CONTROL_ALLOW_ORIGIN, $origin);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
214
            }
215
216
            // Set response access control allowed credentials
217
            if ($this->accessControlAllowCredentials === false) {
218
                output()->addHeader(ResponseFieldInterface::RESPONSE_ACCESS_CONTROL_ALLOW_CREDENTIALS, 'false');
219
            }
220
221
            // Set response access control allowed methods header
222
            if (count($this->accessControlAllowMethods)) {
223
                output()->addHeader(
224
                    ResponseFieldInterface::RESPONSE_ACCESS_CONTROL_ALLOW_METHODS,
225
                    implode(', ', $this->accessControlAllowMethods)
226
                );
227
            }
228
229
            // Set response access control allowed headers header
230
            if (count($this->accessControlAllowHeaders)) {
0 ignored issues
show
Bug introduced by
$this->accessControlAllowHeaders of type integer is incompatible with the type Countable|array expected by parameter $var of count(). ( Ignorable by Annotation )

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

230
            if (count(/** @scrutinizer ignore-type */ $this->accessControlAllowHeaders)) {
Loading history...
231
                output()->addHeader(
232
                    ResponseFieldInterface::RESPONSE_ACCESS_CONTROL_ALLOW_HEADERS,
233
                    implode(', ', $this->accessControlAllowHeaders)
0 ignored issues
show
Bug introduced by
$this->accessControlAllowHeaders of type integer is incompatible with the type array expected by parameter $pieces of implode(). ( Ignorable by Annotation )

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

233
                    implode(', ', /** @scrutinizer ignore-type */ $this->accessControlAllowHeaders)
Loading history...
234
                );
235
            }
236
237
            // Set response access control allowed content types header
238
            if (count($this->accessControlAllowContentTypes)) {
239
                output()->addHeader(
240
                    ResponseFieldInterface::RESPONSE_ACCESS_CONTROL_ALLOW_CONTENT_TYPES,
241
                    implode(', ', $this->accessControlAllowContentTypes)
242
                );
243
            }
244
245
            // Set response access control max age header
246
            if ($this->accessControlMaxAge > 0) {
247
                output()->addHeader(ResponseFieldInterface::RESPONSE_ACCESS_CONTROL_MAX_AGE,
248
                    $this->accessControlMaxAge);
249
            }
250
        }
251
252
        if (input()->server('REQUEST_METHOD') === 'OPTIONS') {
253
            exit(EXIT_SUCCESS);
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
254
        } elseif ( ! in_array(input()->server('REQUEST_METHOD'), $this->accessControlAllowMethods)) {
255
            $this->sendError(405);
256
        } elseif (count($this->accessControlParams)) {
257
            if ($this->accessControlMethod === 'GET') {
258
                if (empty($_GET)) {
259
                    $this->sendError(400);
260
                }
261
            } elseif ($this->accessControlMethod === 'POST') {
262
                if (empty($_POST)) {
263
                    $this->sendError(400);
264
                }
265
            } elseif (in_array($this->accessControlMethod, ['GETPOST', 'POSTGET'])) {
266
                if (empty($_REQUEST)) {
267
                    $this->sendError(400);
268
                }
269
            }
270
        }
271
272
        if (empty($this->model)) {
273
            $controllerClassName = get_called_class();
274
            $modelClassName = str_replace('Controllers', 'Models', $controllerClassName);
275
276
            if (class_exists($modelClassName)) {
277
                $this->model = new $modelClassName();
278
            }
279
        } elseif (class_exists($this->model)) {
0 ignored issues
show
Bug introduced by
$this->model of type O2System\Framework\Model...mework\Models\Sql\Model is incompatible with the type string expected by parameter $class_name of class_exists(). ( Ignorable by Annotation )

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

279
        } elseif (class_exists(/** @scrutinizer ignore-type */ $this->model)) {
Loading history...
280
            $this->model = new $this->model();
281
        }
282
    }
283
284
    // ------------------------------------------------------------------------
285
286
    /**
287
     * Restful::index
288
     */
289
    public function index()
290
    {
291
        if(empty($this->model)) {
292
            output()->sendError(204);
293
        } else {
294
            if ( ! $this->model instanceof Model) {
295
                $this->sendError(503, 'Model is not exists!');
296
            }
297
298
            if (count($this->params)) {
299
                if ($get = input()->get()) {
300
                    $rules = new Rules($get);
0 ignored issues
show
Bug introduced by
$get of type O2System\Spl\DataStructures\SplArrayObject is incompatible with the type array expected by parameter $sourceVars of O2System\Security\Filters\Rules::__construct(). ( Ignorable by Annotation )

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

300
                    $rules = new Rules(/** @scrutinizer ignore-type */ $get);
Loading history...
301
                    $rules->sets($this->rules);
0 ignored issues
show
Bug Best Practice introduced by
The property rules does not exist on O2System\Framework\Http\Controllers\Restful. Since you implemented __get, consider adding a @property annotation.
Loading history...
302
303
                    if ( ! $rules->validate()) {
304
                        $this->sendError(400, implode(', ', $rules->getErrors()));
305
                    }
306
                } else {
307
                    $this->sendError(400, 'Get parameters cannot be empty!');
308
                }
309
310
                $conditions = $get->getArrayCopy();
311
312
                if (false !== ($result = $this->model->withPaging()->findWhere($conditions))) {
313
                    if ($result->count()) {
314
                        $this->sendPayload($result);
315
                    } else {
316
                        $this->sendError(204);
317
                    }
318
                } else {
319
                    $this->sendError(204);
320
                }
321
            } elseif ($get = input()->get()) {
322
                if (false !== ($result = $this->model->withPaging()->findWhere($get->getArrayCopy()))) {
323
                    if ($result->count()) {
324
                        $this->sendPayload($result);
325
                    } else {
326
                        $this->sendError(204);
327
                    }
328
                } else {
329
                    $this->sendError(204);
330
                }
331
            } else {
332
                if (false !== ($result = $this->model->allWithPaging())) {
333
                    $this->sendPayload($result);
334
                } else {
335
                    $this->sendError(204);
336
                }
337
            }
338
        }
339
    }
340
341
    // ------------------------------------------------------------------------
342
343
    public function sendError($code, $message = null)
344
    {
345
        if ($this->ajaxOnly === false) {
346
            output()->setContentType('application/json');
347
        }
348
349
        if (is_array($code)) {
350
            if (is_numeric(key($code))) {
351
                $message = reset($code);
352
                $code = key($code);
353
            } elseif (isset($code[ 'code' ])) {
354
                $code = $code[ 'code' ];
355
                $message = $code[ 'message' ];
356
            }
357
        }
358
359
        output()->sendError($code, $message);
360
    }
361
362
    // ------------------------------------------------------------------------
363
364
    /**
365
     * Restful::sendPayload
366
     *
367
     * @param mixed $data        The payload data to-be send.
368
     * @param bool  $longPooling Long pooling flag mode.
369
     *
370
     * @throws \Exception
371
     */
372
    public function sendPayload($data, $longPooling = false)
373
    {
374
        if ($longPooling === false) {
375
            if ($this->ajaxOnly) {
376
                if (is_ajax()) {
377
                    output()->send($data);
0 ignored issues
show
Bug introduced by
The method send() does not exist on O2System\Kernel\Cli\Output. ( Ignorable by Annotation )

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

377
                    output()->/** @scrutinizer ignore-call */ send($data);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
378
                } else {
379
                    output()->sendError(403);
380
                }
381
            } else {
382
                output()->send($data);
383
            }
384
        } elseif (is_ajax()) {
385
            /**
386
             * Server-side file.
387
             * This file is an infinitive loop. Seriously.
388
             * It gets the cache created timestamp, checks if this is larger than the timestamp of the
389
             * AJAX-submitted timestamp (time of last ajax request), and if so, it sends back a JSON with the data from
390
             * data.txt (and a timestamp). If not, it waits for one seconds and then start the next while step.
391
             *
392
             * Note: This returns a JSON, containing the content of data.txt and the timestamp of the last data.txt change.
393
             * This timestamp is used by the client's JavaScript for the next request, so THIS server-side script here only
394
             * serves new content after the last file change. Sounds weird, but try it out, you'll get into it really fast!
395
             */
396
397
            // set php runtime to unlimited
398
            set_time_limit(0);
399
400
            $longPoolingCacheKey = 'long-pooling-' . session()->get('id');
0 ignored issues
show
Bug introduced by
Are you sure session()->get('id') of type false|mixed can be used in concatenation? ( Ignorable by Annotation )

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

400
            $longPoolingCacheKey = 'long-pooling-' . /** @scrutinizer ignore-type */ session()->get('id');
Loading history...
401
            $longPoolingCacheData = null;
402
403
            if ( ! cache()->hasItem($longPoolingCacheKey)) {
404
                cache()->save(new Item($longPoolingCacheKey, $data));
405
            }
406
407
            // main loop
408
            while (true) {
409
                // if ajax request has send a timestamp, then $lastCallTimestamp = timestamp, else $last_call = null
410
                $lastCallTimestamp = (int)input()->getPost('last_call_timestamp');
0 ignored issues
show
Bug introduced by
The method getPost() does not exist on O2System\Kernel\Cli\Input. ( Ignorable by Annotation )

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

410
                $lastCallTimestamp = (int)input()->/** @scrutinizer ignore-call */ getPost('last_call_timestamp');

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
411
412
                // PHP caches file data, like requesting the size of a file, by default. clearstatcache() clears that cache
413
                clearstatcache();
414
415
                if (cache()->hasItem($longPoolingCacheKey)) {
416
                    $longPoolingCacheData = cache()->getItem($longPoolingCacheKey);
417
                }
418
419
                // get timestamp of when file has been changed the last time
420
                $longPoolingCacheMetadata = $longPoolingCacheData->getMetadata();
421
422
                // if no timestamp delivered via ajax or data.txt has been changed SINCE last ajax timestamp
423
                if ($lastCallTimestamp == null || $longPoolingCacheMetadata[ 'ctime' ] > $lastCallTimestamp) {
424
                    output()->send([
425
                        'timestamp' => $longPoolingCacheMetadata,
426
                        'data'      => $data,
427
                    ]);
428
                } else {
429
                    // wait for 1 sec (not very sexy as this blocks the PHP/Apache process, but that's how it goes)
430
                    sleep(1);
431
                    continue;
432
                }
433
            }
434
        } else {
435
            output()->sendError(501);
436
        }
437
    }
438
439
    /**
440
     * Controller::create
441
     *
442
     * @throws \O2System\Spl\Exceptions\Logic\BadFunctionCall\BadDependencyCallException
443
     * @throws \O2System\Spl\Exceptions\Logic\OutOfRangeException
444
     */
445
    public function create()
446
    {
447
        if ($post = input()->post()) {
448
            if (count($this->fillableColumnsWithRules)) {
449
                $rules = new Rules($post);
0 ignored issues
show
Bug introduced by
$post of type O2System\Spl\DataStructures\SplArrayObject is incompatible with the type array expected by parameter $sourceVars of O2System\Security\Filters\Rules::__construct(). ( Ignorable by Annotation )

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

449
                $rules = new Rules(/** @scrutinizer ignore-type */ $post);
Loading history...
450
                $rules->sets($this->fillableColumnsWithRules);
451
                if ( ! $rules->validate()) {
452
                    $this->sendError(400, $rules->displayErrors(true));
0 ignored issues
show
Unused Code introduced by
The call to O2System\Security\Filters\Rules::displayErrors() has too many arguments starting with true. ( Ignorable by Annotation )

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

452
                    $this->sendError(400, $rules->/** @scrutinizer ignore-call */ displayErrors(true));

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
453
                }
454
            }
455
456
            if ( ! $this->model instanceof Model) {
457
                $this->sendError(503, 'Model is not ready');
458
            }
459
460
            $data = [];
461
462
            if (count($this->fillableColumnsWithRules)) {
463
                foreach ($this->fillableColumnsWithRules as $column) {
464
                    if ($post->offsetExists($column[ 'field' ])) {
465
                        $data[ $column[ 'field' ] ] = $post->offsetGet($column[ 'field' ]);
466
                    }
467
                }
468
            } elseif (count($this->fillableColumns)) {
469
                foreach ($this->fillableColumns as $column) {
470
                    if ($post->offsetExists($column[ 'field' ])) {
471
                        $data[ $column[ 'field' ] ] = $post->offsetGet($column[ 'field' ]);
472
                    }
473
                }
474
            } else {
475
                $data = $post->getArrayCopy();
476
            }
477
478
            if (count($data)) {
479
                $data[ 'record_create_timestamp' ] = $data[ 'record_update_timestamp' ] = timestamp();
480
                $data[ 'record_create_user' ] = $data[ 'record_update_user' ] = globals()->account->id;
0 ignored issues
show
Bug Best Practice introduced by
The property account does not exist on O2System\Framework\Containers\Globals. Since you implemented __get, consider adding a @property annotation.
Loading history...
481
482
                if ($this->model->insert($data)) {
483
                    $data[ 'id' ] = $this->model->db->getLastInsertId();
484
                    $this->sendPayload([
485
                        'code' => 201,
486
                        'Successful insert request',
487
                        'data' => $data,
488
                    ]);
489
                } else {
490
                    $this->sendError(501, 'Failed update request');
491
                }
492
            } else {
493
                $this->sendError(400, 'Post parameters cannot be empty!');
494
            }
495
        } else {
496
            $this->sendError(400);
497
        }
498
    }
499
500
    // ------------------------------------------------------------------------
501
502
    /**
503
     * Restful::update
504
     *
505
     * @throws \O2System\Spl\Exceptions\Logic\BadFunctionCall\BadDependencyCallException
506
     * @throws \O2System\Spl\Exceptions\Logic\OutOfRangeException
507
     */
508
    public function update()
509
    {
510
        if ($post = input()->post()) {
511
            if (count($this->fillableColumnsWithRules)) {
512
                $rules = new Rules($post);
0 ignored issues
show
Bug introduced by
$post of type O2System\Spl\DataStructures\SplArrayObject is incompatible with the type array expected by parameter $sourceVars of O2System\Security\Filters\Rules::__construct(). ( Ignorable by Annotation )

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

512
                $rules = new Rules(/** @scrutinizer ignore-type */ $post);
Loading history...
513
                $rules->sets($this->fillableColumnsWithRules);
514
                $rules->add('id', 'ID', 'required', 'ID field cannot be empty!');
0 ignored issues
show
Bug introduced by
'ID field cannot be empty!' of type string is incompatible with the type array expected by parameter $messages of O2System\Security\Filters\Rules::add(). ( Ignorable by Annotation )

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

514
                $rules->add('id', 'ID', 'required', /** @scrutinizer ignore-type */ 'ID field cannot be empty!');
Loading history...
515
516
                if ( ! $rules->validate()) {
517
                    $this->sendError(400, implode(', ', $rules->displayErrors(true)));
0 ignored issues
show
Unused Code introduced by
The call to O2System\Security\Filters\Rules::displayErrors() has too many arguments starting with true. ( Ignorable by Annotation )

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

517
                    $this->sendError(400, implode(', ', $rules->/** @scrutinizer ignore-call */ displayErrors(true)));

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
Bug introduced by
It seems like $rules->displayErrors(true) can also be of type string; however, parameter $pieces of implode() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

517
                    $this->sendError(400, implode(', ', /** @scrutinizer ignore-type */ $rules->displayErrors(true)));
Loading history...
518
                }
519
            }
520
521
            if ( ! $this->model instanceof Model) {
522
                $this->sendError(503, 'Model is not ready');
523
            }
524
525
            $data = [];
526
527
            if (count($this->fillableColumnsWithRules)) {
528
                foreach ($this->fillableColumnsWithRules as $column) {
529
                    if ($post->offsetExists($column[ 'field' ])) {
530
                        $data[ $column[ 'field' ] ] = $post->offsetGet($column[ 'field' ]);
531
                    }
532
                }
533
            } elseif (count($this->fillableColumns)) {
534
                foreach ($this->fillableColumns as $column) {
535
                    if ($post->offsetExists($column[ 'field' ])) {
536
                        $data[ $column[ 'field' ] ] = $post->offsetGet($column[ 'field' ]);
537
                    }
538
                }
539
            } else {
540
                $data = $post->getArrayCopy();
541
            }
542
543
            if (count($data)) {
544
                $data[ 'record_update_timestamp' ] = timestamp();
545
                $data[ 'record_update_user' ] = globals()->account->id;
0 ignored issues
show
Bug Best Practice introduced by
The property account does not exist on O2System\Framework\Containers\Globals. Since you implemented __get, consider adding a @property annotation.
Loading history...
546
547
                if ($this->model->update($data)) {
548
                    $this->sendError(201, 'Successful update request');
549
                } else {
550
                    $this->sendError(501, 'Failed update request');
551
                }
552
            } else {
553
                $this->sendError(400, 'Post parameters cannot be empty!');
554
            }
555
        } else {
556
            $this->sendError(400);
557
        }
558
    }
559
560
    // ------------------------------------------------------------------------
561
562
    /**
563
     * Restful::delete
564
     *
565
     * @throws \O2System\Spl\Exceptions\Logic\OutOfRangeException
566
     * @throws \O2System\Spl\Exceptions\RuntimeException
567
     * @throws \Psr\Cache\InvalidArgumentException
568
     */
569
    public function delete()
570
    {
571
        if ($post = input()->post()) {
572
            $rules = new Rules($post);
0 ignored issues
show
Bug introduced by
$post of type O2System\Spl\DataStructures\SplArrayObject is incompatible with the type array expected by parameter $sourceVars of O2System\Security\Filters\Rules::__construct(). ( Ignorable by Annotation )

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

572
            $rules = new Rules(/** @scrutinizer ignore-type */ $post);
Loading history...
573
            $rules->add('id', 'ID', 'required', 'ID field cannot be empty!');
0 ignored issues
show
Bug introduced by
'ID field cannot be empty!' of type string is incompatible with the type array expected by parameter $messages of O2System\Security\Filters\Rules::add(). ( Ignorable by Annotation )

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

573
            $rules->add('id', 'ID', 'required', /** @scrutinizer ignore-type */ 'ID field cannot be empty!');
Loading history...
574
575
            if ( ! $rules->validate()) {
576
                $this->sendError(400, implode(', ', $rules->getErrors()));
577
            }
578
579
            if ( ! $this->model instanceof Model) {
580
                $this->sendError(503, 'Model is not ready');
581
            }
582
583
            if ($this->model->delete($post->id)) {
584
                $this->sendError(201, 'Successful delete request');
585
            } else {
586
                $this->sendError(501, 'Failed delete request');
587
            }
588
        } else {
589
            $this->sendError(400);
590
        }
591
    }
592
593
    // ------------------------------------------------------------------------
594
595
    /**
596
     * Restful::publish
597
     *
598
     * @throws OutOfRangeException
599
     */
600
    public function publish()
601
    {
602
        if ($post = input()->post()) {
603
            $rules = new Rules($post);
0 ignored issues
show
Bug introduced by
$post of type O2System\Spl\DataStructures\SplArrayObject is incompatible with the type array expected by parameter $sourceVars of O2System\Security\Filters\Rules::__construct(). ( Ignorable by Annotation )

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

603
            $rules = new Rules(/** @scrutinizer ignore-type */ $post);
Loading history...
604
            $rules->add('id', 'ID', 'required', 'ID field cannot be empty!');
0 ignored issues
show
Bug introduced by
'ID field cannot be empty!' of type string is incompatible with the type array expected by parameter $messages of O2System\Security\Filters\Rules::add(). ( Ignorable by Annotation )

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

604
            $rules->add('id', 'ID', 'required', /** @scrutinizer ignore-type */ 'ID field cannot be empty!');
Loading history...
605
606
            if ( ! $rules->validate()) {
607
                $this->sendError(400, implode(', ', $rules->getErrors()));
608
            }
609
610
            if ( ! $this->model instanceof Model) {
611
                $this->sendError(503, 'Model is not ready');
612
            }
613
614
            if ($this->model->publish($post->id)) {
615
                $this->sendError(201, 'Successful publish request');
616
            } else {
617
                $this->sendError(501, 'Failed publish request');
618
            }
619
        } else {
620
            $this->sendError(400);
621
        }
622
    }
623
624
    // ------------------------------------------------------------------------
625
626
    /**
627
     * Restful::unpublish
628
     *
629
     * @throws OutOfRangeException
630
     */
631
    public function unpublish()
632
    {
633
        if ($post = input()->post()) {
634
            $rules = new Rules($post);
0 ignored issues
show
Bug introduced by
$post of type O2System\Spl\DataStructures\SplArrayObject is incompatible with the type array expected by parameter $sourceVars of O2System\Security\Filters\Rules::__construct(). ( Ignorable by Annotation )

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

634
            $rules = new Rules(/** @scrutinizer ignore-type */ $post);
Loading history...
635
            $rules->add('id', 'ID', 'required', 'ID field cannot be empty!');
0 ignored issues
show
Bug introduced by
'ID field cannot be empty!' of type string is incompatible with the type array expected by parameter $messages of O2System\Security\Filters\Rules::add(). ( Ignorable by Annotation )

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

635
            $rules->add('id', 'ID', 'required', /** @scrutinizer ignore-type */ 'ID field cannot be empty!');
Loading history...
636
637
            if ( ! $rules->validate()) {
638
                $this->sendError(400, implode(', ', $rules->getErrors()));
639
            }
640
641
            if ( ! $this->model instanceof Model) {
642
                $this->sendError(503, 'Model is not ready');
643
            }
644
645
            if ($this->model->unpublish($post->id)) {
646
                $this->sendError(201, 'Successful unpublish request');
647
            } else {
648
                $this->sendError(501, 'Failed unpublish request');
649
            }
650
        } else {
651
            $this->sendError(400);
652
        }
653
    }
654
655
    // ------------------------------------------------------------------------
656
657
    /**
658
     * Controller::archive
659
     *
660
     * @throws OutOfRangeException
661
     */
662
    public function archive()
663
    {
664
        if ($post = input()->post()) {
665
            $rules = new Rules($post);
0 ignored issues
show
Bug introduced by
$post of type O2System\Spl\DataStructures\SplArrayObject is incompatible with the type array expected by parameter $sourceVars of O2System\Security\Filters\Rules::__construct(). ( Ignorable by Annotation )

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

665
            $rules = new Rules(/** @scrutinizer ignore-type */ $post);
Loading history...
666
            $rules->add('id', 'ID', 'required', 'ID field cannot be empty!');
0 ignored issues
show
Bug introduced by
'ID field cannot be empty!' of type string is incompatible with the type array expected by parameter $messages of O2System\Security\Filters\Rules::add(). ( Ignorable by Annotation )

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

666
            $rules->add('id', 'ID', 'required', /** @scrutinizer ignore-type */ 'ID field cannot be empty!');
Loading history...
667
668
            if ( ! $rules->validate()) {
669
                $this->sendError(400, implode(', ', $rules->getErrors()));
670
            }
671
672
            if ( ! $this->model instanceof Model) {
673
                $this->sendError(503, 'Model is not ready');
674
            }
675
676
            if ($this->model->unpublish($post->id)) {
677
                $this->sendError(201, 'Successful archived request');
678
            } else {
679
                $this->sendError(501, 'Failed archived request');
680
            }
681
        } else {
682
            $this->sendError(400);
683
        }
684
    }
685
}