Debugger   A
last analyzed

Complexity

Total Complexity 28

Size/Duplication

Total Lines 127
Duplicated Lines 0 %

Test Coverage

Coverage 78.56%

Importance

Changes 9
Bugs 2 Features 0
Metric Value
eloc 52
c 9
b 2
f 0
dl 0
loc 127
rs 10
ccs 33
cts 42
cp 0.7856
wmc 28

9 Methods

Rating   Name   Duplication   Size   Complexity  
A getId() 0 3 1
A __construct() 0 11 1
A shutdown() 0 15 4
A startup() 0 19 6
A withIgnoredCommands() 0 5 1
A withIgnoredRequests() 0 5 1
A isCommandIgnored() 0 14 6
A stop() 0 10 3
A isRequestIgnored() 0 12 5
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\Debug;
6
7
use Psr\Http\Message\ServerRequestInterface;
8
use Yiisoft\Strings\WildcardPattern;
9
use Yiisoft\Yii\Console\Event\ApplicationStartup;
10
use Yiisoft\Yii\Debug\Collector\CollectorInterface;
11
use Yiisoft\Yii\Debug\Storage\StorageInterface;
12
use Yiisoft\Yii\Http\Event\BeforeRequest;
13
14
final class Debugger
15
{
16
    private bool $skipCollect = false;
17
    private bool $active = false;
18 7
19
    public function __construct(
20
        private readonly DebuggerIdGenerator $idGenerator,
21
        private readonly StorageInterface $target,
22
        /**
23
         * @var CollectorInterface[]
24
         */
25
        private readonly array $collectors,
26
        private array $ignoredRequests = [],
27
        private array $ignoredCommands = [],
28
    ) {
29
        register_shutdown_function([$this, 'shutdown']);
30 1
    }
31
32 1
    public function getId(): string
33
    {
34
        return $this->idGenerator->getId();
35 3
    }
36
37 3
    public function startup(object $event): void
38 1
    {
39 1
        $this->active = true;
40
        $this->skipCollect = false;
41
42 2
        if ($event instanceof BeforeRequest && $this->isRequestIgnored($event->getRequest())) {
43
            $this->skipCollect = true;
44
            return;
45
        }
46
47 2
        if ($event instanceof ApplicationStartup && $this->isCommandIgnored($event->commandName)) {
48 2
            $this->skipCollect = true;
49 2
            return;
50 2
        }
51
52
        $this->idGenerator->reset();
53
        foreach ($this->collectors as $collector) {
54 2
            $this->target->addCollector($collector);
55
            $collector->startup();
56 2
        }
57 2
    }
58 2
59 1
    public function shutdown(): void
60
    {
61
        if (!$this->active) {
62 1
            return;
63
        }
64
65
        try {
66
            if (!$this->skipCollect) {
67
                $this->target->flush();
68
            }
69
        } finally {
70
            foreach ($this->collectors as $collector) {
71
                $collector->shutdown();
72
            }
73
            $this->active = false;
74
        }
75
    }
76
77
    public function stop(): void
78 2
    {
79
        if (!$this->active) {
80
            return;
81 2
        }
82 1
83
        foreach ($this->collectors as $collector) {
84 2
            $collector->shutdown();
85 2
        }
86 2
        $this->active = false;
87
    }
88 2
89
    private function isRequestIgnored(ServerRequestInterface $request): bool
90
    {
91
        if ($request->hasHeader('X-Debug-Ignore') && $request->getHeaderLine('X-Debug-Ignore') === 'true') {
92
            return true;
93
        }
94
        $path = $request->getUri()->getPath();
95
        foreach ($this->ignoredRequests as $pattern) {
96
            if ((new WildcardPattern($pattern))->match($path)) {
97
                return true;
98
            }
99 1
        }
100
        return false;
101 1
    }
102 1
103 1
    private function isCommandIgnored(?string $command): bool
104
    {
105
        if ($command === null || $command === '') {
106
            return true;
107
        }
108
        if (getenv('YII_DEBUG_IGNORE') === 'true') {
109
            return true;
110
        }
111
        foreach ($this->ignoredCommands as $pattern) {
112
            if ((new WildcardPattern($pattern))->match($command)) {
113 1
                return true;
114
            }
115 1
        }
116 1
        return false;
117 1
    }
118
119
    /**
120
     * @param array $ignoredRequests Patterns for ignored request URLs.
121
     *
122
     * @see WildcardPattern
123
     */
124
    public function withIgnoredRequests(array $ignoredRequests): self
125
    {
126
        $new = clone $this;
127
        $new->ignoredRequests = $ignoredRequests;
128
        return $new;
129
    }
130
131
    /**
132
     * @param array $ignoredCommands Patterns for ignored commands names.
133
     *
134
     * @see WildcardPattern
135
     */
136
    public function withIgnoredCommands(array $ignoredCommands): self
137
    {
138
        $new = clone $this;
139
        $new->ignoredCommands = $ignoredCommands;
140
        return $new;
141
    }
142
}
143