Passed
Push — v1 ( 543469...123bab )
by Andrew
10:22 queued 07:08
created

TablesController::actionErrorsIndex()   C

Complexity

Conditions 12
Paths 60

Size

Total Lines 112
Code Lines 74

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 74
dl 0
loc 112
rs 6.1406
c 0
b 0
f 0
cc 12
nc 60
nop 7

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Webperf plugin for Craft CMS 3.x
4
 *
5
 * Monitor the performance of your webpages through real-world user timing data
6
 *
7
 * @link      https://nystudio107.com
0 ignored issues
show
Coding Style introduced by
The tag in position 1 should be the @copyright tag
Loading history...
8
 * @copyright Copyright (c) 2019 nystudio107
0 ignored issues
show
Coding Style introduced by
@copyright tag must contain a year and the name of the copyright holder
Loading history...
9
 */
0 ignored issues
show
Coding Style introduced by
PHP version not specified
Loading history...
Coding Style introduced by
Missing @category tag in file comment
Loading history...
Coding Style introduced by
Missing @package tag in file comment
Loading history...
Coding Style introduced by
Missing @author tag in file comment
Loading history...
Coding Style introduced by
Missing @license tag in file comment
Loading history...
10
11
namespace nystudio107\webperf\controllers;
12
13
use nystudio107\webperf\helpers\Permission as PermissionHelper;
14
15
use Craft;
0 ignored issues
show
Bug introduced by
The type Craft was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
16
use craft\db\Query;
0 ignored issues
show
Bug introduced by
The type craft\db\Query was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
use craft\helpers\DateTimeHelper;
0 ignored issues
show
Bug introduced by
The type craft\helpers\DateTimeHelper was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
18
use craft\helpers\UrlHelper;
0 ignored issues
show
Bug introduced by
The type craft\helpers\UrlHelper was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
19
use craft\web\Controller;
0 ignored issues
show
Bug introduced by
The type craft\web\Controller was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
20
21
use yii\web\ForbiddenHttpException;
0 ignored issues
show
Bug introduced by
The type yii\web\ForbiddenHttpException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
22
use yii\web\Response;
0 ignored issues
show
Bug introduced by
The type yii\web\Response was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
23
24
/**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
25
 * @author    nystudio107
0 ignored issues
show
Coding Style introduced by
The tag in position 1 should be the @package tag
Loading history...
Coding Style introduced by
Content of the @author tag must be in the form "Display Name <[email protected]>"
Loading history...
Coding Style introduced by
Tag value indented incorrectly; expected 2 spaces but found 4
Loading history...
26
 * @package   Webperf
0 ignored issues
show
Coding Style introduced by
Tag value indented incorrectly; expected 1 spaces but found 3
Loading history...
27
 * @since     1.0.0
0 ignored issues
show
Coding Style introduced by
The tag in position 3 should be the @author tag
Loading history...
Coding Style introduced by
Tag value indented incorrectly; expected 3 spaces but found 5
Loading history...
28
 */
