elgg_http_url_is_identical()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 3
dl 0
loc 2
ccs 1
cts 1
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Bootstrapping and helper procedural code available for use in Elgg core and plugins.
4
 */
5
6
/**
7
 * Get a reference to the public service provider
8
 *
9
 * @return \Elgg\Di\PublicContainer
10
 * @since 2.0.0
11
 */
12
function elgg(): \Elgg\Di\PublicContainer {
13 8715
	return \Elgg\Application::$_instance->public_services;
14
}
15
16
/**
17
 * Set a response HTTP header
18
 *
19
 * @see header()
20
 *
21
 * @param string $header  Header
22
 * @param bool   $replace Replace existing header
23
 * @return void
24
 * @since 2.3
25
 */
26
function elgg_set_http_header(string $header, bool $replace = true): void {
27 91
	if (!preg_match('~^HTTP/\\d\\.\\d~', $header)) {
28 91
		list($name, $value) = explode(':', $header, 2);
29 91
		_elgg_services()->responseFactory->setHeader($name, trim($value), $replace);
30
	}
31
}
32
33
/**
34
 * Registers a success system message
35
 *
36
 * @param string|array $options a single string or an array of system message options
37
 *
38
 * @see \ElggSystemMessage::factory()
39
 *
40
 * @return void
41
 * @since 4.2
42
 */
43
function elgg_register_success_message(string|array $options): void {
44 78
	if (!is_array($options)) {
45 78
		$options = ['message' => $options];
46
	}
47
	
48 78
	$options['type'] = 'success';
49 78
	_elgg_services()->system_messages->addMessage($options);
50
}
51
52
/**
53
 * Registers a error system message
54
 *
55
 * @param string|array $options a single string or an array of system message options
56
 *
57
 * @see \ElggSystemMessage::factory()
58
 *
59
 * @return void
60
 * @since 4.2
61
 */
62
function elgg_register_error_message(string|array $options): void {
63 265
	if (!is_array($options)) {
64 265
		$options = ['message' => $options];
65
	}
66
	
67 265
	$options['type'] = 'error';
68 265
	_elgg_services()->system_messages->addMessage($options);
69
}
70
71
/**
72
 * Log a message.
73
 *
74
 * If $level is >= to the debug setting in {@link $CONFIG->debug}, the
75
 * message will be sent to {@link elgg_dump()}.  Messages with lower
76
 * priority than {@link $CONFIG->debug} are ignored.
77
 *
78
 * @note Use the developers plugin to display logs
79
 *
80
 * @param string $message User message
81
 * @param string $level   NOTICE | WARNING | ERROR
82
 *
83
 * @return void
84
 * @since 1.7.0
85
 */
86
function elgg_log($message, $level = \Psr\Log\LogLevel::NOTICE): void {
87 1585
	_elgg_services()->logger->log($level, $message);
88
}
89
90
/**
91
 * Logs $value to PHP's {@link error_log()}
92
 *
93
 * A 'debug', log' event is triggered. If a handler returns
94
 * false, it will stop the default logging method.
95
 *
96
 * @note Use the developers plugin to display logs
97
 *
98
 * @param mixed $value The value
99
 * @return void
100
 * @since 1.7.0
101
 */
102
function elgg_dump($value): void {
103
	_elgg_services()->logger->dump($value);
104
}
105
106
/**
107
 * Log a notice about deprecated use of a function, view, etc.
108
 *
109
 * @param string $msg         Message to log
110
 * @param string $dep_version Human-readable *release* version: 1.7, 1.8, ...
111
 *
112
 * @return void
113
 * @since 1.7.0
114
 */
115
function elgg_deprecated_notice(string $msg, string $dep_version): void {
116 2
	_elgg_services()->logger->warning("Deprecated in {$dep_version}: {$msg}");
117
}
118
119
/**
120
 * Builds a URL from the a parts array like one returned by {@link parse_url()}.
121
 *
122
 * @note If only partial information is passed, a partial URL will be returned.
123
 *
124
 * @param array $parts       Associative array of URL components like parse_url() returns
125
 *                           'user' and 'pass' parts are ignored because of security reasons
126
 * @param bool  $html_encode HTML Encode the url?
127
 *
128
 * @return string Full URL
129
 * @since 1.7.0
130
 */
