Command   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 125
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
wmc 13
lcom 1
cbo 1
dl 0
loc 125
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A setSql() 0 8 2
A getCustomTag() 0 4 1
B getTraceTag() 0 18 6
A insertTags() 0 20 3
A getTraceLine() 0 6 1
1
<?php
2
namespace pastuhov\querytag;
3
4
/**
5
 * Query trace tagging.
6
 *
7
 * Before: 'SELECT * FROM page WHERE 1=1'
8
 * After: 'SELECT \/* EExampleTest:11 UnitHelper:28 Step:218 *\/ * FROM page WHERE 1=1'
9
 */
10
class Command extends \yii\db\Command
11
{
12
    /**
13
     * Trace tag.
14
     */
15
    const TAG_TYPE_TRACE = 'TraceTag';
16
    /**
17
     * Custom tag.
18
     */
19
    const TAG_TYPE_CUSTOM = 'CustomTag';
20
    /**
21
     * Script entry point tag.
22
     */
23
    const TAG_TYPE_ENTRY_POINT = 'EnryPointTag';
24
    /**
25
     * Enabled tags.
26
     *
27
     * @var array
28
     */
29
    public $enabledTags = [
30
        self::TAG_TYPE_TRACE,
31
    ];
32
    /**
33
     * Custom tag value.
34
     *
35
     * @var string
36
     */
37
    public $customTag = '';
38
    /**
39
     * Maximum trace entries in query.
40
     *
41
     * @var int
42
     */
43
    public $traceLevel = 4;
44
    /**
45
     * Maximum debug_backtrace() level param.
46
     *
47
     * @var int
48
     */
49
    public $backTraceLevel = 12;
50
51
    /**
52
     * @inheritdoc
53
     */
54
    public function setSql($sql)
55
    {
56
        if ($sql !== null) {
57
            $sql = $this->insertTags($sql);
58
        }
59
60
        return parent::setSql($sql);
61
    }
62
63
    /**
64
     * Generates custom tag.
65
     */
66
    protected function getCustomTag()
67
    {
68
        return $this->customTag;
69
    }
70
71
    /**
72
     * Generates trace tag.
73
     *
74
     * @return string
75
     */
76
    protected function getTraceTag(): string
77
    {
78
        $count = 0;
79
        $traces = [];
80
        $ts = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, $this->backTraceLevel);
81
        array_pop($ts); // remove the last trace since it would be the entry script, not very useful
82
        foreach ($ts as $trace) {
83
            if (isset($trace['file'], $trace['line']) && strpos($trace['file'], YII2_PATH) !== 0 && strpos($trace['file'], __DIR__) !== 0) {
84
                unset($trace['object'], $trace['args']);
85
                $traces[] = $this->getTraceLine($trace);
86
                if (++$count >= $this->traceLevel) {
87
                    break;
88
                }
89
            }
90
        }
91
92
        return implode(' ', $traces);
93
    }
94
95
    /**
96
     * Inserts tags into query string.
97
     *
98
     * @param string $sql Query.
99
     * @return string
100
     */
101
    protected function insertTags(string $sql): string
102
    {
103
        $position = strpos($sql, ' ');
104
105
        if ($position !== false) {
106
            $tags = [];
107
            foreach ($this->enabledTags as $tag) {
108
                $tags[] = $this->{'get' . $tag}();
109
            }
110
111
            $sql = substr_replace(
112
                $sql,
113
                ' /* ' . implode(' ', $tags) . ' */',
114
                $position,
115
                0
116
            );
117
        }
118
119
        return $sql;
120
    }
121
122
    /**
123
     * Trace entry.
124
     *
125
     * @param array $trace Trace properties array.
126
     * @return string
127
     */
128
    protected function getTraceLine(array $trace): string
129
    {
130
        $line = basename($trace['file'], '.php') . ':' . $trace['line'];
131
132
        return $line;
133
    }
134
}
135