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
Pull Request — master (#191)
by Herbert
10:39
created

AuditTrailBehavior::saveAuditTrail()   B

Complexity

Conditions 5
Paths 10

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 5

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 18
ccs 14
cts 14
cp 1
rs 8.8571
cc 5
eloc 10
nc 10
nop 8
crap 5

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
namespace bedezign\yii2\audit;
3
4
use Yii;
5
use yii\base\Behavior;
6
use yii\db\ActiveRecord;
7
use bedezign\yii2\audit\models\AuditTrail;
8
use yii\db\Query;
9
10
/**
11
 * Class AuditTrailBehavior
12
 * @package bedezign\yii2\audit
13
 *
14
 * @property \yii\db\ActiveRecord $owner
15
 */
16
class AuditTrailBehavior extends Behavior
17
{
18
19
    /**
20
     * Array with fields to save
21
     * You don't need to configure both `allowed` and `ignored`
22
     * @var array
23
     */
24
    public $allowed = [];
25
26
    /**
27
     * Array with fields to ignore
28
     * You don't need to configure both `allowed` and `ignored`
29
     * @var array
30
     */
31
    public $ignored = [];
32
33
    /**
34
     * Array with classes to ignore
35
     * @var array
36
     */
37
    public $ignoredClasses = [];
38
39
    /**
40
     * Timestamp attributes should, in most cases, be ignored. If both AudittrailBehavior and
41
     * TimestampBehavior logs the created_at and updated_at fields, the data is saved twice.
42
     * In case you want to log them, you can unset the column from this timestamp column name suggestions.
43
     * Set to null to disable this filter and log all columns.
44
     * @var null|array
45
     */
46
    public $timestamp_fields = ['created', 'updated', 'created_at', 'updated_at', 'timestamp'];
47
48
    /**
49
     * Is the behavior is active or not
50
     * @var boolean
51
     */
52
    public $active = true;
53
54
    /**
55
     * Date format to use in stamp - set to "Y-m-d H:i:s" for datetime or "U" for timestamp
56
     * @var string
57
     */
58
    public $dateFormat = 'Y-m-d H:i:s';
59
60
    /**
61
     * @var array
62
     */
63
    private $_oldAttributes = [];
64
65
    /**
66
     * Array with fields you want to override before saving the row into audit_trail table
67
     * @var array
68
     */
69
    public $override = [];
70
71
    /**
72
     * @inheritdoc
73
     */
74 38
    public function events()
75
    {
76
        return [
77 38
            ActiveRecord::EVENT_AFTER_FIND => 'afterFind',
78 38
            ActiveRecord::EVENT_AFTER_INSERT => 'afterInsert',
79 38
            ActiveRecord::EVENT_AFTER_UPDATE => 'afterUpdate',
80 38
            ActiveRecord::EVENT_AFTER_DELETE => 'afterDelete',
81 38
        ];
82
    }
83
84
    /**
85
     *
86
     */
87 30
    public function afterFind()
88
    {
89 30
        $this->setOldAttributes($this->owner->getAttributes());
90 30
    }
91
92
    /**
93
     *
94
     */
95 16
    public function afterInsert()
96
    {
97 16
        $this->audit('CREATE');
98 16
        $this->setOldAttributes($this->owner->getAttributes());
99 16
    }
100
101
    /**
102
     *
103
     */
104 18
    public function afterUpdate()
105
    {
106 18
        $this->audit('UPDATE');
107 18
        $this->setOldAttributes($this->owner->getAttributes());
108 18
    }
109
110
    /**
111
     *
112
     */
113 8
    public function afterDelete()
114
    {
115 8
        $this->audit('DELETE');
116 8
        $this->setOldAttributes([]);
117 8
    }
118
119
    /**
120
     * @param $action
121
     * @throws \yii\db\Exception
122
     */
123 38
    public function audit($action)
124
    {
125
        // Not active? get out of here
126 38
        if (!$this->active) {
127 6
            return;
128
        }
129
        // Lets check if the whole class should be ignored
130 32
        if (sizeof($this->ignoredClasses) > 0 && array_search(get_class($this->owner), $this->ignoredClasses) !== false) {
131 6
            return;
132
        }
133
        // If this is a delete then just write one row and get out of here
134 26
        if ($action == 'DELETE') {
135 4
            $this->saveAuditTrailDelete();
136 4
            return;
137
        }
138
        // Now lets actually write the attributes
139 22
        $this->auditAttributes($action);
140 22
    }
141
142
    /**
143
     * Clean attributes of fields that are not allowed or ignored.
144
     *
145
     * @param $attributes
146
     * @return mixed
147
     */
148 22
    protected function cleanAttributes($attributes)
149
    {
150 22
        $attributes = $this->cleanAttributesAllowed($attributes);
151 22
        $attributes = $this->cleanAttributesIgnored($attributes);
152 22
        $attributes = $this->cleanAttributesOverride($attributes);
153 22
        return $attributes;
154
    }
155
156
    /**
157
     * Unset attributes which are not allowed
158
     *
159
     * @param $attributes
160
     * @return mixed
161
     */
162 22
    protected function cleanAttributesAllowed($attributes)
163
    {
164 22
        if (sizeof($this->allowed) > 0) {
165 4
            foreach ($attributes as $f => $v) {
166 4
                if (array_search($f, $this->allowed) === false) {
167 4
                    unset($attributes[$f]);
168 4
                }
169 4
            }
170 4
        }
171 22
        return $attributes;
172
    }
173
174
    /**
175
     * Unset attributes which are ignored
176
     *
177
     * @param $attributes
178
     * @return mixed
179
     */
180 22
    protected function cleanAttributesIgnored($attributes)
181
    {
182 22
        if(is_array($this->timestamp_fields) && count($this->timestamp_fields) > 0) {
183 22
            $this->ignored = array_merge($this->ignored, $this->timestamp_fields);
184 22
        }
185
186 22
        if (count($this->ignored) > 0) {
187 22
            foreach ($attributes as $f => $v) {
188 22
                if (array_search($f, $this->ignored) !== false) {
189 4
                    unset($attributes[$f]);
190 4
                }
191 22
            }
192 22
        }
193 22
        return $attributes;
194
    }
195
196
    /**
197
     * attributes which need to get override with a new value
198
     *
199
     * @param $attributes
200
     * @return mixed
201
     */
202 22
    protected function cleanAttributesOverride($attributes)
203
    {
204 22
        if (sizeof($this->override) > 0 && sizeof($attributes) >0) {
205
            foreach ($this->override as $field => $queryParams) {
206
                $newOverrideValues = $this->getNewOverrideValues($attributes[$field], $queryParams);
207
                $saveField = \yii\helpers\ArrayHelper::getValue($queryParams, 'saveField', $field);
208
209
                if (count($newOverrideValues) >1) {
210
                    $attributes[$saveField] = implode(', ',
211
                                        \yii\helpers\ArrayHelper::map($newOverrideValues, $queryParams['returnField'], $queryParams['returnField'])
212
                    );
213
                } elseif (count($newOverrideValues) == 1) {
214
                    $attributes[$saveField] = $newOverrideValues[0][$queryParams['returnField']];
215
                }
216
            }
217
        }
218 22
        return $attributes;
219
    }
220
221
    /**
222
     * @param string $searchFieldValue
223
     * @param string $queryParams
224
     * @return mixed
225
     */
226
    private function getNewOverrideValues($searchFieldValue, $queryParams)
227
    {
228
        $query = new Query;
229
230
        $query->select($queryParams['returnField'])
231
              ->from($queryParams['tableName'])
232
              ->where([$queryParams['searchField'] => $searchFieldValue]);
233
234
        $rows = $query->all();
235
236
        return $rows;
237
    }
238
239
240
    /**
241
     * @param string $action
242
     * @throws \yii\db\Exception
243
     */
244 22
    protected function auditAttributes($action)
245
    {
246
        // Get the new and old attributes
247 22
        $newAttributes = $this->cleanAttributes($this->owner->getAttributes());
248 22
        $oldAttributes = $this->cleanAttributes($this->getOldAttributes());
249
        // If no difference then get out of here
250 22
        if (count(array_diff_assoc($newAttributes, $oldAttributes)) <= 0) {
251 2
            return;
252
        }
253
        // Get the trail data
254 20
        $entry_id = $this->getAuditEntryId();
255 20
        $user_id = $this->getUserId();
256 20
        $model = $this->owner->className();
257 20
        $model_id = $this->getNormalizedPk();
258 20
        $created = date($this->dateFormat);
259
260 20
        $this->saveAuditTrail($action, $newAttributes, $oldAttributes, $entry_id, $user_id, $model, $model_id, $created);
261 20
    }
262
263
    /**
264
     * Save the audit trails for a create or update action
265
     *
266
     * @param $action
267
     * @param $newAttributes
268
     * @param $oldAttributes
269
     * @param $entry_id
270
     * @param $user_id
271
     * @param $model
272
     * @param $model_id
273
     * @param $created
274
     * @throws \yii\db\Exception
275
     */
276 24
    protected function saveAuditTrail($action, $newAttributes, $oldAttributes, $entry_id, $user_id, $model, $model_id, $created)
277
    {
278
        // Build a list of fields to log
279 20
        $rows = array();
280 20
        foreach ($newAttributes as $field => $new) {
281 20
            $old = isset($oldAttributes[$field]) ? $oldAttributes[$field] : '';
282
            // If they are not the same lets write an audit log
283 20
            if ($new != $old) {
284 20
                $rows[] = [$entry_id, $user_id, $old, $new, $action, $model, $model_id, $field, $created];
285 20
            }
286 20
        }
287
        // Record the field changes with a batch insert
288 20
        if (!empty($rows)) {
289 20
            $columns = ['entry_id', 'user_id', 'old_value', 'new_value', 'action', 'model', 'model_id', 'field', 'created'];
290 20
            $audit = Audit::getInstance();
291 20
            $audit->getDb()->createCommand()->batchInsert(AuditTrail::tableName(), $columns, $rows)->execute();
292 20
        }
293 24
    }
294
295
    /**
296
     * Save the audit trails for a delete action
297
     */
298 24
    protected function saveAuditTrailDelete()
299
    {
300 4
        $audit = Audit::getInstance();
301 4
        $audit->getDb()->createCommand()->insert(AuditTrail::tableName(), [
302 4
            'action' => 'DELETE',
303 4
            'entry_id' => $this->getAuditEntryId(),
304 24
            'user_id' => $this->getUserId(),
305 4
            'model' => $this->owner->className(),
306 4
            'model_id' => $this->getNormalizedPk(),
307 4
            'created' => date($this->dateFormat),
308 4
        ])->execute();
309 4
    }
310
311
    /**
312
     * @return array
313
     */
314 22
    public function getOldAttributes()
315
    {
316 22
        return $this->_oldAttributes;
317
    }
318
319
    /**
320
     * @param $value
321
     */
322 38
    public function setOldAttributes($value)
323
    {
324 38
        $this->_oldAttributes = $value;
325 38
    }
326
327
    /**
328
     * @return string
329
     */
330 24
    protected function getNormalizedPk()
331
    {
332 24
        $pk = $this->owner->getPrimaryKey();
333 24
        return is_array($pk) ? json_encode($pk) : $pk;
334
    }
335
336
    /**
337
     * @return int|null|string
338
     */
339 24
    protected function getUserId()
340
    {
341 24
        return Audit::getInstance()->getUserId();
342
    }
343
344
    /**
345
     * @return models\AuditEntry|null|static
346
     * @throws \Exception
347
     */
348 24
    protected function getAuditEntryId()
349
    {
350 24
        $module = Audit::getInstance();
351 24
        if (!$module) {
352
            $module = \Yii::$app->getModule(Audit::findModuleIdentifier());
353
        }
354 24
        if (!$module) {
355
            throw new \Exception('Audit module cannot be loaded');
356
        }
357 24
        return Audit::getInstance()->getEntry(true)->id;
358
    }
359
360
}
361