131
function elgg_http_build_url(array $parts, bool $html_encode = true): string {
132 22
	return _elgg_services()->urls->buildUrl($parts, $html_encode);
133
}
134
135
/**
136
 * Adds action tokens to URL
137
 *
138
 * As of 1.7.0 action tokens are required on all actions.
139
 * Use this function to append action tokens to a URL's GET parameters.
140
 * This will preserve any existing GET parameters.
141
 *
142
 * @note If you are using {@elgg_view input/form} you don't need to
143
 * add tokens to the action.  The form view automatically handles
144
 * tokens.
145
 *
146
 * @param string $url         Full action URL
147
 * @param bool   $html_encode HTML encode the url? (default: false)
148
 *
149
 * @return string URL with action tokens
150
 * @since 1.7.0
151
 */
152
function elgg_add_action_tokens_to_url(string $url, bool $html_encode = false): string {
153 19
	return _elgg_services()->urls->addActionTokensToUrl($url, $html_encode);
154
}
155
156
/**
157
 * Removes an element from a URL's query string.
158
 *
159
 * @note You can send a partial URL string.
160
 *
161
 * @param string $url     Full URL
162
 * @param string $element The element to remove
163
 *
164
 * @return string The new URL with the query element removed.
165
 * @since 1.7.0
166
 */
167
function elgg_http_remove_url_query_element(string $url, string $element): string {
168 25
	return _elgg_services()->urls->addQueryElementsToUrl($url, [$element => null]);
169
}
170
171
/**
172
 * Sets elements in a URL's query string.
173
 *
174
 * @param string $url      The URL
175
 * @param array  $elements Key/value pairs to set in the URL. If the value is null, the
176
 *                         element is removed from the URL.
177
 *
178
 * @return string The new URL with the query strings added
179
 * @since 1.7.0
180
 */
181
function elgg_http_add_url_query_elements(string $url, array $elements): string {
182 185
	return _elgg_services()->urls->addQueryElementsToUrl($url, $elements);
183
}
184
185
/**
186
 * Test if two URLs are functionally identical.
187
 *
188
 * @tip If $ignore_params is used, neither the name nor its value will be considered when comparing.
189
 *
190
 * @tip The order of GET params doesn't matter.
191
 *
192
 * @param string $url1          First URL
193
 * @param string $url2          Second URL
194
 * @param array  $ignore_params GET params to ignore in the comparison
195
 *
196
 * @return bool
197
 * @since 1.8.0
198
 */
199
function elgg_http_url_is_identical(string $url1, string $url2, array $ignore_params = ['offset', 'limit']): bool {
200 138
	return _elgg_services()->urls->isUrlIdentical($url1, $url2, (array) $ignore_params);
201
}
202
203
/**
204
 * Signs provided URL with a SHA256 HMAC key
205
 *
206
 * @note Signed URLs do not offer CSRF protection and should not be used instead of action tokens.
207
 *
208
 * @param string $url     URL to sign
209
 * @param string $expires Expiration time
210
 *                        A string suitable for strtotime()
211
 *                        Null value indicate non-expiring URL
212
 * @return string
213
 */
214
function elgg_http_get_signed_url(string $url, string $expires = null): string {
215 3
	return _elgg_services()->urlSigner->sign($url, $expires);
216
}
217
218
/**
219
 * Validates if the HMAC signature of the URL is valid
220
 *
221
 * @param string $url URL to validate
222
 * @return bool
223
 */
224
function elgg_http_validate_signed_url(string $url): bool {
225
	return _elgg_services()->urlSigner->isValid($url);
226
}
227
228
/**
229
 * Returns a Guzzle HTTP client
230
 *
231
 * @param array $options Options for the client
232
 *
233
 * @return \Elgg\Http\Client
234
 */
