Completed
Push — master ( ea4f60...1c3eca )
by Mark
02:32 queued 01:18
created

QueryListener   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 102
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 14
lcom 1
cbo 3
dl 0
loc 102
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
B listen() 0 35 7
A getPossibleTraces() 0 12 3
A formatPossibleTraces() 0 16 3
A formatData() 0 17 1
1
<?php
2
3
namespace Socialblue\LaravelQueryAdviser\DataListener;
4
5
use Illuminate\Database\Events\QueryExecuted;
6
use Illuminate\Support\Facades\Cache;
7
use Socialblue\LaravelQueryAdviser\Helper\QueryBuilderHelper;
8
9
class QueryListener {
10
11
    public static function listen(QueryExecuted $query) {
12
        if (config('laravel-query-adviser.enable_query_logging') === false) {
13
            return;
14
        }
15
16
        $url = url()->current();
17
        if (strpos($url, '/query-adviser') !== false) {
18
            return;
19
        }
20
        $time = time();
21
        $referer = request()->headers->get('referer');
22
23
        if (empty($url)) {
24
            $url = '';
25
        }
26
27
        $data = Cache::get(config('laravel-query-adviser.cache.key'), []);
28
        if (!is_array($data)) {
29
            $data = [];
30
        }
31
32
        if (!isset($data[$time])) {
33
            $data[$time] = [];
34
        }
35
36
        $possibleTraces = self::formatPossibleTraces(self::getPossibleTraces());
37
38
        $data = self::formatData($query, $data, $time, $possibleTraces, $url, $referer);
39
40
        if (count($data) > config('laravel-query-adviser.cache.max_entries')) {
41
            array_shift($data);
42
        }
43
44
        Cache::put(config('laravel-query-adviser.cache.key'), $data, config('laravel-query-adviser.cache.ttl'));
45
    }
46
47
    /**
48
     * @return array
49
     */
50
    protected static function getPossibleTraces(): array
51
    {
52
        $possibleTraces = array_filter(debug_backtrace(\DEBUG_BACKTRACE_PROVIDE_OBJECT, 25),
53
            static function ($trace) {
54
                return isset($trace['file']) &&
55
                    strpos($trace['file'], '/var/www/app/') !== false &&
56
                    isset($trace['object']);
57
58
            }
59
        );
60
        return $possibleTraces;
61
    }
62
63
    /**
64
     * @param possibleTraces
65
     * @return mixed
66
     */
67
    protected static function formatPossibleTraces($possibleTraces)
68
    {
69
        array_walk($possibleTraces, static function (&$trace) {
70
            if (method_exists($trace['object'], 'getModel')) {
71
                $a = $trace['object']->getModel();
72
                if (is_string($a)) {
73
                    $trace['model'] = $a;
74
                } else {
75
                    $trace['model'] = get_class($a);
76
                }
77
            }
78
            unset($trace['object']);
79
            unset($trace['args']);
80
        });
81
        return $possibleTraces;
82
    }
83
84
    /**
85
     * @param QueryExecuted $query
86
     * @param array $data
87
     * @param int $time
88
     * @param $possibleTraces
89
     * @param string $url
90
     * @param string|null $referer
91
     * @return array
92
     */
93
    protected static function formatData(QueryExecuted $query, array $data, int $time, $possibleTraces, string $url, ?string $referer): array
94
    {
95
        $key = count($data[$time]);
96
97
        $data[$time][$key] = [
98
            'time'      => $time,
99
            'timeKey'   => $key,
100
            'backtrace' => $possibleTraces,
101
            'sql'       => QueryBuilderHelper::combineQueryAndBindings($query->sql, $query->bindings),
102
            'rawSql'    => $query->sql,
103
            'bindings'  => $query->bindings,
104
            'queryTime' => $query->time,
105
            'url'       => $url,
106
            'referer'   => $referer,
107
        ];
108
        return $data;
109
    }
110
}
111