Passed
Push — master ( 7ce3f4...5e32cd )
by for
14:35
created

LoggerBehavior   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 123
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 55
c 2
b 0
f 0
dl 0
loc 123
rs 10
wmc 26

7 Methods

Rating   Name   Duplication   Size   Complexity  
A paramReplace() 0 3 1
A headerFilter() 0 8 4
A paramPartialHiddenReplace() 0 14 2
C paramsFilter() 0 19 12
A events() 0 5 1
A beforeSend() 0 29 5
A beforeAction() 0 3 1
1
<?php
2
3
namespace app\core\behaviors;
4
5
use Yii;
6
use yii\base\Behavior;
7
use yii\helpers\ArrayHelper;
8
use yii\helpers\Json;
9
use yii\web\Controller;
10
use yii\web\Response;
11
12
class LoggerBehavior extends Behavior
13
{
14
    public function events()
15
    {
16
        return [
17
            Response::EVENT_BEFORE_SEND => 'beforeSend',
18
            Controller::EVENT_BEFORE_ACTION => 'beforeAction'
19
        ];
20
    }
21
22
    /**
23
     * @param $event
24
     * @throws \Exception
25
     */
26
    public function beforeSend($event)
27
    {
28
        $response = $event->sender;
29
        if ($response->format != 'html') {
30
            $request = \Yii::$app->request;
31
            $params = Yii::$app->params;
32
            $requestId = Yii::$app->requestId->id;
33
            $code = ArrayHelper::getValue($response->data, 'code');
34
35
            $ignoredKeys = explode(',', ArrayHelper::getValue($params, 'logFilterIgnoredKeys', ''));
36
            $hideKeys = explode(',', ArrayHelper::getValue($params, 'logFilterHideKeys', ''));
37
            $halfHideKeys = explode(',', ArrayHelper::getValue($params, 'logFilterHalfHideKeys', ''));
38
            $ignoredHeaderKeys = explode(',', ArrayHelper::getValue($params, 'logFilterIgnoredHeaderKeys', ''));
39
            $requestHeaderParams = $this->headerFilter($request->headers->toArray(), $ignoredHeaderKeys);
40
41
            $requestParams = $this->paramsFilter($request->bodyParams, $ignoredKeys, $hideKeys, $halfHideKeys);
42
43
            $message = [
44
                'request_id' => $requestId,
45
                'type' => $code === 0 ? 'response_data_success' : 'response_data_error',
46
                'header' => Json::encode($requestHeaderParams),
47
                'params' => Json::encode($requestParams),
48
                'url' => $request->absoluteUrl,
49
                'response' => Json::encode($response->data)
50
            ];
51
            if (is_array($response->data)) {
52
                $response->data = ['request_id' => $requestId] + $response->data;
53
            }
54
            $code === 0 ? Yii::info($message, 'request') : Yii::error($message, 'request');
55
        }
56
    }
57
58
    public function beforeAction()
59
    {
60
        return Yii::$app->requestId->id;
61
    }
62
63
64
    /**
65
     * @param array $params
66
     * @param array $ignoredHeaderKeys
67
     * @return array
68
     */
69
    protected function headerFilter(array $params, array $ignoredHeaderKeys)
70
    {
71
        foreach ($params as $key => $item) {
72
            if ($key && in_array($key, $ignoredHeaderKeys)) {
73
                unset($params[$key]);
74
            }
75
        }
76
        return $params;
77
    }
78
79
    /**
80
     * @param $params array
81
     * @param array $ignoredKeys
82
     * @param array $hideKeys
83
     * @param array $halfHideKeys
84
     * @return string|int|array
85
     */
86
    protected function paramsFilter(array $params, array $ignoredKeys, array $hideKeys, array $halfHideKeys)
87
    {
88
        if (!$hideKeys && !$halfHideKeys && !$ignoredKeys) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $ignoredKeys of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
Bug Best Practice introduced by
The expression $hideKeys of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
Bug Best Practice introduced by
The expression $halfHideKeys of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
89
            return $params;
90
        }
91
        foreach ($params as $key => &$item) {
92
            if (is_array($item)) {
93
                $item = $this->paramsFilter($item, $ignoredKeys, $hideKeys, $halfHideKeys);
94
                continue;
95
            }
96
            if ($key && in_array($key, $ignoredKeys)) {
97
                unset($params[$key]);
98
            } elseif ($key && in_array($key, $hideKeys)) {
99
                $item = $this->paramReplace($item);
100
            } elseif ($key && in_array($key, $halfHideKeys)) {
101
                $item = $this->paramPartialHiddenReplace($item);
102
            }
103
        }
104
        return $params;
105
    }
106
107
    /**
108
     * @param string $value
109
     * @return string
110
     */
111
    protected function paramReplace(string $value)
112
    {
113
        return str_repeat('*', strlen($value));
114
    }
115
116
117
    /**
118
     * @param $value
119
     * @return string
120
     */
121
    protected function paramPartialHiddenReplace(string $value)
122
    {
123
        $valueLength = strlen($value);
124
        if ($valueLength > 2) {
125
            $showLength = ceil($valueLength * 0.2);
126
            $hideLength = $valueLength - $showLength * 2;
127
            $newValue = mb_substr($value, 0, $showLength)
0 ignored issues
show
Bug introduced by
$showLength of type double is incompatible with the type integer|null expected by parameter $length of mb_substr(). ( Ignorable by Annotation )

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

127
            $newValue = mb_substr($value, 0, /** @scrutinizer ignore-type */ $showLength)
Loading history...
128
                . str_repeat('*', $hideLength)
0 ignored issues
show
Bug introduced by
$hideLength of type double is incompatible with the type integer expected by parameter $times of str_repeat(). ( Ignorable by Annotation )

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

128
                . str_repeat('*', /** @scrutinizer ignore-type */ $hideLength)
Loading history...
129
                . mb_substr($value, -1 * $showLength);
0 ignored issues
show
Bug introduced by
-1 * $showLength of type double is incompatible with the type integer expected by parameter $start of mb_substr(). ( Ignorable by Annotation )

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

129
                . mb_substr($value, /** @scrutinizer ignore-type */ -1 * $showLength);
Loading history...
130
        } else {
131
            $newValue = $this->paramReplace($value);
132
        }
133
134
        return $newValue;
135
    }
136
}
137