Passed
Push — master ( f13f78...5c1b24 )
by Ismayil
04:22
created

engine/classes/Elgg/Logger.php (1 issue)

Check for loose comparison of boolean to boolean

Best Practice Coding Style Informational

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
namespace Elgg;
3
4
/**
5
 * WARNING: API IN FLUX. DO NOT USE DIRECTLY.
6
 *
7
 * Use the elgg_* versions instead.
8
 *
9
 * @access private
10
 *
11
 * @package    Elgg.Core
12
 * @subpackage Logging
13
 * @since      1.9.0
14
 */
15
class Logger {
16
17
	const OFF = 0;
18
	const ERROR = 400;
19
	const WARNING = 300;
20
	const NOTICE = 250;
21
	const INFO = 200;
22
23
	protected static $levels = [
24
		0 => 'OFF',
25
		200 => 'INFO',
26
		250 => 'NOTICE',
27
		300 => 'WARNING',
28
		400 => 'ERROR',
29
	];
30
31
	/**
32
	 * @var int The logging level
33
	 */
34
	protected $level = self::ERROR;
35
36
	/**
37
	 * @var bool Display to user?
38
	 */
39
	protected $display = false;
40
41
	/**
42
	 * @var PluginHooksService
43
	 */
44
	protected $hooks;
45
46
	/**
47
	 * @var Context
48
	 */
49
	private $context;
50
51
	/**
52
	 * @var array
53
	 */
54
	private $disabled_stack;
55
56
	/**
57
	 * @var callable
58
	 */
59
	private $printer;
60
61
	/**
62
	 * Constructor
63
	 *
64
	 * @param PluginHooksService $hooks   Hooks service
65
	 * @param Context            $context Context service
66
	 */
67 257
	public function __construct(PluginHooksService $hooks, Context $context) {
68 257
		$this->hooks = $hooks;
69 257
		$this->context = $context;
70 257
	}
71
72
	/**
73
	 * Set the logging level
74
	 *
75
	 * @param int $level The logging level
76
	 * @return void
77
	 */
78 200
	public function setLevel($level) {
79 200
		if (!$level) {
80
			// 0 or empty string
81 1
			$this->level = self::OFF;
82 1
			return;
83
		}
84
85
		// @todo Elgg has used string constants for logging levels
86 199
		if (is_string($level)) {
87 198
			$level = strtoupper($level);
88 198
			$level = array_search($level, self::$levels);
89
90 198
			if ($level !== false) {
91 198
				$this->level = $level;
92
			} else {
93
				$this->warn(__METHOD__ .": invalid level ignored.");
94
			}
95 198
			return;
96
		}
97
98 1
		if (isset(self::$levels[$level])) {
99 1
			$this->level = $level;
100
		} else {
101
			$this->warn(__METHOD__ .": invalid level ignored.");
102
		}
103 1
	}
104
105
	/**
106
	 * Get the current logging level
107
	 *
108
	 * @return int
109
	 */
110 36
	public function getLevel() {
111 36
		return $this->level;
112
	}
113
114
	/**
115
	 * Set whether the logging should be displayed to the user
116
	 *
117
	 * Whether data is actually displayed to the user depends on this setting
118
	 * and other factors such as whether we are generating a JavaScript or CSS
119
	 * file.
120
	 *
121
	 * @param bool $display Whether to display logging
122
	 * @return void
123
	 */
124
	public function setDisplay($display) {
125
		$this->display = $display;
126
	}
127
128
	/**
129
	 * Set custom printer
130
	 *
131
	 * @param callable $printer Printer
132
	 * @return void
133
	 */
134
	public function setPrinter(callable $printer) {
135
		if (is_callable($printer)) {
136
			$this->printer = $printer;
137
		}
138
	}
139
140
	/**
141
	 * Add a message to the log
142
	 *
143
	 * @param string $message The message to log
144
	 * @param int    $level   The logging level
145
	 * @return bool Whether the messages was logged
146
	 */
147 384
	public function log($message, $level = self::NOTICE) {
148 384
		if ($this->disabled_stack) {
149
			// capture to top of stack
150 224
			end($this->disabled_stack);
151 224
			$key = key($this->disabled_stack);
152 224
			$this->disabled_stack[$key][] = [
153 224
				'message' => $message,
154 224
				'level' => $level,
155
			];
156
		}
157
158 384
		if ($this->level == self::OFF || $level < $this->level) {
159 287
			return false;
160
		}
161
162 112
		if (!array_key_exists($level, self::$levels)) {
163
			return false;
164
		}
165
166
		// when capturing, still use consistent return value
167 112
		if ($this->disabled_stack) {
168 106
			return true;
169
		}
170
171 7
		$levelString = self::$levels[$level];
172
173
		// notices and below never displayed to user
174 7
		$display = $this->display && $level > self::NOTICE;
175
176 7
		$this->process("$levelString: $message", $display, $level);
177
178 7
		return true;
179
	}
180
181
	/**
182
	 * Log message at the ERROR level
183
	 *
184
	 * @param string $message The message to log
185
	 * @return bool
186
	 */
187 30
	public function error($message) {
188 30
		return $this->log($message, self::ERROR);
189
	}
190
191
	/**
192
	 * Log message at the WARNING level
193
	 *
194
	 * @param string $message The message to log
195
	 * @return bool
196
	 */
197 13
	public function warn($message) {
198 13
		return $this->log($message, self::WARNING);
199
	}
200
201
	/**
202
	 * Log message at the NOTICE level
203
	 *
204
	 * @param string $message The message to log
205
	 * @return bool
206
	 */
207 88
	public function notice($message) {
208 88
		return $this->log($message, self::NOTICE);
209
	}
210
211
	/**
212
	 * Log message at the INFO level
213
	 *
214
	 * @param string $message The message to log
215
	 * @return bool
216
	 */
217 284
	public function info($message) {
218 284
		return $this->log($message, self::INFO);
219
	}
220
221
	/**
222
	 * Dump data to log or screen
223
	 *
224
	 * @param mixed $data    The data to log
225
	 * @param bool  $display Whether to include this in the HTML page
226
	 * @return void
227
	 */
228
	public function dump($data, $display = true) {
229
		$this->process($data, $display, self::ERROR);
230
	}
231
232
	/**
233
	 * Process logging data
234
	 *
235
	 * @param mixed $data    The data to process
236
	 * @param bool  $display Whether to display the data to the user. Otherwise log it.
237
	 * @param int   $level   The logging level for this data
238
	 * @return void
239
	 */
240 7
	protected function process($data, $display, $level) {
241
		
242
		// plugin can return false to stop the default logging method
243
		$params = [
244 7
			'level' => $level,
245 7
			'msg' => $data,
246 7
			'display' => $display,
247 7
			'to_screen' => $display,
248
		];
249
250 7
		if (!$this->hooks->trigger('debug', 'log', $params, true)) {
251 1
			return;
252
		}
253
254
		// Do not want to write to JS or CSS pages
255 6
		if ($this->context->contains('js') || $this->context->contains('css')) {
256
			$display = false;
257
		}
258
259
		// don't display in simplecache requests
260 6
		$path = substr(current_page_url(), strlen(elgg_get_site_url()));
261 6
		if (preg_match('~^(cache|action|serve-file)/~', $path)) {
262
			$display = false;
263
		}
264
265 6
		if ($display == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
266
			if ($this->printer) {
267
				call_user_func($this->printer, $data, $level);
268
			} else {
269
				echo '<pre class="elgg-logger-data">';
270
				echo htmlspecialchars(print_r($data, true), ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
271
				echo '</pre>';
272
			}
273
		}
274
		
275 6
		error_log(print_r($data, true));
276 6
	}
277
278
	/**
279
	 * Temporarily disable logging and capture logs (before tests)
280
	 *
281
	 * Call disable() before your tests and enable() after. enable() will return a list of
282
	 * calls to log() (and helper methods) that were not acted upon.
283
	 *
284
	 * @note This behaves like a stack. You must call enable() for each disable() call.
285
	 *
286
	 * @return void
287
	 * @see enable
288
	 * @access private
289
	 * @internal
290
	 */
291 281
	public function disable() {
292 281
		$this->disabled_stack[] = [];
293 281
	}
294
295
	/**
296
	 * Restore logging and get record of log calls (after tests)
297
	 *
298
	 * @return array
299
	 * @see disable
300
	 * @access private
301
	 * @internal
302
	 */
303 262
	public function enable() {
304 262
		return array_pop($this->disabled_stack);
305
	}
306
307
	/**
308
	 * Reset the hooks service for this instance (testing)
309
	 *
310
	 * @return void
311
	 * @access private
312
	 * @internal
313
	 */
314 1
	public function setHooks(PluginHooksService $hooks) {
315 1
		$this->hooks = $hooks;
316 1
	}
317
}
318
319