Completed
Push — master ( 3bd469...f9d5ad )
by Tobias
12:41
created

BaseCollector::getFailedStacks()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1.037

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 2
cts 3
cp 0.6667
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 1.037
1
<?php
2
3
namespace Http\HttplugBundle\Collector;
4
5
use Symfony\Component\HttpKernel\Kernel;
6
use Symfony\Component\HttpFoundation\Request;
7
use Symfony\Component\HttpFoundation\Response;
8
use Symfony\Component\HttpKernel\DataCollector\DataCollector;
9
use Throwable;
10
11
/**
12
 * The Collector hold profiled Stacks pushed by StackPlugin. It also have a list of configured clients.
13
 * All those data are used to display the HTTPlug panel in the Symfony profiler.
14
 *
15
 * The collector is not designed for execution in a threaded application and does not support plugins that execute an
16
 * other request before the current one is sent by the client.
17
 *
18
 * @author Fabien Bourigault <[email protected]>
19
 *
20
 * @internal
21
 */
22
// Make this class non-abstract and move collect into it when we drop support for Symfony 4.
23
abstract class BaseCollector extends DataCollector
24
{
25
    /**
26
     * @var Stack|null
27
     */
28
    private $activeStack;
29
30 20
    public function __construct()
31
    {
32 20
        $this->reset();
33 20
    }
34
35
    /**
36
     * {@inheritdoc}
37
     */
38 19
    public function reset()
39
    {
40 19
        $this->data['stacks'] = [];
41 19
        $this->activeStack = null;
42 19
    }
43
44
    /**
45
     * {@inheritdoc}
46
     */
47 2
    public function getName()
48
    {
49 2
        return 'httplug';
50
    }
51
52
    /**
53
     * Mark the stack as active. If a stack was already active, use it as parent for our stack.
54
     *
55
     * @param Stack $stack
56
     */
57 8
    public function activateStack(Stack $stack)
58
    {
59 8
        if (null !== $this->activeStack) {
60 2
            $stack->setParent($this->activeStack);
0 ignored issues
show
Documentation introduced by
$this->activeStack is of type object<Http\HttplugBundle\Collector\Stack>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
61
        }
62
63 8
        $this->activeStack = $stack;
64 8
    }
65
66
    /**
67
     * Mark the stack as inactive.
68
     *
69
     * @param Stack $stack
70
     */
71 6
    public function deactivateStack(Stack $stack)
72
    {
73 6
        $this->activeStack = $stack->getParent();
74 6
    }
75
76
    /**
77
     * @return Stack|null
78
     */
79 8
    public function getActiveStack()
80
    {
81 8
        return $this->activeStack;
82
    }
83
84
    /**
85
     * @param Stack $stack
86
     */
87 7
    public function addStack(Stack $stack)
88
    {
89 7
        $this->data['stacks'][] = $stack;
90 7
    }
91
92
    /**
93
     * @param Stack $parent
94
     *
95
     * @return Stack[]
96
     */
97
    public function getChildrenStacks(Stack $parent)
98
    {
99
        return array_filter($this->data['stacks'], function (Stack $stack) use ($parent) {
100
            return $stack->getParent() === $parent;
101
        });
102
    }
103
104
    /**
105
     * @return Stack[]
106
     */
107 5
    public function getStacks()
108
    {
109 5
        return $this->data['stacks'];
110
    }
111
112
    /**
113
     * @return Stack[]
114
     */
115
    public function getSuccessfulStacks()
116
    {
117
        return array_filter($this->data['stacks'], function (Stack $stack) {
118
            return !$stack->isFailed();
119
        });
120
    }
121
122
    /**
123
     * @return Stack[]
124
     */
125 1
    public function getFailedStacks()
126
    {
127
        return array_filter($this->data['stacks'], function (Stack $stack) {
128
            return $stack->isFailed();
129 1
        });
130
    }
131
132
    /**
133
     * @return array
134
     */
135 3
    public function getClients()
136
    {
137
        $stacks = array_filter($this->data['stacks'], function (Stack $stack) {
138 2
            return null === $stack->getParent();
139 3
        });
140
141
        return array_unique(array_map(function (Stack $stack) {
142 2
            return $stack->getClient();
143 3
        }, $stacks));
144
    }
145
146
    /**
147
     * @param $client
148
     *
149
     * @return Stack[]
150
     */
151 1
    public function getClientRootStacks($client)
152
    {
153
        return array_filter($this->data['stacks'], function (Stack $stack) use ($client) {
154 1
            return $stack->getClient() == $client && null == $stack->getParent();
155 1
        });
156
    }
157
158
    /**
159
     * Count all messages for a client.
160
     *
161
     * @param $client
162
     *
163
     * @return int
164
     */
165
    public function countClientMessages($client)
166
    {
167
        return array_sum(array_map(function (Stack $stack) {
168
            return $this->countStackMessages($stack);
169
        }, $this->getClientRootStacks($client)));
170
    }
171
172
    /**
173
     * Recursively count message in stack.
174
     *
175
     * @param Stack $stack
176
     *
177
     * @return int
178
     */
179
    private function countStackMessages(Stack $stack)
180
    {
181
        return 1 + array_sum(array_map(function (Stack $child) {
182
            return $this->countStackMessages($child);
183
        }, $this->getChildrenStacks($stack)));
184
    }
185
186
    /**
187
     * @return int
188
     */
189
    public function getTotalDuration()
190
    {
191
        return array_reduce($this->data['stacks'], function ($carry, Stack $stack) {
192
            return $carry + $stack->getDuration();
193
        }, 0);
194
    }
195
}
196
197 1
if (Kernel::MAJOR_VERSION >= 5) {
198
    class Collector extends BaseCollector
199
    {
200
        /**
201
         * {@inheritdoc}
202
         */
203
        public function collect(Request $request, Response $response, Throwable $exception = null)
204
        {
205
            // We do not need to collect any data from the Symfony Request and Response
206 1
        }
207
    }
208
} else {
209
    class Collector extends BaseCollector
0 ignored issues
show
Comprehensibility Best Practice introduced by
The type Http\HttplugBundle\Collector\Collector has been defined more than once; this definition is ignored, only the first definition in this file (L198-207) is considered.

This check looks for classes that have been defined more than once in the same file.

If you can, we would recommend to use standard object-oriented programming techniques. For example, to avoid multiple types, it might make sense to create a common interface, and then multiple, different implementations for that interface.

This also has the side-effect of providing you with better IDE auto-completion, static analysis and also better OPCode caching from PHP.

Loading history...
210
    {
211
        /**
212
         * {@inheritdoc}
213
         */
214
        public function collect(Request $request, Response $response, \Exception $exception = null)
215
        {
216
            // We do not need to collect any data from the Symfony Request and Response
217
        }
218
    }
219
}
220