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 ( f92a7f...7a9465 )
by Brett
17:02 queued 04:26
created

AuditTrailBehavior::auditAttributes()   B

Complexity

Conditions 6
Paths 18

Size

Total Lines 28
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 6

Importance

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