Passed
Push — master ( 3a7ca9...c8f541 )
by Mihail
01:50
created

rmdir()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 6
nc 5
nop 1
dl 0
loc 11
ccs 6
cts 6
cp 1
crap 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of the Koded package.
5
 *
6
 * (c) Mihail Binev <[email protected]>
7
 *
8
 * Please view the LICENSE distributed with this source code
9
 * for the full copyright and license information.
10
*/
11
12
namespace Koded\Stdlib;
13
14
use DateTimeImmutable;
15
use Exception;
16
use FilesystemIterator;
17
use Koded\Stdlib\Serializer\{JsonSerializer, XmlSerializer};
18
use RecursiveDirectoryIterator;
19
use RecursiveIteratorIterator;
20
use function array_diff_assoc;
21
use function array_key_exists;
22
use function array_product;
23
use function array_values;
24
use function chr;
25
use function date_create_immutable;
26
use function getenv;
27
use function htmlentities;
28
use function join;
29
use function ord;
30
use function preg_replace;
31
use function preg_split;
32
use function putenv;
33
use function random_int;
34
use function sprintf;
35
use function str_replace;
36
use function strtolower;
37
use function timezone_open;
38
use function trim;
39
use function ucwords;
40
use function unlink;
41
use function var_export;
42
43
/**
44
 * Creates a new Arguments instance
45
 * with optional arbitrary number of arguments.
46
 *
47
 * @param array ...$values
48
 *
49
 * @return Argument
50
 */
51
function arguments(...$values): Argument
52
{
53 1
    return new Arguments(...$values);
0 ignored issues
show
Bug introduced by
$values is expanded, but the parameter $values of Koded\Stdlib\Arguments::__construct() does not expect variable arguments. ( Ignorable by Annotation )

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

53
    return new Arguments(/** @scrutinizer ignore-type */ ...$values);
Loading history...
54
}
55
56
/**
57
 * Transforms simple CamelCaseName into camel_case_name (lower case underscored).
58
 *
59
 * @param string $string CamelCase string to be underscored
60
 *
61
 * @return string Transformed string (for weird strings, you get what you deserve)
62
 */
63
function camel_to_snake_case(string $string): string
64
{
65 5
    $string = snake_to_camel_case($string);
66 5
    return strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', trim($string)));
67
}
68
69
/**
70
 * Send a formatted error message to PHP's system logger.
71
 *
72
 * @param string $func The function name where error occurred
73
 * @param string $message The error message
74
 * @param mixed $data Original data passed into function
75
 */
76
function error_log(string $func, string $message, mixed $data): void
77
{
78 3
    \error_log(sprintf("(%s) %s:\n%s", $func, $message, var_export($data, true)));
79 3
}
80
81
/**
82
 * Gets or sets environment variables.
83
 *
84
 * @param string|null $name
85
 * @param string [optional] $name The name of the env variable
86
 * @param array|null $initialState
87
 * @return mixed The value for the env variable,
88
 *               or all variables if $name is not provided
89
 */
90
function env(
91
    string $name = null,
92
    mixed  $default = null,
93
    array  $initialState = null): mixed
94
{
95 4
    static $state = [];
96 4
    if (null !== $initialState) {
97 4
        foreach ($initialState as $k => $v) {
98 3
            null === $v || putenv($k . '=' . $v);
99
        }
100 4
        return $state = $initialState;
101
    }
102 3
    if (null === $name) {
103 3
        return $state;
104
    }
105 1
    return array_key_exists($name, $state)
106 1
        ? $state[$name]
107 1
        : (getenv($name) ?: $default);
108
}
109
110
/**
111
 * HTML encodes a string.
112
 * Useful for escaping the input values in HTML templates.
113
 *
114
 * @param string $input The input string
115
 * @param string $encoding The encoding
116
 *
117
 * @return string
118
 */
119
function htmlencode(string $input, string $encoding = 'UTF-8'): string
120
{
121 1
    return htmlentities($input, ENT_QUOTES | ENT_HTML5, $encoding);
122
}
123
124
/**
125
 * Checks if the array is an associative array.
126
 *
127
 * Simple rules:
128
 *
129
 * - If all keys are sequential starting from 0..n, it is not an associative array
130
 * - empty array is not associative
131
 *
132
 * Unfortunately, the internal typecast to integer on the keys makes
133
 * the sane programming an ugly Array Oriented Programming hackery.
134
 *
135
 * @param array $array
136
 *
137
 * @return bool
138
 */
139
function is_associative(array $array): bool
140
{
141 25
    return (bool)array_diff_assoc($array, array_values($array));
142
}
143
144
/**
145
 * Returns the JSON representation of a value.
146
 *
147
 * @param mixed $value The data to be serialized
148
 * @param int $options [optional] JSON bitmask options for JSON encoding.
149
 *                       [WARNING]: uses {@JsonSerializer::OPTIONS} as defaults;
150
 *                       instead of adding, it may remove the option (if set in OPTIONS)
151
 *
152
 * @return string JSON encoded string, or EMPTY STRING if encoding failed
153
 * @see http://php.net/manual/en/function.json-encode.php
154
 */
