Passed
Push — master ( bb8bc9...9a5af0 )
by Paul
03:47
created

SlowActions::stopTimer()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 4
nc 1
nop 1
dl 0
loc 6
rs 10
c 1
b 0
f 0
1
<?php
2
3
namespace GeminiLabs\BlackBar;
4
5
class SlowActions
6
{
7
    /**
8
     * @var array
9
     */
10
    protected $flow;
11
12
    /**
13
     * This is the time that WordPress takes to execute the all hook.
14
     * @var int
15
     */
16
    protected $noise = 0;
17
18
    /**
19
     * @var int
20
     */
21
    protected $start = null;
22
23
    /**
24
     * @var int
25
     */
26
    protected $stop = null;
27
28
    /**
29
     * @var int
30
     */
31
    protected $totalActions = 0;
32
33
    /**
34
     * @var int
35
     */
36
    protected $totalTime = 0;
37
38
    public function __construct()
39
    {
40
        $this->flow = [];
41
        $this->start = microtime(true);
42
    }
43
44
    /**
45
     * @return array
46
     */
47
    public function getTotalTimeForHook(array $data)
48
    {
49
        $total = 0;
50
        foreach ($data['time'] as $time) {
51
            $total += ($time['stop'] - $time['start']) * 1000;
52
        }
53
        return $total;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $total returns the type integer which is incompatible with the documented return type array.
Loading history...
54
    }
55
56
    /**
57
     * @return array
58
     */
59
    public function addCallbacksForAction($action)
60
    {
61
        global $wp_filter;
62
        if (!array_key_exists($action, $this->flow)) {
63
            return;
64
        }
65
        $this->flow[$action]['callbacks_count'] = 0;
66
        foreach ($wp_filter[$action] as $priority => $callbacks) {
67
            if (!array_key_exists($priority, $this->flow[$action]['callbacks'])) {
68
                $this->flow[$action]['callbacks'][$priority] = [];
69
            }
70
            foreach ($callbacks as $callback) {
71
                if (is_array($callback['function']) && 2 == count($callback['function'])) {
72
                    list($object, $method) = $callback['function'];
73
                    if (is_object($object)) {
74
                        $object = get_class($object);
75
                    }
76
                    $this->flow[$action]['callbacks'][$priority][] = sprintf('%s::%s', $object, $method);
77
                } elseif (is_object($callback['function'])) {
78
                    $this->flow[$action]['callbacks'][$priority][] = get_class($callback['function']);
79
                } else {
80
                    $this->flow[$action]['callbacks'][$priority][] = $callback['function'];
81
                }
82
                ++$this->flow[$action]['callbacks_count'];
83
            }
84
        }
85
    }
86
87
    /**
88
     * @return array
89
     */
90
    public function getMeasure()
91
    {
92
        foreach ($this->flow as $action => $data) {
93
            $total = $this->getTotalTimeForHook($data);
94
            $this->flow[$action]['total'] = $total;
95
            $this->totalTime += $total;
96
            $this->totalActions += $data['count'];
97
            $this->addCallbacksForAction($action);
98
        }
99
        uasort($this->flow, [$this, 'sortByTime']);
100
        return $this->flow;
101
    }
102
103
    /**
104
     * @return int
105
     */
106
    public function getTotalActions()
107
    {
108
        return $this->totalActions;
109
    }
110
111
    /**
112
     * @return int Microseconds
113
     */
114
    public function getTotalTime()
115
    {
116
        return $this->totalTime;
117
        // $totalNoise = (count($this->timers) - 1) * $this->noise;
118
        // return $this->stop - $this->start - $totalNoise;
119
    }
120
121
    /**
122
     * @param string $name
123
     * @return void
124
     */
125
    public function startTimer()
126
    {
127
        if (!isset($this->flow[current_filter()])) {
128
            $this->flow[current_filter()] = [
129
                'callbacks' => [],
130
                'count' => 0,
131
                'stack' => [],
132
                'time' => [],
133
            ];
134
            add_action(current_filter(), [$this, 'stopTimer'], 9000);
135
        }
136
        $count = ++$this->flow[current_filter()]['count'];
0 ignored issues
show
Unused Code introduced by
The assignment to $count is dead and can be removed.
Loading history...
137
        array_push($this->flow[current_filter()]['stack'], ['start' => microtime(true)]);
138
    }
139
140
    /**
141
     * @param mixed $possibleFilter
142
     * @return mixed
143
     */
144
    public function stopTimer($possibleFilter = null)
145
    {
146
        $time = array_pop($this->flow[current_filter()]['stack']);
147
        $time['stop'] = microtime(true);
148
        array_push($this->flow[current_filter()]['time'], $time);
149
        return $possibleFilter;
150
    }
151
152
    /**
153
     * @param array $a
154
     * @param array $b
155
     * @return int
156
     */
157
    protected function sortByTime($a, $b)
158
    {
159
        if ($a['total'] == $b['total']) {
160
            return 0;
161
        }
162
        return ($a['total'] > $b['total']) ? -1 : 1;
163
    }
164
}
165