Completed
Push — master ( e8d3de...59dd4d )
by Marwan
12s queued 11s
created

Utility::objectToArray()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 9
c 1
b 0
f 0
nc 3
nop 2
dl 0
loc 16
ccs 10
cts 10
cp 1
crap 3
rs 9.9666
1
<?php
2
/**
3
 * @author Marwan Al-Soltany <[email protected]>
4
 * @copyright Marwan Al-Soltany 2020
5
 * For the full copyright and license information, please view
6
 * the LICENSE file that was distributed with this source code.
7
 */
8
9
namespace MAKS\AmqpAgent\Helper;
10
11
use stdClass;
12
use ReflectionObject;
13
use DateTime;
14
use DateTimeZone;
15
16
/**
17
 * A class containing miscellaneous helper functions.
18
 * @since 1.2.0
19
 */
20
final class Utility
21
{
22
    /**
23
     * Returns a DateTime object with the right time zone.
24
     * @param string $time A valid php date/time string.
25
     * @param string $timezone A valid php timezone string.
26
     * @return DateTime
27
     */
28 4
    public static function time(string $time = 'now', ?string $timezone = null): DateTime
29
    {
30 4
        $timezone = $timezone
31 1
            ? $timezone
32 4
            : date_default_timezone_get();
33
34 4
        $timezoneObject = $timezone
35 4
            ? new DateTimeZone($timezone)
36 4
            : null;
37
38 4
        return new DateTime($time, $timezoneObject);
39
    }
40
41
    /**
42
     * Generates a user-level notice, warning, or an error with styling.
43
     * @param array|string|null $text [optional] The text wished to be styled (when passing an array, if array key is a valid color it will style this array element value with its key).
44
     * @param string $color [optional] Case sensitive ANSI color name in this list [black, red, green, yellow, magenta, cyan, white, default] (when passing array, this parameter will be the fallback).
45
     * @param int $type [optional] Error type (E_USER family). 1024 E_USER_NOTICE, 512 E_USER_WARNING, 256 E_USER_ERROR, 16384 E_USER_DEPRECATED.
46
     * @return bool True if error type is accepted.
47
     */
48 4
    public static function emit($text = null, ?string $color = 'yellow', int $type = E_USER_NOTICE): bool
49
    {
50
        $colors = [
51 4
            'reset'   => 0,
52
            'black'   => 30,
53
            'red'     => 31,
54
            'green'   => 32,
55
            'yellow'  => 33,
56
            'blue'    => 34,
57
            'magenta' => 35,
58
            'cyan'    => 36,
59
            'white'   => 37,
60
            'default' => 39,
61
        ];
62
63
        $types = [
64 4
            E_USER_NOTICE     => E_USER_NOTICE,
65 4
            E_USER_WARNING    => E_USER_WARNING,
66 4
            E_USER_ERROR      => E_USER_ERROR,
67 4
            E_USER_DEPRECATED => E_USER_DEPRECATED,
68
        ];
69
70 4
        $cli = php_sapi_name() === 'cli' || php_sapi_name() === 'cli-server' || http_response_code() === false;
71
72 4
        $trim = ' \t\0\x0B';
73 4
        $backspace = chr(8);
74 4
        $wrapper = $cli ? "\033[%dm %s\033[0m" : "@COLOR[%d] %s";
75 4
        $color = $colors[$color] ?? 39;
76 4
        $type = $types[$type] ?? 1024;
77 4
        $message = '';
78
79 4
        if (is_array($text)) {
80 2
            foreach ($text as $segmentColor => $string) {
81 2
                $string = trim($string, $trim);
82 2
                if (is_string($segmentColor)) {
83 2
                    $segmentColor = $colors[$segmentColor] ?? $color;
84 2
                    $message .= !strlen($message)
85 2
                        ? sprintf($wrapper, $segmentColor, $backspace . $string)
86 2
                        : sprintf($wrapper, $segmentColor, $string);
87 2
                    continue;
88
                }
89 1
                $message = $message . $string;
90
            }
91 2
        } elseif (is_string($text)) {
92 1
            $string = $backspace . trim($text, $trim);
93 1
            $message = sprintf($wrapper, $color, $string);
94
        } else {
95 1
            $string = $backspace . 'From ' . __METHOD__ . ': No message was specified!';
96 1
            $message = sprintf($wrapper, $color, $string);
97
        }
98
99 4
        $message = $cli ? $message : preg_replace('/@COLOR\[\d+\]/', '', $message);
100
101 4
        return trigger_error($message, $type);
102
    }
103
104
    /**
105
     * Returns the passed key(s) from the backtrace. Note that the backtrace is reversed (last is first).
106
     * @param string|array $pluck The key to to get as a string or an array of strings (keys) from this list [file, line, function, class, type, args].
107
     * @param int $offset [optional] The offset of the backtrace (last executed is index at 0).
108
     * @return string|int|array|null A string or int if a string is passed, an array if an array is passed and null if no match was found.
109
     */
110 8
    public static function backtrace($pluck, int $offset = 0)
111
    {
112 8
        $backtrace = array_reverse(debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT));
113 8
        $plucked = null;
114
115 8
        if (count($backtrace) < $offset + 1) {
116 1
            return null;
117 7
        } elseif (is_string($pluck)) {
118 1
            $plucked = isset($backtrace[$offset][$pluck]) ? $backtrace[$offset][$pluck] : null;
119 6
        } elseif (is_array($pluck)) {
0 ignored issues
show
introduced by
The condition is_array($pluck) is always true.
Loading history...
120 6
            $plucked = [];
121 6
            foreach ($pluck as $key) {
122 6
                !isset($backtrace[$offset][$key]) ?: $plucked[$key] = $backtrace[$offset][$key];
123
            }
124
        }
125
126 7
        return is_string($plucked) || is_array($plucked) && count($plucked, COUNT_RECURSIVE) ? $plucked : null;
127
    }