155
function json_serialize(mixed $value, int $options = 0): string
156
{
157 11
    return (new JsonSerializer($options))->serialize($value);
158
}
159
160
/**
161
 * Decodes a JSON string into appropriate PHP type.
162
 *
163
 * @param string $json A JSON string
164
 * @param bool $associative When TRUE, returned objects will be
165
 *                            converted into associative arrays
166
 *
167
 * @return mixed The decoded value, or EMPTY STRING on error
168
 */
169
function json_unserialize(string $json, bool $associative = false): mixed
170
{
171 7
    return (new JsonSerializer(0, $associative))->unserialize($json);
172
}
173
174
/**
175
 * Gets an instance of DateTimeImmutable in UTC.
176
 *
177
 * @return DateTimeImmutable
178
 */
179
function now(): DateTimeImmutable
180
{
181 1
    return date_create_immutable('now', timezone_open('UTC'));
182
}
183
184
/**
185
 * Creates a random generated string with optional prefix and/or suffix.
186
 *
187
 * NOTE: DO NOT use it for passwords or any data that requires cryptographic secureness!
188
 *
189
 * @param int $length [optional]
190
 * @param string $prefix [optional]
191
 * @param string $suffix [optional]
192
 *
193
 * @return string
194
 * @throws Exception if it was not possible to gather sufficient entropy
195
 * @since 1.10.0
196
 */
197
function randomstring(
198
    int    $length = 16,
199
    string $prefix = '',
200
    string $suffix = ''): string
201
{
202 5
    $buffer = '';
203 5
    for ($x = 0; $x < $length; ++$x) {
204 5
        $buffer .= '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'[random_int(0, 61)];
205
    }
206 5
    return $prefix . $buffer . $suffix;
207
}
208
209
/**
210
 * Removes a directory.
211
 *
212
 * @param string $dirname The folder name
213
 *
214
 * @return bool TRUE on success, FALSE otherwise
215
 */
216
function rmdir(string $dirname): bool
217
{
218 1
    $deleted = [];
219
220
    /** @var \SplFileInfo $path */
221 1
    foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dirname, FilesystemIterator::SKIP_DOTS),
222 1
        RecursiveIteratorIterator::CHILD_FIRST) as $path) {
223 1
        $deleted[] = ($path->isDir() && false === $path->isLink())
224 1
            ? \rmdir($path->getPathname()) : unlink($path->getPathname());
225
    }
226 1
    return (bool)array_product($deleted);
227
}
228
229
/**
230
 * Transforms the simple snake_case string into CamelCaseName.
231
 *
232
 * @param string $string
233
 *
234
 * @return string Camel-cased string
235
 */
236
function snake_to_camel_case(string $string): string
237
{
238 10
    $string = preg_replace('/[\W_]++/', ' ', $string);
239 10
    return str_replace(' ', '', ucwords($string));
240
}
241
242
/**
243
 * Converts the string with desired delimiter character.
244
 *
245
 * @param string $string
246
 * @param int $delimiter chr() of the delimiter character
247
 *
248
 * @return string The converted string with the provided delimiter
249
 */
250
function to_delimited_string(string $string, int $delimiter): string
251
{
252 3
    $str = preg_split('~[^\p{L}\p{N}\']+~u', trim($string));
253 3
    return join(chr($delimiter), $str);
254
}
255
256
/**
257
 * Converts the string to-kebab-case
258
 *
259
 * @param string $string
260
 *
261
 * @return string
262
 */
263
function to_kebab_string(string $string): string
264
{
265 1
    return strtolower(to_delimited_string($string, ord('-')));
266
}
267
268
/**
269
 * Creates a new Data instance (Immutable)
270
 * with optional arbitrary number of arguments.
271
 *
272
 * @param array ...$values
273
 *
274
 * @return Data
275
 */
276
function value(...$values): Data
277
{
278 1
    return new Immutable(...$values);
0 ignored issues
show
Bug introduced by
$values is expanded, but the parameter $values of Koded\Stdlib\Immutable::__construct() does not expect variable arguments. ( Ignorable by Annotation )

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

278
    return new Immutable(/** @scrutinizer ignore-type */ ...$values);
Loading history...
279
}
280
281
/**
282
 * Serializes the data into XML document.
283
 *
284
 * @param string $root The XML document root name
285
 * @param iterable $data The data to be encoded
286
 *
287
 * @return string XML document
288
 */
289
function xml_serialize(string $root, iterable $data): string
290
{
291 2
    return (new XmlSerializer($root))->serialize($data);
292
}
293
294
/**
295
 * Unserialize an XML document into PHP array.
296
 * This function does not deal with magical conversions
297
 * of complicated XML structures.
298
 *
299
 * @param string $xml The XML document to be decoded into array
300
 *
301
 * @return array Decoded version of the XML string,
302
 *               or empty array on malformed XML
303
 */
304
function xml_unserialize(string $xml): array
305
{
306 2
    return (new XmlSerializer(null))->unserialize($xml) ?: [];
307
}
308