Passed
Push — master ( bbc3bd...e70b0b )
by Marwan
01:25
created

Misc::log()   B

Complexity

Conditions 11
Paths 113

Size

Total Lines 57
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 27
CRAP Score 11.727

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 11
eloc 32
c 1
b 0
f 0
nc 113
nop 4
dl 0
loc 57
ccs 27
cts 33
cp 0.8182
crap 11.727
rs 7.2083

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * @author Marwan Al-Soltany <[email protected]>
5
 * @copyright Marwan Al-Soltany 2021
6
 * For the full copyright and license information, please view
7
 * the LICENSE file that was distributed with this source code.
8
 */
9
10
declare(strict_types=1);
11
12
namespace MAKS\Velox\Helper;
13
14
use MAKS\Velox\Backend\Config;
15
16
/**
17
 * A class that serves as a holder for various miscellaneous utility function.
18
 */
19
final class Misc
20
{
21
    /**
22
     * Gets a value from an array via dot-notation.
23
     *
24
     * @param array &$array The array to get the value from.
25
     * @param string $key The dotted key representation.
26
     * @param mixed $default [optional] The default fallback value.
27
     *
28
     * @return mixed The requested value if found otherwise the default parameter.
29
     */
30 35
    public static function getArrayValueByKey(array &$array, string $key, $default = null)
31
    {
32 35
        if (!count($array)) {
33 3
            return $default;
34
        }
35
36 35
        $data = &$array;
37
38 35
        if (strpos($key, '.') !== false) {
39 21
            $parts = explode('.', $key);
40
41 21
            foreach ($parts as $part) {
42 21
                if (!array_key_exists($part, $data)) {
43 4
                    return $default;
44
                }
45
46 21
                $data = &$data[$part];
47
            }
48
49 21
            return $data;
50
        }
51
52 19
        return array_key_exists($key, $data) ? $data[$key] : $default;
53
    }
54
55
    /**
56
     * Sets a value of an array via dot-notation.
57
     *
58
     * @param array $array The array to set the value in.
59
     * @param string $key The string key representation.
60
     * @param mixed $value The value to set.
61
     *
62
     * @return bool True on success.
63
     */
64 31
    public static function setArrayValueByKey(array &$array, string $key, $value): bool
65
    {
66 31
        if (!strlen($key)) {
67 1
            return false;
68
        }
69
70 31
        $parts = explode('.', $key);
71 31
        $lastPart = array_pop($parts);
72
73 31
        $data = &$array;
74
75 31
        if (!empty($parts)) {
76 6
            foreach ($parts as $part) {
77 6
                if (!isset($data[$part])) {
78 4
                    $data[$part] = [];
79
                }
80
81 6
                $data = &$data[$part];
82
            }
83
        }
84
85 31
        $data[$lastPart] = $value;
86
87 31
        return true;
88
    }
89
90
91
    /**
92
     * Gets a private, protected, or public property (default, static, or constant) of an object.
93
     *
94
     * @param object $object Class instance.
95
     * @param string $property Property name.
96
     *
97
     * @return mixed The property value.
98
     *
99
     * @throws \Exception On failure.
100
     */
101 6
    public static function getObjectProperty($object, string $property)
102
    {
103 6
        return \Closure::bind(function ($object, $property) {
104 6
            $return = null;
105
106
            try {
107 6
                $class = get_class($object);
108 6
                if (defined($class . '::' . $property)) {
109 1
                    $return = constant($class . '::' . $property);
110 6
                } elseif (isset($object::$$property)) {
111 5
                    $return = $object::$$property;
112 3
                } elseif (isset($object->{$property})) {
113 3
                    $return = $object->{$property};
114
                } else {
115 6
                    throw new \Exception("No default, static, or constant property with the name '{$property}' exists!");
116
                }
117 1
            } catch (\Exception $error) {
118 1
                throw new \Exception(sprintf('%s() failed!', __METHOD__), $error->getCode(), $error);
119
            }
120
121 6
            return $return;
122 6
        }, null, $object)($object, $property);
123
    }
124
125
    /**
126
     * Sets a private, protected, or public property (default or static) of an object.
127
     *
128
     * @param object $object Class instance.
129
     * @param string $property Property name.
130
     * @param string $value Property value.
131
     *
132
     * @return mixed The new property value.
133
     *
134
     * @throws \Exception On failure.
135
     */
136 13
    public static function setObjectProperty($object, string $property, $value)
137
    {
138 13
        return \Closure::bind(function ($object, $property, $value) {
139 13
            $return = null;
140
141
            try {
142 13
                if (isset($object::$$property)) {
143 13
                    $return = $object::$$property = $value;
144 1
                } elseif (isset($object->{$property})) {
145 1
                    $return = $object->{$property} = $value;
146
                } else {
147 13
                    throw new \Exception("No default, static, or constant property with the name '{$property}' exists!");
148
                }
149 1
            } catch (\Exception $error) {
150 1
                throw new \Exception(sprintf('%s() failed!', __METHOD__), $error->getCode(), $error);
151
            }
152
153 13
            return $return;
154 13
        }, null, $object)($object, $property, $value);
155
    }
156
157
    /**
158
     * Calls a private, protected, or public method on an object.
159
     *
160
     * @param object $object Class instance.
161
     * @param string $method Method name.
162
     * @param mixed ...$arguments
163
     *
164
     * @return mixed The function result, or false on error.
165
     *
166
     * @throws \Exception On failure or if the called function threw an exception.
167
     */
168 1
    public static function callObjectMethod($object, string $method, ...$arguments)
169
    {
170 1
        return \Closure::bind(function ($object, $method, $arguments) {
171
            try {
172 1
                return call_user_func_array([$object, $method], $arguments);
173 1
            } catch (\Exception $error) {
174 1
                throw new \Exception(sprintf('%s() failed!', __METHOD__), $error->getCode(), $error);
175
            }
176 1
        }, null, $object)($object, $method, $arguments);
177
    }
178
179
    /**
180
     * Interpolates context values into text placeholders.
181
     *
182
     * @param string $text The text to interpolate.
183
     * @param array $context An associative array like `['varName' => 'varValue']`.
184
     * @param string $placeholderIndicator The wrapper that indicate a variable. Max 2 chars, anything else will be ignored and "{}" will be used instead.
185
     *
186
     * @return string The interpolated string.
187
     */
188 10
    public static function interpolate(string $text, array $context = [], string $placeholderIndicator = '{}'): string
189
    {
190 10
        if (strlen($placeholderIndicator) !== 2) {
191 1
            $placeholderIndicator = '{}';
192
        }
193
194 10
        $replacements = [];
195 10
        foreach ($context as $key => $value) {
196
            // check that the value can be cast to string
197 10
            if (!is_array($value) && (!is_object($value) || method_exists($value, '__toString'))) {
198 10
                $replacements[$placeholderIndicator[0] . $key . $placeholderIndicator[1]] = $value;
199
            }
200
        }
201
202 10
        return strtr($text, $replacements);
203
    }
204
205
    /**
206
     * Returns the passed key(s) from the backtrace.
207
     *
208
     * @param null|string|string[] $pluck [optional] $pluck The key to to get as a string or an array of strings (keys) from this list `[file, line, function, class, type, args]`, passing `null` will return the entire backtrace.
209
     * @param int $offset [optional] The offset of the backtrace, passing `-1` will reference the last item in the backtrace.
210
     *
211
     * @return string|int|array|null A string or int if a string is passed, an array if an array or null is passed, and null if no match was found.
212
     */
213 5
    public static function backtrace($pluck = null, ?int $offset = 0)
214
    {
215 5
        $backtrace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT);
216 5
        $plucked = null;
217
218 5
        if ($pluck === null) {
219 1
            return $backtrace;
220
        }
221
222 5
        if ($offset === -1) {
223 1
            $offset = 0;
224 1
            $backtrace = array_reverse($backtrace);
225
        }
226
227 5
        if (count($backtrace) < $offset + 1) {
228 1
            return null;
229 5
        } elseif (is_string($pluck)) {
230 3
            $plucked = isset($backtrace[$offset][$pluck]) ? $backtrace[$offset][$pluck] : null;
231 3
        } elseif (is_array($pluck)) {
0 ignored issues
show
introduced by
The condition is_array($pluck) is always true.
Loading history...
232 3
            $plucked = [];
233 3
            foreach ($pluck as $key) {
234 3
                !isset($backtrace[$offset][$key]) ?: $plucked[$key] = $backtrace[$offset][$key];
235
            }
236
        }
237
238 5
        return is_string($plucked) || is_array($plucked) && count($plucked, COUNT_RECURSIVE) ? $plucked : null;
239
    }
240
}
241