Helper   A
last analyzed

Complexity

Total Complexity 25

Size/Duplication

Total Lines 117
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 0

Test Coverage

Coverage 0%

Importance

Changes 1
Bugs 0 Features 1
Metric Value
wmc 25
c 1
b 0
f 1
lcom 0
cbo 0
dl 0
loc 117
ccs 0
cts 75
cp 0
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
C dumpClosure() 0 29 7
A exportVar() 0 14 3
B collectClosures() 0 18 6
D mergeConfig() 0 25 9
1
<?php
2
3
namespace hiqdev\composerextensionplugin;
4
5
use Closure;
6
use ReflectionFunction;
7
8
/**
9
 * Helper class.
10
 *
11
 * @author Andrii Vasyliev <[email protected]>
12
 */
13
class Helper
14
{
15
    /**
16
     * Merges two or more arrays into one recursively.
17
     * Based on Yii2 yii\helpers\BaseArrayHelper::merge.
18
     * @param array $a array to be merged to
19
     * @param array $b array to be merged from
20
     * @return array the merged array
21
     */
22
    public static function mergeConfig($a, $b)
0 ignored issues
show
Unused Code introduced by
The parameter $a is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $b is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
23
    {
24
        $args = func_get_args();
25
        $res = array_shift($args);
26
        foreach ($args as $items) {
27
            if (!is_array($items)) {
28
                continue;
29
            }
30
            foreach ($items as $k => $v) {
31
                if (is_int($k)) {
32
                    if (isset($res[$k])) {
33
                        $res[] = $v;
34
                    } else {
35
                        $res[$k] = $v;
36
                    }
37
                } elseif (is_array($v) && isset($res[$k]) && is_array($res[$k])) {
38
                    $res[$k] = self::mergeConfig($res[$k], $v);
39
                } else {
40
                    $res[$k] = $v;
41
                }
42
            }
43
        }
44
45
        return $res;
46
    }
47
48
    /**
49
     * Dumps closure object to string.
50
     * Based on http://www.metashock.de/2013/05/dump-source-code-of-closure-in-php/
51
     * @param Closure $c 
52
     * @return string
53
     */
54
    public static function dumpClosure(Closure $c) {
55
        $res = 'function (';
56
        $fun = new ReflectionFunction($c);
57
        $args = [];
58
        foreach($fun->getParameters() as $arg) {
59
            $str = '';
60
            if($arg->isArray()) {
61
                $str .= 'array ';
62
            } else if($arg->getClass()) {
63
                $str .= $arg->getClass()->name . ' ';
64
            }
65
            if($arg->isPassedByReference()){
66
                $str .= '&';
67
            }
68
            $str .= '$' . $arg->name;
69
            if ($arg->isOptional()) {
70
                $str .= ' = ' . var_export($arg->getDefaultValue(), true);
71
            }
72
            $args[] = $str;
73
        }
74
        $res .= implode(', ', $args);
75
        $res .= ') {' . PHP_EOL;
76
        $lines = file($fun->getFileName());
77
        for ($i = $fun->getStartLine(); $i < $fun->getEndLine(); $i++) {
78
            $res .= $lines[$i];
79
        }
80
81
        return rtrim($res, "\n ,");
82
    }
83
84
    /**
85
     * Returns a parsable string representation of given value.
86
     * In contrast to var_dump outputs Closures as PHP code.
87
     * @param mixed $value
88
     * @return string
89
     */
90
    public static function exportVar($value)
91
    {
92
        $closures = self::collectClosures($value);
93
        $res = var_export($value, true);
94
        if (!empty($closures)) {
95
            $subs = [];
96
            foreach ($closures as $key => $closure) {
97
                $subs["'" . $key . "'"] = self::dumpClosure($closure);
98
            }
99
            $res = strtr($res, $subs);
100
        }
101
102
        return $res;
103
    }
104
105
    /**
106
     * Collects closures from given input.
107
     * Substitutes closures with a tag.
108
     * @param mixed $input will be changed
109
     * @return array array of found closures
110
     */
111
    private static function collectClosures(&$input) {
112
        static $closureNo = 1;
113
        $closures = [];
114
        if (is_array($input)) {
115
            foreach ($input as &$value) {
116
                if (is_array($value) || $value instanceof Closure) {
117
                    $closures = array_merge($closures, self::collectClosures($value));
118
                }
119
            }
120
        } elseif ($input instanceof Closure) {
121
            $closureNo++;
122
            $key = "--==<<[[((Closure#$closureNo))]]>>==--";
123
            $closures[$key] = $input;
124
            $input = $key;
125
        }
126
127
        return $closures;
128
    }
129
}
130