HandlerAwareTrait::checkEntry()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 3
nc 3
nop 2
1
<?php
2
3
/**
4
 * Phoole (PHP7.2+)
5
 *
6
 * @category  Library
7
 * @package   Phoole\Logger
8
 * @copyright Copyright (c) 2019 Hong Zhang
9
 */
10
declare(strict_types=1);
11
12
namespace Phoole\Logger\Handler;
13
14
use Phoole\Logger\Entry\LogLevelTrait;
15
use Phoole\Base\Queue\UniquePriorityQueue;
16
use Phoole\Logger\Entry\LogEntryInterface;
17
use Phoole\Logger\Processor\VerifyCallableTrait;
18
19
/**
20
 * HandlerAwareTrait
21
 *
22
 * @package   Phoole\Logger
23
 * @interface HandlerAwareInterface
24
 */
25
trait HandlerAwareTrait
26
{
27
    use LogLevelTrait;
28
    use VerifyCallableTrait;
29
30
    /**
31
     * queue for the handlers
32
     *
33
     * @var  UniquePriorityQueue[][]
34
     */
35
    protected $handlers = [];
36
37
    /**
38
     * @var array
39
     */
40
    protected $handlerCache = [];
41
42
    /**
43
     * {@inheritDoc}
44
     */
45
    public function addHandler(
46
        string $level,
47
        callable $handler,
48
        $entryClass = LogEntryInterface::class,
49
        int $priority = 50
50
    ) {
51
        // verify parameters
52
        $requiredClass = self::verifyCallable($handler, LogEntryInterface::class);
53
        $entryClass = $this->checkEntry($entryClass, $requiredClass);
54
55
        // add handler
56
        $q = $this->handlers[$level][$entryClass] ?? new UniquePriorityQueue();
57
        $q->insert($handler, $priority);
58
        $this->handlers[$level][$entryClass] = $q;
59
60
        // clear cache
61
        $this->handlerCache = [];
62
63
        return $this;
64
    }
65
66
    /**
67
     * Get handlers handling $level and $entry type
68
     *
69
     * @param  LogEntryInterface $entry
70
     * @return \Traversable
71
     */
72
    protected function getHandlers(LogEntryInterface $entry): \Traversable
73
    {
74
        // check cache
75
        $level = $entry->getLevel();
76
        if (isset($this->handlerCache[$level][\get_class($entry)])) {
77
            return $this->handlerCache[$level][\get_class($entry)];
78
        }
79
80
        // find matching handlers
81
        $queue = $this->findHandlers($entry, $level);
82
83
        // update cache
84
        $this->handlerCache[$level][\get_class($entry)] = $queue;
85
86
        return $queue;
87
    }
88
89
    /**
90
     * @param  string|object $entryClass
91
     * @param  string        $requiredClass
92
     * @return string
93
     * @throws \InvalidArgumentException if not valid message entry
94
     */
95
    protected function checkEntry($entryClass, string $requiredClass): string
96
    {
97
        if (!\is_a($entryClass, $requiredClass, TRUE)) {
98
            throw new \InvalidArgumentException("not a valid entry " . $requiredClass);
99
        }
100
        return \is_string($entryClass) ? $entryClass : \get_class($entryClass);
101
    }
102
103
    /**
104
     * @param  LogEntryInterface $entry
105
     * @param  string            $level
106
     * @return UniquePriorityQueue
107
     */
108
    protected function findHandlers(LogEntryInterface $entry, string $level): UniquePriorityQueue
109
    {
110
        $queue = new UniquePriorityQueue();
111
        foreach ($this->handlers as $l => $qs) {
112
            if (!$this->matchLevel($level, $l)) {
113
                continue;
114
            }
115
116
            /** @var  UniquePriorityQueue $q */
117
            foreach ($qs as $class => $q) {
118
                if (is_a($entry, $class)) {
119
                    $queue = $queue->combine($q);
120
                }
121
            }
122
        }
123
        return $queue;
124
    }
125
126
    /**
127
     * return TRUE if can handle the entry level
128
     *
129
     * @param  string $entryLevel
130
     * @param  string $handlerLevel
131
     * @return bool
132
     */
133
    protected function matchLevel(string $entryLevel, string $handlerLevel): bool
134
    {
135
        if ($this->convert[$entryLevel] >= $this->convert[$handlerLevel]) {
136
            return TRUE;
137
        }
138
        return FALSE;
139
    }
140
}