Passed
Push — develop ( 0ddaa0...84fc18 )
by Andrew
03:29
created

ErrorSamples::deleteAllErrorSamples()   A

Complexity

Conditions 3
Paths 5

Size

Total Lines 19
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 13
dl 0
loc 19
rs 9.8333
c 0
b 0
f 0
cc 3
nc 5
nop 1
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\services;
12
13
use nystudio107\webperf\Webperf;
14
use nystudio107\webperf\base\DbErrorSampleInterface;
15
16
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...
17
use craft\base\Component;
0 ignored issues
show
Bug introduced by
The type craft\base\Component 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\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...
19
20
/**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
21
 * @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...
22
 * @package   Webperf
0 ignored issues
show
Coding Style introduced by
Tag value indented incorrectly; expected 1 spaces but found 3
Loading history...
23
 * @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...
24
 */
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...
25
class ErrorSamples extends Component
26
{
27
    // Constants
28
    // =========================================================================
29
30
    // Public Methods
31
    // =========================================================================
32
33
    /**
34
     * Get the total number of errors optionally limited by siteId
35
     *
36
     * @param int    $siteId
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
37
     * @param string $column
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
38
     *
39
     * @return int|string
40
     */
41
    public function totalErrorSamples(int $siteId, string $column)
42
    {
43
        // Get the total number of errors
44
        $query = (new Query())
45
            ->from(['{{%webperf_error_samples}}'])
46
            ->where(['not', [$column => null]])
0 ignored issues
show
Coding Style introduced by
Space after closing parenthesis of function call prohibited
Loading history...
47
            ;
48
        if ((int)$siteId !== 0) {
49
            $query->andWhere(['siteId' => $siteId]);
50
        }
51
52
        return $query->count();
53
    }
54
55
    /**
56
     * Get the page title from errors by URL and optionally siteId
57
     *
58
     * @param string   $url
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter type; 3 found
Loading history...
59
     * @param int $siteId
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 4 spaces after parameter type; 1 found
Loading history...
60
     *
61
     * @return string
62
     */
63
    public function pageTitle(string $url, int $siteId = 0): string
64
    {
65
        // Get the page title from a URL
66
        $query = (new Query())
67
            ->select(['title'])
68
            ->from(['{{%webperf_error_samples}}'])
69
            ->where([
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...
70
                'and', ['url' => $url],
71
                ['not', ['title' => '']],
72
            ])
0 ignored issues
show
Coding Style introduced by
Space after closing parenthesis of function call prohibited
Loading history...
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...
73
        ;
74
        if ((int)$siteId !== 0) {
75
            $query->andWhere(['siteId' => $siteId]);
76
        }
77
        $result = $query->one();
78
        // Decode any emojis in the title
79
        if (!empty($result['title'])) {
80
            $result['title'] = html_entity_decode($result['title'], ENT_NOQUOTES, 'UTF-8');
81
        }
82
83
        return $result['title'] ?? '';
84
    }
85
86
    /**
87
     * Add an error to the webperf_error_samples table
88
     *
89
     * @param DbErrorSampleInterface $errorSample
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
90
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
91
    public function addErrorSample(DbErrorSampleInterface $errorSample)
92
    {
93
        // Validate the model before saving it to the db
94
        if ($errorSample->validate() === false) {
95
            Craft::error(
96
                Craft::t(
97
                    'webperf',
98
                    'Error validating error sample: {errors}',
99
                    ['errors' => print_r($errorSample->getErrors(), true)]
100
                ),
101
                __METHOD__
102
            );
103
104
            return;
105
        }
106
        // Get the validated model attributes and save them to the db
107
        $errorSampleConfig = $errorSample->getAttributes();
108
        $db = Craft::$app->getDb();
109
        Craft::debug('Creating new error sample', __METHOD__);
110
        // Create a new record
111
        try {
112
            $result = $db->createCommand()->insert(
113
                '{{%webperf_error_samples}}',
114
                $errorSampleConfig
115
            )->execute();
116
            Craft::debug($result, __METHOD__);
117
        } catch (\Exception $e) {
118
            Craft::error($e->getMessage(), __METHOD__);
119
        }
120
        // After adding the ErrorSample, trim the webperf_error_samples db table
121
        if (Webperf::$settings->automaticallyTrimErrorSamples) {
122
            $this->trimErrorSamples();
123
        }
124
    }
125
126
    /**
127
     * Delete a error sample by id
128
     *
129
     * @param int $id
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
130
     *
131
     * @return int The result
132
     */
133
    public function deleteErrorSampleById(int $id): int
134
    {
135
        $db = Craft::$app->getDb();
136
        // Delete a row from the db table
137
        try {
138
            $result = $db->createCommand()->delete(
139
                '{{%webperf_error_samples}}',
140
                [
141
                    'id' => $id,
142
                ]
143
            )->execute();
144
        } catch (\Exception $e) {
145
            Craft::error($e->getMessage(), __METHOD__);
146
            $result = 0;
147
        }
148
149
        return $result;
150
    }
151
152
    /**
153
     * Delete error samples by URL and optionally siteId
154
     *
155
     * @param string   $url
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
156
     * @param int|null $siteId
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
157
     *
158
     * @return int
159
     */
160
    public function deleteErrorSamplesByUrl(string $url, int $siteId = null): int
161
    {
162
        $db = Craft::$app->getDb();
163
        // Delete a row from the db table
164
        try {
165
            $conditions = ['url' => $url];
166
            if ($siteId !== null) {
167
                $conditions['siteId'] = $siteId;
168
            }
169
            $result = $db->createCommand()->delete(
170
                '{{%webperf_error_samples}}',
171
                $conditions
172
            )->execute();
173
        } catch (\Exception $e) {
174
            Craft::error($e->getMessage(), __METHOD__);
175
            $result = 0;
176
        }
177
178
        return $result;
179
    }
180
181
    /**
182
     * Delete all error samples optionally siteId
183
     *
184
     * @param int|null $siteId
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
185
     *
186
     * @return int
187
     */
188
    public function deleteAllErrorSamples(int $siteId = null): int
189
    {
190
        $db = Craft::$app->getDb();
191
        // Delete a row from the db table
192
        try {
193
            $conditions = [];
194
            if ($siteId !== null) {
195
                $conditions['siteId'] = $siteId;
196
            }
197
            $result = $db->createCommand()->delete(
198
                '{{%webperf_error_samples}}',
199
                $conditions
200
            )->execute();
201
        } catch (\Exception $e) {
202
            Craft::error($e->getMessage(), __METHOD__);
203
            $result = 0;
204
        }
205
206
        return $result;
207
    }
208
209
    /**
210
     * Trim the webperf_error_samples db table based on the errorSamplesStoredLimit
211
     * config.php setting
212
     *
213
     * @param int|null $limit
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
214
     *
215
     * @return int
216
     */
217
    public function trimErrorSamples(int $limit = null): int
218
    {
219
        $affectedRows = 0;
220
        $db = Craft::$app->getDb();
221
        $quotedTable = $db->quoteTableName('{{%webperf_error_samples}}');
222
        $limit = $limit ?? Webperf::$settings->errorSamplesStoredLimit;
223
224
        if ($limit !== null) {
225
            //  https://stackoverflow.com/questions/578867/sql-query-delete-all-records-from-the-table-except-latest-n
226
            try {
227
                if ($db->getIsMysql()) {
228
                    // Handle MySQL
229
                    $affectedRows = $db->createCommand(/** @lang mysql */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
230
                        "
231
                        DELETE FROM {$quotedTable}
232
                        WHERE id NOT IN (
233
                          SELECT id
234
                          FROM (
235
                            SELECT id
236
                            FROM {$quotedTable}
237
                            ORDER BY dateCreated DESC
238
                            LIMIT {$limit}
239
                          ) foo
240
                        )
241
                        "
242
                    )->execute();
243
                }
244
                if ($db->getIsPgsql()) {
245
                    // Handle Postgres
246
                    $affectedRows = $db->createCommand(/** @lang mysql */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
247
                        "
248
                        DELETE FROM {$quotedTable}
249
                        WHERE id NOT IN (
250
                          SELECT id
251
                          FROM (
252
                            SELECT id
253
                            FROM {$quotedTable}
254
                            ORDER BY \"dateCreated\" DESC
255
                            LIMIT {$limit}
256
                          ) foo
257
                        )
258
                        "
259
                    )->execute();
260
                }
261
            } catch (\Exception $e) {
262
                Craft::error($e->getMessage(), __METHOD__);
263
            }
264
            Craft::info(
265
                Craft::t(
266
                    'webperf',
267
                    'Trimmed {rows} from webperf_error_samples table',
268
                    ['rows' => $affectedRows]
269
                ),
270
                __METHOD__
271
            );
272
        }
273
274
        return $affectedRows;
275
    }
276
}
277