0 ignored issues
show
Coding Style introduced by
Missing @category tag in class comment
Loading history...
Coding Style introduced by
Missing @license tag in class comment
Loading history...
Coding Style introduced by
Missing @link tag in class comment
Loading history...
29
class TablesController extends Controller
30
{
31
    // Constants
32
    // =========================================================================
33
34
    // Protected Properties
35
    // =========================================================================
36
37
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
38
     * @var    bool|array
0 ignored issues
show
Coding Style introduced by
Tag value indented incorrectly; expected 1 spaces but found 4
Loading history...
39
     */
40
    protected $allowAnonymous = [];
41
42
    // Public Methods
43
    // =========================================================================
44
45
    /**
46
     * Handle requests for the performance index table
47
     *
48
     * @param string $sort
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Doc comment for parameter $sort does not match actual variable name $start
Loading history...
49
     * @param int    $page
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Doc comment for parameter $page does not match actual variable name $end
Loading history...
50
     * @param int    $per_page
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Doc comment for parameter $per_page does not match actual variable name $sort
Loading history...
51
     * @param string $filter
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Doc comment for parameter $filter does not match actual variable name $page
Loading history...
52
     * @param string $start
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Doc comment for parameter $start does not match actual variable name $per_page
Loading history...
53
     * @param string $end
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Doc comment for parameter $end does not match actual variable name $filter
Loading history...
54
     * @param int    $siteId
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
55
     *
56
     * @return Response
57
     * @throws ForbiddenHttpException
58
     */
59
    public function actionPagesIndex(
60
        string $start = '',
61
        string $end = '',
62
        string $sort = 'pageLoad|DESC',
63
        int $page = 1,
64
        int $per_page = 20,
65
        $filter = '',
66
        $siteId = 0
67
    ): Response {
68
        PermissionHelper::controllerPermissionCheck('webperf:performance');
69
        $data = [];
70
        $sortField = 'pageLoad';
71
        $sortType = 'DESC';
72
        // Add a day since YYYY-MM-DD is really YYYY-MM-DD 00:00:00
73
        $end = date('Y-m-d', strtotime($end.'+1 day'));
74
        // Figure out the sorting type
75
        if ($sort !== '') {
76
            if (strpos($sort, '|') === false) {
77
                $sortField = $sort;
78
            } else {
79
                list($sortField, $sortType) = explode('|', $sort);
80
            }
81
        }
82
        // Query the db table
83
        $offset = ($page - 1) * $per_page;
84
        $query = (new Query())
85
            ->select([
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
86
                '[[url]]',
87
                'MIN([[title]]) AS [[title]]',
88
                'COUNT([[url]]) AS [[cnt]]',
89
                'AVG([[pageLoad]]) AS [[pageLoad]]',
90
                'AVG([[domInteractive]]) AS [[domInteractive]]',
91
                'AVG([[firstContentfulPaint]]) AS [[firstContentfulPaint]]',
92
                'AVG([[firstPaint]]) AS [[firstPaint]]',
93
                'AVG([[firstByte]]) AS [[firstByte]]',
94
                'AVG([[connect]]) AS [[connect]]',
95
                'AVG([[dns]]) AS [[dns]]',
96
                'AVG([[craftTotalMs]]) AS [[craftTotalMs]]',
97
                'AVG([[craftDbCnt]]) AS [[craftDbCnt]]',
98
                'AVG([[craftDbMs]]) AS [[craftDbMs]]',
99
                'AVG([[craftTwigCnt]]) AS [[craftTwigCnt]]',
100
                'AVG([[craftTwigMs]]) AS [[craftTwigMs]]',
101
                'AVG([[craftTotalMemory]]) AS [[craftTotalMemory]]',
102
            ])
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
103
            ->from(['{{%webperf_data_samples}}'])
104
            ->offset($offset)
105
            ->where(['between', 'dateCreated', $start, $end])
0 ignored issues
show
Coding Style introduced by
Space after closing parenthesis of function call prohibited
Loading history...
106
        ;
107
        if ((int)$siteId !== 0) {
108
            $query->andWhere(['siteId' => $siteId]);
109
        }
110
        if ($filter !== '') {
111
            $query
112
                ->andWhere(['like', 'url', $filter])
113
                ->orWhere(['like', 'title', $filter])
0 ignored issues
show
Coding Style introduced by
Space after closing parenthesis of function call prohibited
Loading history...
114
            ;
115
        }
116
        $query
117
            ->orderBy("[[{$sortField}]] {$sortType}")
118
            ->groupBy('url')
119
            ->limit($per_page)
0 ignored issues
show
Coding Style introduced by
Space after closing parenthesis of function call prohibited
Loading history...
120
        ;
121
122
        $stats = $query->all();
123
        if ($stats) {
124
            $user = Craft::$app->getUser()->getIdentity();
125
            // Compute the largest page load time
126
            $maxTotalPageLoad = 0;
127
            foreach ($stats as &$stat) {
128
             // Determine the stat type
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected at least 16 spaces, found 13
Loading history...
129
                if (!empty($stat['pageLoad']) && !empty($stat['craftTotalMs'])) {
130
                    $stat['type'] = 'both';
131
                }
132
                if (empty($stat['firstByte'])) {
133
                    $stat['type'] = 'craft';
134
                }
135
                if (empty($stat['craftTotalMs'])) {
136
                    $stat['type'] = 'frontend';
137
                }
138
                if ($stat['pageLoad'] > $maxTotalPageLoad) {
139
                    $maxTotalPageLoad = $stat['pageLoad'];
140
                }
141
            }
142
            // Massage the stats
143
            $index = 1;
144
            foreach ($stats as &$stat) {
145
                $stat['id'] = $index++;
146
                $stat['cnt'] = (int)$stat['cnt'];
147
                $stat['maxTotalPageLoad'] = (int)$maxTotalPageLoad;
148
                // Decode any emojis in the title
149
                if (!empty($stat['title'])) {
150
                    $stat['title'] = html_entity_decode($stat['title'], ENT_NOQUOTES, 'UTF-8');
151
                }
152
                // Set up the appropriate helper links
153
                $stat['deleteLink'] = UrlHelper::actionUrl('webperf/data-samples/delete-samples-by-url', [
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
154
                    'pageUrl' => $stat['url'],
155
                    'siteId' => $siteId
156
                ]);
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
157
                $stat['detailPageUrl'] = UrlHelper::cpUrl('webperf/performance/page-detail', [
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
158
                    'pageUrl' => $stat['url'],
159
                    'siteId' => $siteId,
160
                ]);
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
161
                // Override based on permissions
162
                if (!$user->can('webperf:delete-data-samples')) {
163
                    $stat['deleteLink'] = '';
164
                }
165
                if (!$user->can('webperf:performance-detail')) {
166
                    $stat['detailPageUrl'] = '';
167
                }
168
            }
169
            // Format the data for the API
170
            $data['data'] = $stats;
171
            $query = (new Query())
172
                ->select(['[[url]]'])
173
                ->from(['{{%webperf_data_samples}}'])
174
                ->groupBy('[[url]]')
175
                ->where(['between', 'dateCreated', $start, $end])
0 ignored issues
show
Coding Style introduced by
Space after closing parenthesis of function call prohibited
Loading history...
176
                ;
177
            if ($filter !== '') {
178
                $query->andWhere(['like', 'url', $filter]);
179
                $query->orWhere(['like', 'title', $filter]);
180
            }
181
            $count = $query->count();
182
            $data['links']['pagination'] = [
183
                'total' => $count,
184
                'per_page' => $per_page,
185
                'current_page' => $page,
186
                'last_page' => ceil($count / $per_page),
187
                'next_page_url' => null,
188
                'prev_page_url' => null,
189
                'from' => $offset + 1,
190
                'to' => $offset + ($count > $per_page ? $per_page : $count),
191
            ];
192
        }
193
194
        return $this->asJson($data);
195
    }
196
197
    /**
198
     * Handle requests for the performance detail table
199
     *
200
     * @param string $sort
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Doc comment for parameter $sort does not match actual variable name $start
Loading history...
201
     * @param int    $page
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Doc comment for parameter $page does not match actual variable name $end
Loading history...
202
     * @param int    $per_page
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Doc comment for parameter $per_page does not match actual variable name $sort
Loading history...
203
     * @param string $filter
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Doc comment for parameter $filter does not match actual variable name $page
Loading history...
204
     * @param string $pageUrl
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Doc comment for parameter $pageUrl does not match actual variable name $per_page
Loading history...
205
     * @param string $start
0 ignored issues
show
Coding Style introduced by
Doc comment for parameter $start does not match actual variable name $filter
Loading history...
Coding Style introduced by
Missing parameter comment
Loading history...
206
     * @param string $end
0 ignored issues
show
Coding Style introduced by
Doc comment for parameter $end does not match actual variable name $pageUrl
Loading history...
Coding Style introduced by
Missing parameter comment
Loading history...
207
     * @param int    $siteId
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
208
     *
209
     * @return Response
210
     * @throws ForbiddenHttpException
211
     */
212
    public function actionPageDetail(
213
        string $start = '',
214
        string $end = '',
215
        string $sort = 'pageLoad|DESC',
216
        int $page = 1,
217
        int $per_page = 20,
218
        $filter = '',
219
        $pageUrl = '',
220
        $siteId = 0
221
    ): Response {
222
        PermissionHelper::controllerPermissionCheck('webperf:performance');
223
        $data = [];
224
        $sortField = 'pageLoad';
225
        $sortType = 'DESC';
226
        // Add a day since YYYY-MM-DD is really YYYY-MM-DD 00:00:00
227
        $end = date('Y-m-d', strtotime($end.'+1 day'));
228
        $pageUrl = urldecode($pageUrl);
229
        // Figure out the sorting type
230
        if ($sort !== '') {
231
            if (strpos($sort, '|') === false) {
232
                $sortField = $sort;
233
            } else {
234
                list($sortField, $sortType) = explode('|', $sort);
235
            }
236
        }
237
        // Query the db table
238
        $offset = ($page - 1) * $per_page;
239
        $query = (new Query())
240
            ->from(['{{%webperf_data_samples}}'])
241
            ->offset($offset)
242
            ->where(['url' => $pageUrl])
243
            ->andWhere(['between', 'dateCreated', $start, $end])
0 ignored issues
show
Coding Style introduced by
Space after closing parenthesis of function call prohibited
Loading history...
244
        ;
245
        if ((int)$siteId !== 0) {
246
            $query->andWhere(['siteId' => $siteId]);
247
        }
248
        if ($filter !== '') {
249
            $query
250
                ->andWhere(['like', 'device', $filter])
251
                ->orWhere(['like', 'os', $filter])
252
                ->orWhere(['like', 'browser', $filter])
253
                ->orWhere(['like', 'countryCode', $filter])
0 ignored issues
show
Coding Style introduced by
Space after closing parenthesis of function call prohibited
Loading history...
254
            ;
255
        }
256
        $query
257
            ->orderBy("{$sortField} {$sortType}")
258
            ->limit($per_page)
0 ignored issues
show
Coding Style introduced by
Space after closing parenthesis of function call prohibited
Loading history...
259
        ;
260
        $stats = $query->all();
261
        if ($stats) {
262
            $user = Craft::$app->getUser()->getIdentity();
263
            // Compute the largest page load time
264
            $maxTotalPageLoad = 0;
265
            foreach ($stats as &$stat) {
266
                // Determine the stat type
267
                if (!empty($stat['pageLoad']) && !empty($stat['craftTotalMs'])) {
268
                    $stat['type'] = 'both';
269
                }
270
                if (empty($stat['firstByte'])) {
271
                    $stat['type'] = 'craft';
272
                }
273
                if (empty($stat['craftTotalMs'])) {
274
                    $stat['type'] = 'frontend';
275
                }
276
                if ($stat['pageLoad'] > $maxTotalPageLoad) {
277
                    $maxTotalPageLoad = (int)$stat['pageLoad'];
278
                }
279
            }
280
            // Massage the stats
281
            foreach ($stats as &$stat) {
282
                if (!empty($stats['dateCreated'])) {
283
                    $date = DateTimeHelper::toDateTime($stats['dateCreated']);
284
                    $stats['dateCreated'] = $date->format('Y-m-d H:i:s');
285
                }
286
                $stat['mobile'] = (bool)$stat['mobile'];
287
                $stat['maxTotalPageLoad'] = (int)$maxTotalPageLoad;
288
                // Decode any emojis in the title
289
                if (!empty($stat['title'])) {
290
                    $stat['title'] = html_entity_decode($stat['title'], ENT_NOQUOTES, 'UTF-8');
291
                }
292
                $stat['deleteLink'] = UrlHelper::actionUrl('webperf/data-samples/delete-sample-by-id', [
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
293
                    'id' => $stat['id']
294
                ]);
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
295
                // Override based on permissions
296
                if (!$user->can('webperf:delete-data-samples')) {
297
                    $stat['deleteLink'] = '';
298
                }
299
            }
300
            // Format the data for the API
301
            $data['data'] = $stats;
302
            $query = (new Query())
303
                ->select(['[[url]]'])
304
                ->from(['{{%webperf_data_samples}}'])
305
                ->where(['url' => $pageUrl])
306
                ->andWhere(['between', 'dateCreated', $start, $end])
0 ignored issues
show
Coding Style introduced by
Space after closing parenthesis of function call prohibited
Loading history...
307
            ;
308
            if ($filter !== '') {
309
                $query
310
                    ->andWhere(['like', 'device', $filter])
311
                    ->orWhere(['like', 'os', $filter])
312
                    ->orWhere(['like', 'browser', $filter])
313
                    ->orWhere(['like', 'countryCode', $filter])
0 ignored issues
show
Coding Style introduced by
Space after closing parenthesis of function call prohibited
Loading history...
314
                ;
315
            }
316
            $count = $query->count();
317
            $data['links']['pagination'] = [
318
                'total' => $count,
319
                'per_page' => $per_page,
320
                'current_page' => $page,
321
                'last_page' => ceil($count / $per_page),
322
                'next_page_url' => null,
323
                'prev_page_url' => null,
324
                'from' => $offset + 1,
325
                'to' => $offset + ($count > $per_page ? $per_page : $count),
326
            ];
327
        }
328
329
        return $this->asJson($data);
330
    }
331
332
    /**
333
     * Handle requests for the pages index table
334
     *
335
     * @param string $sort
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Doc comment for parameter $sort does not match actual variable name $start
Loading history...
336
     * @param int    $page
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Doc comment for parameter $page does not match actual variable name $end
Loading history...
337
     * @param int    $per_page
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Doc comment for parameter $per_page does not match actual variable name $sort
Loading history...
338
     * @param string $filter
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Doc comment for parameter $filter does not match actual variable name $page
Loading history...
339
     * @param string $start
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Doc comment for parameter $start does not match actual variable name $per_page
Loading history...
340
     * @param string $end
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Doc comment for parameter $end does not match actual variable name $filter
Loading history...
341
     * @param int    $siteId
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
342
     *
343
     * @return Response
344
     * @throws ForbiddenHttpException
345
     */
346
    public function actionErrorsIndex(
347
        string $start = '',
348
        string $end = '',
349
        string $sort = 'url|DESC',
350
        int $page = 1,
351
        int $per_page = 20,
352
        $filter = '',
353
        $siteId = 0
354
    ): Response {
355
        PermissionHelper::controllerPermissionCheck('webperf:errors');
356
        $data = [];
357
        $sortField = 'url';
358
        $sortType = 'DESC';
359
        // Add a day since YYYY-MM-DD is really YYYY-MM-DD 00:00:00
360
        $end = date('Y-m-d', strtotime($end.'+1 day'));
361
        // Figure out the sorting type
362
        if ($sort !== '') {
363
            if (strpos($sort, '|') === false) {
364
                $sortField = $sort;
365
            } else {
366
                list($sortField, $sortType) = explode('|', $sort);
367
            }
368
        }
369
        // Query the db table
370
        $offset = ($page - 1) * $per_page;
371
        $query = (new Query())
372
            ->select([
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
373
                '[[url]]',
374
                'MIN([[title]]) as [[title]]',
375
                'MAX([[dateCreated]]) as [[latestErrorDate]]',
376
                'SUM([[type]] = \'craft\') as [[craftCount]]',
377
                'SUM([[type]] = \'boomerang\') as [[boomerangCount]]',
378
                'COUNT([[url]]) AS cnt',
379
            ])
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
380
            ->from(['{{%webperf_error_samples}}'])
381
            ->offset($offset)
382
            ->where(['between', 'dateCreated', $start, $end])
0 ignored issues
show
Coding Style introduced by
Space after closing parenthesis of function call prohibited
Loading history...
383
        ;
384
        if ((int)$siteId !== 0) {
385
            $query->andWhere(['siteId' => $siteId]);
386
        }
387
        if ($filter !== '') {
388
            $query
389
                ->andWhere(['like', 'url', $filter])
390
                ->orWhere(['like', 'title', $filter])
391
                ->orWhere(['like', 'pageErrors', $filter])
0 ignored issues
show
Coding Style introduced by
Space after closing parenthesis of function call prohibited
Loading history...
392
            ;
393
        }
394
        $query
395
            ->orderBy("[[{$sortField}]] {$sortType}")
396
            ->groupBy('url')
397
            ->limit($per_page)
0 ignored issues
show
Coding Style introduced by
Space after closing parenthesis of function call prohibited
Loading history...
398
        ;
399
400
        $stats = $query->all();
401
        if ($stats) {
402
            $user = Craft::$app->getUser()->getIdentity();
403
            // Massage the stats
404
            foreach ($stats as &$stat) {
405
                $stat['cnt'] = (int)$stat['cnt'];
406
                $stat['craftCount'] = (int)$stat['craftCount'];
407
                $stat['boomerangCount'] = (int)$stat['boomerangCount'];
408
                // Decode any emojis in the title
409
                if (!empty($stat['title'])) {
410
                    $stat['title'] = html_entity_decode($stat['title'], ENT_NOQUOTES, 'UTF-8');
411
                }
412
                // Set up the appropriate helper links
413
                $stat['deleteLink'] = UrlHelper::actionUrl('webperf/error-samples/delete-samples-by-url', [
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
414
                    'pageUrl' => $stat['url'],
415
                    'siteId' => $siteId
416
                ]);
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
417
                $stat['detailPageUrl'] = UrlHelper::cpUrl('webperf/errors/page-detail', [
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
418
                    'pageUrl' => $stat['url'],
419
                    'siteId' => $siteId,
420
                ]);
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
421
                // Override based on permissions
422
                if (!$user->can('webperf:delete-error-samples')) {
423
                    $stat['deleteLink'] = '';
424
                }
425
                if (!$user->can('webperf:errors-detail')) {
426
                    $stat['detailPageUrl'] = '';
427
                }
428
            }
429
            // Format the data for the API
430
            $data['data'] = $stats;
431
            $query = (new Query())
432
                ->select(['[[url]]'])
433
                ->from(['{{%webperf_error_samples}}'])
434
                ->groupBy('[[url]]')
435
                ->where(['between', 'dateCreated', $start, $end])
0 ignored issues
show
Coding Style introduced by
Space after closing parenthesis of function call prohibited
Loading history...
436
            ;
437
            if ($filter !== '') {
438
                $query
439
                    ->andWhere(['like', 'url', $filter])
440
                    ->orWhere(['like', 'title', $filter])
441
                    ->orWhere(['like', 'pageErrors', $filter])
0 ignored issues
show
Coding Style introduced by
Space after closing parenthesis of function call prohibited
Loading history...
442
                ;
443
            }
444
            $count = $query->count();
445
            $data['links']['pagination'] = [
446
                'total' => $count,
447
                'per_page' => $per_page,
448
                'current_page' => $page,
449
                'last_page' => ceil($count / $per_page),
450
                'next_page_url' => null,
451
                'prev_page_url' => null,
452
                'from' => $offset + 1,
453
                'to' => $offset + ($count > $per_page ? $per_page : $count),
454
            ];
455
        }
456
457
        return $this->asJson($data);
458
    }
459
460
461
    /**
462
     * Handle requests for the performance detail table
463
     *
464
     * @param string $sort
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Doc comment for parameter $sort does not match actual variable name $start
Loading history...
465
     * @param int    $page
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Doc comment for parameter $page does not match actual variable name $end
Loading history...
466
     * @param int    $per_page
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Doc comment for parameter $per_page does not match actual variable name $sort
Loading history...
467
     * @param string $filter
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Doc comment for parameter $filter does not match actual variable name $page
Loading history...
468
     * @param string $pageUrl
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Doc comment for parameter $pageUrl does not match actual variable name $per_page
Loading history...
469
     * @param string $start
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Doc comment for parameter $start does not match actual variable name $filter
Loading history...
470
     * @param string $end
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Doc comment for parameter $end does not match actual variable name $pageUrl
Loading history...
471
     * @param int    $siteId
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
472
     *
473
     * @return Response
474
     * @throws ForbiddenHttpException
475
     */
476
    public function actionErrorsDetail(
477
        string $start = '',
478
        string $end = '',
479
        string $sort = 'dateCreated|DESC',
480
        int $page = 1,
481
        int $per_page = 20,
482
        $filter = '',
483
        $pageUrl = '',
484
        $siteId = 0
485
    ): Response {
486
        PermissionHelper::controllerPermissionCheck('webperf:errors');
487
        $data = [];
488
        $sortField = 'dateCreated';
489
        $sortType = 'DESC';
490
        // Add a day since YYYY-MM-DD is really YYYY-MM-DD 00:00:00
491
        $end = date('Y-m-d', strtotime($end.'+1 day'));
492
        $pageUrl = urldecode($pageUrl);
493
        // Figure out the sorting type
494
        if ($sort !== '') {
495
            if (strpos($sort, '|') === false) {
496
                $sortField = $sort;
497
            } else {
498
                list($sortField, $sortType) = explode('|', $sort);
499
            }
500
        }
501
        // Query the db table
502
        $offset = ($page - 1) * $per_page;
503
        $query = (new Query())
504
            ->from(['{{%webperf_error_samples}}'])
505
            ->offset($offset)
506
            ->where(['url' => $pageUrl])
507
            ->andWhere(['between', 'dateCreated', $start, $end])
0 ignored issues
show
Coding Style introduced by
Space after closing parenthesis of function call prohibited
Loading history...
508
        ;
509
        if ((int)$siteId !== 0) {
510
            $query->andWhere(['siteId' => $siteId]);
511
        }
512
        if ($filter !== '') {
513
            $query
514
                ->andWhere(['like', 'pageErrors', $filter])
515
                /*
516
                ->orWhere(['like', 'device', $filter])
517
                ->orWhere(['like', 'os', $filter])
518
                ->orWhere(['like', 'browser', $filter])
519
                ->orWhere(['like', 'countryCode', $filter])
520
                */
521
            ;
522
        }
523
        $query
524
            ->orderBy("{$sortField} {$sortType}")
525
            ->limit($per_page)
0 ignored issues
show
Coding Style introduced by
Space after closing parenthesis of function call prohibited
Loading history...
526
        ;
527
        $stats = $query->all();
528
        if ($stats) {
529
            $user = Craft::$app->getUser()->getIdentity();
530
            // Massage the stats
531
            foreach ($stats as &$stat) {
532
                if (!empty($stats['dateCreated'])) {
533
                    $date = DateTimeHelper::toDateTime($stats['dateCreated']);
534
                    $stats['dateCreated'] = $date->format('Y-m-d H:i:s');
535
                }
536
                if (isset($stat['mobile'])) {
537
                    $stat['mobile'] = (bool)$stat['mobile'];
538
                }
539
                // Decode any emojis in the title
540
                if (!empty($stat['title'])) {
541
                    $stat['title'] = html_entity_decode($stat['title'], ENT_NOQUOTES, 'UTF-8');
542
                }
543
                $stat['deleteLink'] = UrlHelper::actionUrl('webperf/error-samples/delete-sample-by-id', [
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
544
                    'id' => $stat['id']
545
                ]);
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
546
                // Override based on permissions
547
                if (!$user->can('webperf:delete-error-samples')) {
548
                    $stat['deleteLink'] = '';
549
                }
550
            }
551
            // Format the data for the API
552
            $data['data'] = $stats;
553
            $query = (new Query())
554
                ->select(['[[url]]'])
555
                ->from(['{{%webperf_error_samples}}'])
556
                ->where(['url' => $pageUrl])
557
                ->andWhere(['between', 'dateCreated', $start, $end])
0 ignored issues
show
Coding Style introduced by
Space after closing parenthesis of function call prohibited
Loading history...
558
            ;
559
            if ($filter !== '') {
560
                $query
561
                    ->andWhere(['like', 'pageErrors', $filter])
562
                    /*
563
                    ->orWhere(['like', 'device', $filter])
564
                    ->orWhere(['like', 'os', $filter])
565
                    ->orWhere(['like', 'browser', $filter])
566
                    ->orWhere(['like', 'countryCode', $filter])
567
                    */
568
                ;
569
            }
570
            $count = $query->count();
571
            $data['links']['pagination'] = [
572
                'total' => $count,
573
                'per_page' => $per_page,
574
                'current_page' => $page,
575
                'last_page' => ceil($count / $per_page),
576
                'next_page_url' => null,
577
                'prev_page_url' => null,
578
                'from' => $offset + 1,
579
                'to' => $offset + ($count > $per_page ? $per_page : $count),
580
            ];
581
        }
582
583
        return $this->asJson($data);
584
    }
585
586
    // Protected Methods
587
    // =========================================================================
588
}
589