StaticLogger::checkContextException()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 10
c 0
b 0
f 0
ccs 6
cts 6
cp 1
rs 9.4285
cc 2
eloc 6
nc 2
nop 1
crap 2
1
<?php
2
namespace Subreality\Dilmun\Nabu;
3
4
use \Subreality\Dilmun\Nabu\LoggerHandler\HandlerInterface as handler;
5
6
/**
7
 * Static logger framework that follows the PHP-FIG PSR-3 standard for logging.
8
 *
9
 * @see http://www.php-fig.org/psr/psr-3/
10
 *
11
 * @author Derek DeHart
12
 */
13
class StaticLogger
14
{
15
    /**
16
     * Emergency: system is unusable
17
     */
18
    const EMERGENCY = 'emergency';
19
    /**
20
     * Alert: action must be taken immediately
21
     */
22
    const ALERT = 'alert';
23
    /**
24
     * Critical: critical conditions
25
     */
26
    const CRITICAL = 'critical';
27
    /**
28
     * Error: error conditions
29
     */
30
    const ERROR = 'error';
31
    /**
32
     * Warning: warning conditions
33
     */
34
    const WARNING = 'warning';
35
    /**
36
     * Notice: normal but significant condition
37
     */
38
    const NOTICE = 'notice';
39
    /**
40
     * Informational: informational messages
41
     */
42
    const INFO = 'info';
43
    /**
44
     * Debug: debug-level messages
45
     */
46
    const DEBUG = 'debug';
47
48
    /**
49
     * @var handler
50
     */
51
    private static $handler;
52
    private static $silence = false;
53
54
    private static $valid_levels = array(
55
        "EMERGENCY",
56
        "ALERT",
57
        "CRITICAL",
58
        "ERROR",
59
        "WARNING",
60
        "NOTICE",
61
        "INFO",
62
        "DEBUG"
63
    );
64
65
    /**
66
     * Sets the handler (e.g. a File) to be used to log messages.
67
     *
68
     * @param handler $handler  The handler to be used to write a log message.
69
     */
70 16
    public static function setHandler(handler $handler)
71
    {
72 16
        self::$handler = $handler;
73 16
    }
74
75
    /**
76
     * @param string $level     Must contain a valid log level:
77
     *                              "emergency"
78
     *                              "alert"
79
     *                              "critical"
80
     *                              "error"
81
     *                              "warning"
82
     *                              "notice"
83
     *                              "info"
84
     *                              "debug"
85
     * @param string $message   Message to be logged
86
     * @param array $context    PSR-3 context for log entry
87
     *
88
     * @return string           Returns the log entry string.
89
     */
90 31
    public static function log($level, $message, array $context = array())
91
    {
92 31
        self::validateLogLevel($level);
93
94 30
        $u_level = strtoupper($level);
95
96 30
        $log_trace = debug_backtrace();
97
98 30
        $trace_origin = end($log_trace);
99
100 30
        $trace_line = $trace_origin["line"];
101 30
        $trace_file = $trace_origin["file"];
102
103 30
        $processed_message = self::processContext($message, $context);
104
105 30
        $log_entry = "$u_level: $trace_file, $trace_line: $processed_message";
106
107 30
        if (!self::$silence) {
108 19
            self::$handler->write($log_entry);
109 19
        }
110
111 30
        return $log_entry;
112
    }
113
114
    /**
115
     * Generates a call to the log method given a supplied $level.
116
     *
117
     * @param string $level         Must contain a valid log level:
118
     *                                  "emergency"
119
     *                                  "alert"
120
     *                                  "critical"
121
     *                                  "error"
122
     *                                  "warning"
123
     *                                  "notice"
124
     *                                  "info"
125
     *                                  "debug"
126
     *                              Not specified inherently but rather derived from the overload.
127
     * @param array $log_arguments  The arguments passed to the log method by the __callStatic framework
128
     * @return string               The entry logged to the handler.
129
     *
130
     * @see StaticLogger::log
131
     * @see StaticLogger::validateLogLevel
132
     */
133 8
    public static function __callStatic($level, array $log_arguments)
134
    {
135 8
        self::validateLogLevel($level);
136
137
        //If there's only one argument passed to the logging function...
138 8
        if (count($log_arguments) == 1) {
139
            //Set the the second array element as an empty array.
140 8
            $log_arguments[1] = array();
141 8
        }
142
143 8
        $log_entry = self::log($level, $log_arguments[0], $log_arguments[1]);
144
145 8
        return $log_entry;
146
    }
147
148
    /**
149
     * Globally silences all logging.
150
     */
151 2
    public static function silenceLogging()
152
    {
153 2
        self::$silence = true;
154 2
    }
155
156
    /**
157
     * Globally unsliences all logging.
158
     */
159 19
    public static function unSilenceLogging()
160
    {
161 19
        self::$silence = false;
162 19
    }
163
164
    /**
165
     * Returns the current state of the StaticLogger's "silence" property
166
     *
167
     * @return bool The current state of silence
168
     */
169 3
    public static function getSilence()
170
    {
171 3
        return self::$silence;
172
    }
173
174
    /**
175
     * Validates that a given $level is a valid PSR-3 log level
176
     *
177
     * @param string $level                 The log level being validated
178
     * @throws \InvalidArgumentException    Generates an Invalid Argument Exception if the supplied level is invalid
179
     *
180
     * @see StaticLogger::valid_levels
181
     */
182 31
    private static function validateLogLevel($level)
183
    {
184 31
        $u_level = strtoupper($level);
185
186 31
        if (!in_array($u_level, self::$valid_levels)) {
187 1
            throw new \InvalidArgumentException("Unknown log level");
188
        }
189 30
    }
190
191
    /**
192
     * Processes context as supplied by the log method, replacing templated strings with data from the context array
193
     * or processing exception data via checkContextException.
194
     *
195
     * Context array elements with the "exception" key are processed by pulling Exception line, file, and message into
196
     * the log message provided appropriate templates within the message: {line}, {file}, and {message}, respectively.
197
     * Note that any line, file, or message templates provided outside of an exception will be overwritten by context
198
     * processing, and so the order in which the context array data are stacked is relevant.
199
     *
200
     *
201
     *
202
     * @param string $message   The original log message to be processed with context.
203
     * @param array $context    An array of key => value pairs with additional data to be inserted into the log
204
     *                          message provided {templated text} (i.e. surrounded by curly braces.
205
     *
206
     * @return string           The processed log message
207
     */
208 30
    private static function processContext($message, array $context = array())
209
    {
210 30
        $replace = array();
211
212 30
        foreach ($context as $key => $value) {
213 6
            $templated           = "{" . $key . "}";
214 6
            $replace[$templated] = $value;
215 30
        }
216
217 30
        if (self::checkContextException($context)) {
218
            /**
219
             * @var \Exception $exception
220
             */
221 1
            $exception = $context["exception"];
222
223 1
            $replace["{line}"]    = $exception->getLine();
224 1
            $replace["{file}"]    = $exception->getFile();
225 1
            $replace["{message}"] = $exception->getMessage();
226 1
        }
227
228 30
        return strtr($message, $replace);
229
    }
230
231
    /**
232
     * Determines whether a context array contains an Exception.
233
     *
234
     * @param array $context    PSR-3 context array.
235
     * @return bool             Returns true if the context array contains an element identified by an "exception" key
236
     *                          AND the value that corresponds with the "exception" key is an Exception.
237
     *                          Returns false otherwise.
238
     */
239 30
    private static function checkContextException(array $context = array())
240
    {
241 30
        if (isset($context["exception"])) {
242 1
            $includes_exception = $context["exception"] instanceof \Exception;
243 1
        } else {
244 29
            $includes_exception = false;
245
        }
246
247 30
        return $includes_exception;
248
    }
249
}
250