Exception::__construct()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 2
nc 2
nop 5
dl 0
loc 6
ccs 0
cts 0
cp 0
crap 6
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * General exception handler. Has support for throwing errors that
5
 * are specifically targeted at users, and even placing multiple messages
6
 * in one exception.
7
 *
8
 * @package   ElkArte Forum
9
 * @copyright ElkArte Forum contributors
10
 * @license   BSD http://opensource.org/licenses/BSD-3-Clause (see accompanying LICENSE.txt file)
11
 *
12
 * @version 2.0 dev
13
 *
14
 */
15
16
namespace ElkArte\Exceptions;
17
18
use ElkArte\Errors\Errors;
0 ignored issues
show
Bug introduced by
The type ElkArte\Errors\Errors was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
19
use ElkArte\Languages\Txt;
20
use ElkArte\User;
21
22
/**
23
 * Class ElkArte\Exception
24
 */
25
class Exception extends \Exception
26
{
27
	/**
28
	 * Values to use in vsprintf.
29
	 *
30
	 * @var string[]
31
	 */
32
	protected $sprintf = [];
33
34
	/**
35
	 * \ElkArte\Exceptions\Exception constructor.
36
	 * Extended exception rules because we need more stuff
37
	 *
38
	 * @param string|string[] $message index of $txt or message
39
	 *  - If an array is used, then it can specify a custom language template to load.
40
	 * @param bool|string $log type of error, defines under which "log" is it shown.
41
	 *  - If false is used, the error is not logged.
42
	 * @param string[] $sprintf optional array of values to use in vsprintf with the $txt
43
	 * @param int $code
44
	 * @param Exception|null $previous
45
	 */
46
	public function __construct($message, protected $log = false, $sprintf = [], $code = 0, Exception $previous = null)
47
	{
48
		$this->sprintf = is_array($sprintf) ? $sprintf : (array) $sprintf;
0 ignored issues
show
introduced by
The condition is_array($sprintf) is always true.
Loading history...
49
50
		// Make sure everything is assigned properly
51
		parent::__construct($this->loadMessage($message), $code, $previous);
52 34
	}
53
54 34
	/**
55 34
	 * Loads the language file specified in \ElkArte\Exceptions\Exception::parseMessage()
56
	 * and replaces the index received in the constructor.
57
	 *
58 34
	 * @param string|string[] $message
59 34
	 *
60
	 * @return string The index or the message.
61
	 */
62
	protected function loadMessage($message)
63
	{
64
		global $txt;
65
66
		$msg = '';
0 ignored issues
show
Unused Code introduced by
The assignment to $msg is dead and can be removed.
Loading history...
67
		$lang = false;
0 ignored issues
show
Unused Code introduced by
The assignment to $lang is dead and can be removed.
Loading history...
68
		try
69 34
		{
70
			[$msg, $lang] = $this->parseMessage($message);
71 34
			if ($lang !== false)
72
			{
73
				Txt::load($lang);
74
			}
75 34
		}
76 34
		catch (\Exception)
77
		{
78 34
			Errors::instance()->display_minimal_error($message);
79
		}
80
81
		$this->logMessage($message, $lang);
0 ignored issues
show
Bug introduced by
It seems like $message can also be of type string[]; however, parameter $msg of ElkArte\Exceptions\Exception::logMessage() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

81
		$this->logMessage(/** @scrutinizer ignore-type */ $message, $lang);
Loading history...
82
83
		return isset($txt[$msg]) ? (empty($this->sprintf) ? $txt[$msg] : vsprintf($txt[$msg], $this->sprintf)) : ($msg);
84
	}
85
86 34
	/**
87
	 * Cleans up the message param passed to the constructor.
88 34
	 *
89
	 * @param string|string[] $message Can be several different thing:
90
	 * - The index of $txt string
91
	 * - A plain text message
92
	 * - An array with the following structure:
93
	 *        array(
94
	 *            0 => language to load (use \ElkArte\Languages\Txt::load)
95
	 *            1 => index of $txt
96
	 *        )
97
	 * - A namespaced index in the form:
98
	 *     - language.index
99
	 *   - a "language" followed by a "dot" followed by the "index"
100
	 *   - "language" can be any character matched by \w
101
	 *   - "index" can be anything
102
	 * - "language" is loaded by \ElkArte\Languages\Txt::load.
103
	 *
104
	 * @return array
105
	 */
106
	protected function parseMessage($message)
107
	{
108
		// Load message with language support
109
		if (is_array($message))
110
		{
111 34
			return [$message[1], $message[0]];
112
		}
113
114 34
		if (preg_match('/^(\w+)\.(.+)$/', $message, $matches) !== 0)
115
		{
116
			// language.messageIndex
117
			return [$matches[2], $matches[1]];
118
		}
119 34
120
		// Simple Error message
121
		return [$message, 'Errors'];
122
	}
123
124
	/**
125
	 * Loads the language file specified in \ElkArte\Exceptions\Exception::parseMessage()
126
	 * and replaces the index received in the constructor.  Logs the message if needed.
127
	 *
128 34
	 * @param string $msg
129 34
	 * @param string $lang
130
	 */
131
	protected function logMessage($msg, $lang)
132 34
	{
133
		global $language, $txt;
134
135
		// Don't need to reload the language file if both the user and
136
		// the forum share the same language.
137
		if (!isset($language) || $language !== User::$info->language)
0 ignored issues
show
Bug Best Practice introduced by
The property language does not exist on ElkArte\Helper\ValuesContainer. Since you implemented __get, consider adding a @property annotation.
Loading history...
138
		{
139
			Txt::load($lang, $language);
140
		}
141
142
		if ($this->log !== false)
143 34
		{
144
			$msg = isset($txt[$msg]) ? (empty($this->sprintf) ? $txt[$msg] : vsprintf($txt[$msg], $this->sprintf)) : ($msg);
145 34
			Errors::instance()->log_error($msg, $this->log, $this->getFile(), $this->getLine());
146
		}
147
	}
148
149 34
	/**
150
	 * Calls fatal_lang_error and ends the execution of the script.
151 28
	 *
152
	 * @DEPRECATED
153
	 */
154 34
	public function fatalLangError()
155
	{
156
		Errors::instance()->fatal_lang_error($this->message, $this->log, $this->sprintf);
157
	}
158
}
159