128
129
    /**
130
     * Returns a string representation of an array by imploding it recursively with common formatting of data-types.
131
     * @since 1.2.1
132
     * @param array $pieces The array to implode.
133
     * @return string
134
     */
135 4
    public static function collapse(array $pieces): string
136
    {
137 4
        $flat = [];
138
139 4
        foreach ($pieces as $piece) {
140 2
            if (is_array($piece)) {
141 1
                $flat[] = self::collapse($piece);
142 2
            } elseif (is_object($piece)) {
143 1
                $flat[] = get_class($piece) ?? 'object';
144 2
            } elseif (is_string($piece)) {
145 2
                $flat[] = "'{$piece}'";
146 1
            } elseif (is_bool($piece)) {
147 1
                $flat[] = $piece ? 'true' : 'false';
148 1
            } elseif (is_null($piece)) {
149 1
                $flat[] = 'null';
150
            } else {
151 1
                $flat[] = $piece;
152
            }
153
        }
154
155 4
        return '[' . implode(', ', $flat). ']';
156
    }
157
158
    /**
159
     * Converts (casts) an object to an associative array.
160
     * @since 1.2.2
161
     * @param object $object The object to convert.
162
     * @param bool $useJson [optional] Wether to use json_decode/json_encode to cast the object, default is via reflection.
163
     * @return array The result array.
164
     */
165 2
    public static function objectToArray($object, bool $useJson = false): array
166
    {
167 2
        if ($useJson) {
168 1
            return json_decode(json_encode($object), true);
169
        }
170
171 1
        $array = [];
172
173 1
        $reflectionClass = new ReflectionObject($object);
174 1
        foreach ($reflectionClass->getProperties() as $property) {
175 1
            $property->setAccessible(true);
176 1
            $array[$property->getName()] = $property->getValue($object);
177 1
            $property->setAccessible(false);
178
        }
179
180 1
        return $array;
181
    }
182
183
    /**
184
     * Converts (casts) an array to an object (stdClass).
185
     * @since 1.2.2
186
     * @param object $object The array to convert.
187
     * @param bool $useJson [optional] Wether to use json_decode/json_encode to cast the array, default is via iteration.
188
     * @return stdClass The result object.
189
     */
190 2
    public static function arrayToObject(array $array, bool $useJson = false): stdClass
191
    {
192 2
        if ($useJson) {
193 1
            return json_decode(json_encode($array));
194
        }
195
196 1
        $stdClass = new stdClass();
197
198 1
        foreach ($array as $key => $value) {
199 1
            $stdClass->{$key} = is_array($value)
200 1
                ? self::arrayToObject($value, $useJson)
201 1
                : $value;
202
        }
203
204 1
        return $stdClass;
205
    }
206
207
    /**
208
     * Gets a value from an array via dot-notation representation.
209
     * @since 1.2.2
210
     * @param array $array The array to get the value from.
211
     * @param string $key The dotted key representation.
212
     * @param mixed $default [optional] The default fallback value.
213
     * @return mixed The requested value if found otherwise the default parameter.
214
     */
215 4
    public static function getArrayValueByKey(array &$array, string $key, $default = null)
216
    {
217 4
        if (!strlen($key) || !count($array)) {
218 1
            return $default;
219
        }
220
221 4
        $data = &$array;
222
223 4
        if (strpos($key, '.') !== false) {
224 4
            $parts = explode('.', $key);
225
226 4
            foreach ($parts as $part) {
227 4
                if (!array_key_exists($part, $data)) {
228 2
                    return $default;
229
                }
230
231 4
                $data = &$data[$part];
232
            }
233
234 4
            return $data;
235
        }
236
237 4
        return array_key_exists($key, $data) ? $data[$key] : $default;
238
    }
239
240
    /**
241
     * Sets a value of an array via dot-notation representation.
242
     * @since 1.2.2
243
     * @param array $array The array to set the value in.
244
     * @param string $key The string key representation.
245
     * @param mixed $value The value to set.
246
     * @return bool True on success.
247
     */
248 2
    public static function setArrayValueByKey(array &$array, string $key, $value): bool
249
    {
250 2
        if (!strlen($key)) {
251 1
            return false;
252
        }
253
254 2
        $parts = explode('.', $key);
255 2
        $lastPart = array_pop($parts);
256
257 2
        $data = &$array;
258
259 2
        if (!empty($parts)) {
260 2
            foreach ($parts as $part) {
261 2
                if (!isset($data[$part])) {
262 2
                    $data[$part] = [];
263
                }
264
265 2
                $data = &$data[$part];
266
            }
267
        }
268
269 2
        $data[$lastPart] = $value;
270
271 2
        return true;
272
    }
273
}
274