Test Failed
Pull Request — master (#236)
by
unknown
04:56
created

FingersCrossedHandler::activate()   A

Complexity

Conditions 5
Paths 6

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 5
eloc 9
c 1
b 1
f 0
nc 6
nop 0
dl 0
loc 15
rs 9.6111
1
<?php
2
3
/*
4
 * This file is part of the Monolog package.
5
 *
6
 * (c) Jordi Boggiano <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Monolog\Handler;
13
14
use Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy;
15
use Monolog\Handler\FingersCrossed\ActivationStrategyInterface;
16
use Monolog\Logger;
17
18
/**
19
 * Buffers all records until a certain level is reached
20
 *
21
 * The advantage of this approach is that you don't get any clutter in your log files.
22
 * Only requests which actually trigger an error (or whatever your actionLevel is) will be
23
 * in the logs, but they will contain all records, not only those above the level threshold.
24
 *
25
 * You can find the various activation strategies in the
26
 * Monolog\Handler\FingersCrossed\ namespace.
27
 *
28
 * @author Jordi Boggiano <[email protected]>
29
 */
30
class FingersCrossedHandler extends AbstractHandler
31
{
32
    protected $handler;
33
    protected $activationStrategy;
34
    protected $buffering = true;
35
    protected $bufferSize;
36
    protected $buffer = array();
37
    protected $stopBuffering;
38
    protected $passthruLevel;
39
40
    /**
41
     * @param callable|HandlerInterface       $handler            Handler or factory callable($record, $fingersCrossedHandler).
42
     * @param int|ActivationStrategyInterface $activationStrategy Strategy which determines when this handler takes action
43
     * @param int                             $bufferSize         How many entries should be buffered at most, beyond that the oldest items are removed from the buffer.
44
     * @param Boolean                         $bubble             Whether the messages that are handled can bubble up the stack or not
45
     * @param Boolean                         $stopBuffering      Whether the handler should stop buffering after being triggered (default true)
46
     * @param int                             $passthruLevel      Minimum level to always flush to handler on close, even if strategy not triggered
47
     */
48
    public function __construct($handler, $activationStrategy = null, $bufferSize = 0, $bubble = true, $stopBuffering = true, $passthruLevel = null)
49
    {
50
        if (null === $activationStrategy) {
51
            $activationStrategy = new ErrorLevelActivationStrategy(Logger::WARNING);
52
        }
53
54
        // convert simple int activationStrategy to an object
55
        if (!$activationStrategy instanceof ActivationStrategyInterface) {
56
            $activationStrategy = new ErrorLevelActivationStrategy($activationStrategy);
57
        }
58
59
        $this->handler = $handler;
60
        $this->activationStrategy = $activationStrategy;
61
        $this->bufferSize = $bufferSize;
62
        $this->bubble = $bubble;
63
        $this->stopBuffering = $stopBuffering;
64
65
        if ($passthruLevel !== null) {
66
            $this->passthruLevel = Logger::toMonologLevel($passthruLevel);
67
        }
68
69
        if (!$this->handler instanceof HandlerInterface && !is_callable($this->handler)) {
70
            throw new \RuntimeException("The given handler (".json_encode($this->handler).") is not a callable nor a Monolog\Handler\HandlerInterface object");
71
        }
72
    }
73
74
    /**
75
     * {@inheritdoc}
76
     */
77
    public function isHandling(array $record)
78
    {
79
        return true;
80
    }
81
82
    /**
83
     * Manually activate this logger regardless of the activation strategy
84
     */
85
    public function activate()
86
    {
87
        if ($this->stopBuffering) {
88
            $this->buffering = false;
89
        }
90
        if (!$this->handler instanceof HandlerInterface) {
91
            $record = end($this->buffer) ?: null;
92
93
            $this->handler = call_user_func($this->handler, $record, $this);
94
            if (!$this->handler instanceof HandlerInterface) {
95
                throw new \RuntimeException("The factory callable should return a HandlerInterface");
96
            }
97
        }
98
        $this->handler->handleBatch($this->buffer);
99
        $this->buffer = array();
100
    }
101
102
    /**
103
     * {@inheritdoc}
104
     */
105
    public function handle(array $record)
106
    {
107
        if ($this->processors) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->processors of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
108
            foreach ($this->processors as $processor) {
109
                $record = call_user_func($processor, $record);
110
            }
111
        }
112
113
        if ($this->buffering) {
114
            $this->buffer[] = $record;
115
            if ($this->bufferSize > 0 && count($this->buffer) > $this->bufferSize) {
116
                array_shift($this->buffer);
117
            }
118
            if ($this->activationStrategy->isHandlerActivated($record)) {
0 ignored issues
show
Bug introduced by
The method isHandlerActivated() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

118
            if ($this->activationStrategy->/** @scrutinizer ignore-call */ isHandlerActivated($record)) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
119
                $this->activate();
120
            }
121
        } else {
122
            $this->handler->handle($record);
123
        }
124
125
        return false === $this->bubble;
126
    }
127
128
    /**
129
     * {@inheritdoc}
130
     */
131
    public function close()
132
    {
133
        if (null !== $this->passthruLevel) {
134
            $level = $this->passthruLevel;
135
            $this->buffer = array_filter($this->buffer, function ($record) use ($level) {
136
                return $record['level'] >= $level;
137
            });
138
            if (count($this->buffer) > 0) {
139
                $this->handler->handleBatch($this->buffer);
140
                $this->buffer = array();
141
            }
142
        }
143
    }
144
145
    /**
146
     * Resets the state of the handler. Stops forwarding records to the wrapped handler.
147
     */
148
    public function reset()
149
    {
150
        $this->buffering = true;
151
    }
152
153
    /**
154
     * Clears the buffer without flushing any messages down to the wrapped handler.
155
     *
156
     * It also resets the handler to its initial buffering state.
157
     */
158
    public function clear()
159
    {
160
        $this->buffer = array();
161
        $this->reset();
162
    }
163
}
164