Completed
Push — master ( 3c6d4a...e8d3de )
by Marwan
25s queued 11s
created

Utility::collapse()   B

Complexity

Conditions 8
Paths 8

Size

Total Lines 21
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 8

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 8
eloc 15
c 3
b 0
f 0
nc 8
nop 1
dl 0
loc 21
ccs 15
cts 15
cp 1
crap 8
rs 8.4444
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 DateTime;
12
use DateTimeZone;
13
14
/**
15
 * A class containing miscellaneous helper functions.
16
 * @since 1.2.0
17
 */
18
final class Utility
19
{
20
    /**
21
     * Returns a DateTime object with the right time zone.
22
     * @param string $time A valid php date/time string.
23
     * @param string $timezone A valid php timezone string.
24
     * @return DateTime
25
     */
26 4
    public static function time(string $time = 'now', ?string $timezone = null): DateTime
27
    {
28 4
        $timezone = $timezone
29 1
            ? $timezone
30 4
            : date_default_timezone_get();
31
32 4
        $timezoneObject = $timezone
33 4
            ? new DateTimeZone($timezone)
34 4
            : null;
35
36 4
        return new DateTime($time, $timezoneObject);
37
    }
38
39
    /**
40
     * Generates a user-level notice, warning, or an error with styling.
41
     * @param array|string|null [optional] $text 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).
42
     * @param string [optional] $color 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).
43
     * @param int [optional] $type Error type (E_USER family). 1024 E_USER_NOTICE, 512 E_USER_WARNING, 256 E_USER_ERROR, 16384 E_USER_DEPRECATED.
44
     * @return bool True if error type is accepted.
45
     * @codeCoverageIgnore
46
     */
47
    public static function emit($text = null, ?string $color = 'yellow', int $type = E_USER_NOTICE): bool
48
    {
49
        $colors = [
50
            'reset'   => 0,
51
            'black'   => 30,
52
            'red'     => 31,
53
            'green'   => 32,
54
            'yellow'  => 33,
55
            'blue'    => 34,
56
            'magenta' => 35,
57
            'cyan'    => 36,
58
            'white'   => 37,
59
            'default' => 39,
60
        ];
61
62
        $types = [
63
            E_USER_NOTICE     => E_USER_NOTICE,
64
            E_USER_WARNING    => E_USER_WARNING,
65
            E_USER_ERROR      => E_USER_ERROR,
66
            E_USER_DEPRECATED => E_USER_DEPRECATED,
67
        ];
68
69
        $cli = php_sapi_name() === 'cli' || php_sapi_name() === 'cli-server' || http_response_code() === false;
70
71
        $trim = ' \t\0\x0B';
72
        $backspace = chr(8);
73
        $wrapper = $cli ? "\033[%dm %s\033[0m" : "@COLOR[%d] %s";
74
        $color = $colors[$color] ?? 39;
75
        $type = $types[$type] ?? 1024;
76
        $message = '';
77
78
        if (is_array($text)) {
79
            foreach ($text as $segmentColor => $string) {
80
                $string = trim($string, $trim);
81
                if (is_string($segmentColor)) {
82
                    $segmentColor = $colors[$segmentColor] ?? $color;
83
                    $message .= !strlen($message)
84
                        ? sprintf($wrapper, $segmentColor, $backspace . $string)
85
                        : sprintf($wrapper, $segmentColor, $string);
86
                    continue;
87
                }
88
                $message = $message . $string;
89
            }
90
        } elseif (is_string($text)) {
91
            $string = $backspace . trim($text, $trim);
92
            $message = sprintf($wrapper, $color, $string);
93
        } else {
94
            $string = $backspace . 'From ' . __METHOD__ . ': No message was specified!';
95
            $message = sprintf($wrapper, $color, $string);
96
        }
97
98
        $message = $cli ? $message : preg_replace('/@COLOR\[\d+\]/', '', $message);
99
100
        return trigger_error($message, $type);
101
    }
102
103
    /**
104
     * Returns the passed key(s) from the backtrace. Note that the backtrace is reversed (last is first).
105
     * @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].
106
     * @param int [optional] $offset The offset of the backtrace (last executed is index at 0).
107
     * @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.
108
     */
109 8
    public static function backtrace($pluck, int $offset = 0)
110
    {
111 8
        $backtrace = array_reverse(debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT));
112 8
        $plucked = null;
113
114 8
        if (count($backtrace) < $offset + 1) {
115 1
            return null;
116 7
        } elseif (is_string($pluck)) {
117 1
            $plucked = isset($backtrace[$offset][$pluck]) ? $backtrace[$offset][$pluck] : null;
118 6
        } elseif (is_array($pluck)) {
0 ignored issues
show
introduced by
The condition is_array($pluck) is always true.
Loading history...
119 6
            $plucked = [];
120 6
            foreach ($pluck as $key) {
121 6
                !isset($backtrace[$offset][$key]) ?: $plucked[$key] = $backtrace[$offset][$key];
122
            }
123
        }
124
125 7
        return is_string($plucked) || is_array($plucked) && count($plucked, COUNT_RECURSIVE) ? $plucked : null;
126
    }
127
128
    /**
129
     * Returns a string representation of an array by imploding it recursively with common formatting of data-types.
130
     * @since 1.2.1
131
     * @param array $pieces The array to implode.
132
     * @return string
133
     */
134 4
    public static function collapse(array $pieces): string
135
    {
136 4
        $flat = [];
137
138 4
        foreach ($pieces as $piece) {
139 2
            if (is_array($piece)) {
140 1
                $flat[] = self::collapse($piece);
141 2
            } elseif (is_object($piece)) {
142 1
                $flat[] = get_class($piece) ?? 'object';
143 2
            } elseif (is_string($piece)) {
144 2
                $flat[] = "'{$piece}'";
145 1
            } elseif (is_bool($piece)) {
146 1
                $flat[] = $piece ? 'true' : 'false';
147 1
            } elseif (is_null($piece)) {
148 1
                $flat[] = 'null';
149
            } else {
150 1
                $flat[] = $piece;
151
            }
152
        }
153
154 4
        return '[' . implode(', ', $flat). ']';
155
    }
156
}
157