Passed
Pull Request — master (#2)
by Wilmer
02:40
created

Target::collect()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3

Importance

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