Passed
Pull Request — master (#19)
by Rustam
02:41
created

Target::filterMessages()   B

Complexity

Conditions 8
Paths 25

Size

Total Lines 26
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 8

Importance

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