Passed
Push — master ( 1bc903...93f74b )
by Rustam
02:00
created

AbstractTarget::isCategoryMatched()   A

Complexity

Conditions 6
Paths 12

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 6

Importance

Changes 0
Metric Value
cc 6
eloc 11
nc 12
nop 1
dl 0
loc 20
ccs 12
cts 12
cp 1
crap 6
rs 9.2222
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Profiler\Target;
6
7
use Yiisoft\Profiler\Message;
8
use Yiisoft\Strings\WildcardPattern;
9
10
/**
11
 * Target is the base class for all profiling target classes.
12
 *
13
 * A profile target object will filter the messages stored by {@see Profiler} according
14
 * to its {@see AbstractTarget::include} and {@see AbstractTarget::exclude} properties.
15
 *
16
 * For more details and usage information on Target,
17
 * see the [guide article on profiling & targets](guide:runtime-profiling).
18
 */
19
abstract class AbstractTarget
20
{
21
    /**
22
     * @var array list of message categories that this target is interested in. Defaults to empty, meaning all
23
     * categories.
24
     *
25
     * You can use an asterisk at the end of a category so that the category may be used to
26
     * match those categories sharing the same common prefix. For example, 'Yiisoft\Db\*' will match
27
     * categories starting with 'Yiisoft\Db\', such as `Yiisoft\Db\Connection`.
28
     */
29
    private array $include = [];
30
31
    /**
32
     * @var array list of message categories that this target is NOT interested in. Defaults to empty, meaning no
33
     * uninteresting messages.
34
     *
35
     * If this property is not empty, then any category listed here will be excluded from {@see include}.
36
     * You can use an asterisk at the end of a category so that the category can be used to
37
     * match those categories sharing the same common prefix. For example, 'Yiisoft\Db\*' will match
38
     * categories starting with 'Yiisoft\Db\', such as `Yiisoft\Db\Connection`.
39
     *
40
     * {@see include}
41
     */
42
    private array $exclude = [];
43
44
    /**
45
     * @var bool whether to enable this log target. Defaults to true.
46
     */
47
    private bool $enabled = true;
48
49
    /**
50
     * Processes the given log messages.
51
     *
52
     * This method will filter the given messages with {@see include} and {@see exclude}.
53
     * And if requested, it will also export the filtering result to specific medium (e.g. email).
54
     *
55
     * @param array $messages profiling messages to be processed. See {@see Profiler::$messages} for the structure
56
     * of each message.
57
     */
58 5
    public function collect(array $messages): void
59
    {
60 5
        if (!$this->enabled) {
61 1
            return;
62
        }
63
64 4
        $messages = $this->filterMessages($messages);
65
66 4
        if (count($messages) > 0) {
67 3
            $this->export($messages);
68
        }
69 4
    }
70
71 5
    public function include(array $include): self
72
    {
73 5
        $this->include = $include;
74 5
        return $this;
75
    }
76
77 6
    public function exclude(array $exclude): self
78
    {
79 6
        $this->exclude = $exclude;
80 6
        return $this;
81
    }
82
83 1
    public function enable(): self
84
    {
85 1
        $this->enabled = true;
86 1
        return $this;
87
    }
88
89 1
    public function disable(): self
90
    {
91 1
        $this->enabled = false;
92 1
        return $this;
93
    }
94
95 2
    public function isEnabled(): bool
96
    {
97 2
        return $this->enabled;
98
    }
99
100
    /**
101
     * Exports profiling messages to a specific destination.
102
     *
103
     * Child classes must implement this method.
104
     *
105
     * @param Message[] $messages profiling messages to be exported.
106
     */
107
    abstract public function export(array $messages): void;
108
109
    /**
110
     * Filters the given messages according to their categories.
111
     *
112
     * @param Message[] $messages messages to be filtered.
113
     * The message structure follows that in {@see Profiler::$messages}.
114
     *
115
     * @return array the filtered messages.
116
     */
117 9
    protected function filterMessages(array $messages): array
118
    {
119 9
        foreach ($messages as $i => $message) {
120 9
            if (!$this->isCategoryMatched($message->level())) {
121 3
                unset($messages[$i]);
122
            }
123
        }
124 9
        return $messages;
125
    }
126
127 9
    private function isCategoryMatched(string $category): bool
128
    {
129 9
        $matched = empty($this->include);
130
131 9
        foreach ($this->include as $pattern) {
132 2
            if ((new WildcardPattern($pattern))->match($category)) {
133 1
                $matched = true;
134 1
                break;
135
            }
136
        }
137
138 9
        if ($matched) {
139 8
            foreach ($this->exclude as $pattern) {
140 3
                if ((new WildcardPattern($pattern))->match($category)) {
141 2
                    $matched = false;
142 2
                    break;
143
                }
144
            }
145
        }
146 9
        return $matched;
147
    }
148
}
149