235
function elgg_get_http_client(array $options = []): \Elgg\Http\Client {
236 712
	return new \Elgg\Http\Client($options);
237
}
238
239
/**
240
 * Checks for $array[$key] and returns its value if it exists, else
241
 * returns $default.
242
 *
243
 * Shorthand for $value = (isset($array['key'])) ? $array['key'] : 'default';
244
 *
245
 * @param string|int $key     Key to check in the source array
246
 * @param array      $array   Source array
247
 * @param mixed      $default Value to return if key is not found
248
 * @param bool       $strict  Return array key if it's set, even if empty. If false,
249
 *                            return $default if the array key is unset or empty.
250
 *
251
 * @return mixed
252
 * @since 1.8.0
253
 */
254
function elgg_extract($key, $array, $default = null, bool $strict = true) {
255 8988
	if (!is_array($array) && !$array instanceof ArrayAccess) {
256 4
		return $default;
257
	}
258
259 8988
	if ($strict) {
260 8988
		return $array[$key] ?? $default;
261
	}
262
	
263 310
	return (isset($array[$key]) && !empty($array[$key])) ? $array[$key] : $default;
264
}
265
266
/**
267
 * Extract class names from an array, optionally merging into a preexisting set.
268
 *
269
 * @param array           $array       Source array
270
 * @param string|string[] $existing    Existing name(s)
271
 * @param string          $extract_key Key to extract new classes from
272
 *
273
 * @return string[]
274
 *
275
 * @since 2.3.0
276
 */
277
function elgg_extract_class(array $array, array|string $existing = [], string $extract_key = 'class'): array {
278 205
	$existing = empty($existing) ? [] : (array) $existing;
279
280 205
	$merge = (array) elgg_extract($extract_key, $array, []);
281
282 205
	array_splice($existing, count($existing), 0, $merge);
283
284 205
	return array_values(array_filter(array_unique($existing)));
285
}
286
287
/**
288
 * Calls a callable autowiring the arguments using public DI services
289
 * and applying logic based on flags
290
 *
291
 * @param int     $flags   Bitwise flags
292
 *                         ELGG_IGNORE_ACCESS
293
 *                         ELGG_ENFORCE_ACCESS
294
 *                         ELGG_SHOW_DISABLED_ENTITIES
295
 *                         ELGG_HIDE_DISABLED_ENTITIES
296
 *                         ELGG_DISABLE_SYSTEM_LOG
297
 *                         ELGG_ENABLE_SYSTEM_LOG
298
 *                         ELGG_SHOW_DELETED_ENTITIES
299
 *                         ELGG_HIDE_DELETED_ENTITIES
300
 * @param Closure $closure Callable to call
301
 *
302
 * @return mixed
303
 */
304
function elgg_call(int $flags, Closure $closure) {
305 4713
	return _elgg_services()->invoker->call($flags, $closure);
306
}
307
308
/**
309
 * Returns a PHP INI setting in bytes.
310
 *
311
 * @tip Use this for arithmetic when determining if a file can be uploaded.
312
 *
313
 * @param string $setting The php.ini setting
314
 *
315
 * @return int
316
 * @since 1.7.0
317
 * @link http://www.php.net/manual/en/function.ini-get.php
318
 */
319
function elgg_get_ini_setting_in_bytes(string $setting): int {
320
	// retrieve INI setting
321 21
	$val = ini_get($setting);
322
323
	// convert INI setting when shorthand notation is used
324 21
	$last = strtolower($val[strlen($val) - 1]);
325 21
	if (in_array($last, ['g', 'm', 'k'])) {
326 7
		$val = substr($val, 0, -1);
327
	}
328
	
329 21
	$val = (int) $val;
330
	switch ($last) {
331 21
		case 'g':
332
			$val *= 1024;
333
			// fallthrough intentional
334 21
		case 'm':
335 7
			$val *= 1024;
336
			// fallthrough intentional
337 14
		case 'k':
338 7
			$val *= 1024;
339
	}
340
341
	// return byte value
342 21
	return $val;
343
}
344
345
/**
346
 * Get the global service provider
347
 *
348
 * @return \Elgg\Di\InternalContainer
349
 * @internal
350
 */
351
function _elgg_services(): \Elgg\Di\InternalContainer {
352
	// This yields a more shallow stack depth in recursive APIs like views. This aids in debugging and
353
	// reduces false positives in xdebug's infinite recursion protection.
354 8989
	return \Elgg\Application::$_instance->internal_services;
355
}
356