ArrayUtilsTrait::intersectKeyMultiple()   A
last analyzed

Complexity

Conditions 5
Paths 8

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 5

Importance

Changes 0
Metric Value
dl 0
loc 15
c 0
b 0
f 0
ccs 12
cts 12
cp 1
rs 9.4555
cc 5
nc 8
nop 1
crap 5
1
<?php
2
3
namespace Maketok\DataMigration;
4
5
use Maketok\DataMigration\Action\Exception\ConflictException;
6
use Maketok\DataMigration\Action\Exception\NormalizationException;
7
8
trait ArrayUtilsTrait
9
{
10
    /**
11
     * recursive array_filter
12
     * @param array $data
13
     * @return bool
14
     */
15 27
    public function isEmptyData(array $data)
16
    {
17
        $filteredData = array_filter($data, function ($var) {
18 26
            if (is_array($var)) {
19 18
                return !$this->isEmptyData($var);
20
            }
21 25
            return !empty($var);
22 27
        });
23 27
        return empty($filteredData);
24
    }
25
26
    /**
27
     * Accepts array of strings or arrays and tries to extract array of string[] from it
28
     * @param array $row
29
     * @return array
30
     * @throws NormalizationException
31
     */
32 8
    public function normalize(array $row)
33
    {
34
        $arrayRow = array_map(function ($var) {
35 7
            if (!is_array($var)) {
36 7
                return [$var];
37
            }
38 1
            return $var;
39 8
        }, $row);
40 8
        $count = 0;
41 8
        foreach ($arrayRow as $el) {
42 7
            $count = count($el);
43 7
            if (isset($oldCount) && $count != $oldCount) {
44
                throw new NormalizationException(
45
                    sprintf("Can not extract values: uneven data for row %s", json_encode($row))
46
                );
47
            }
48 7
            $oldCount = $count;
49 8
        }
50 8
        array_map('array_values', $arrayRow);
51 8
        $extracted = [];
52 8
        for ($i = 0; $i < $count; ++ $i) {
53
            $extracted[] = array_map(function ($var) use ($i) {
54 7
                return $var[$i];
55 7
            }, $arrayRow);
56 7
        }
57 8
        return $extracted;
58
    }
59
60
    /**
61
     * @param array $data
62
     * @param bool $force
63
     * @param bool $resolve
64
     * @return array
65
     * @throws ConflictException
66
     */
67 35
    public function assemble(array $data, $force = false, $resolve = false)
68
    {
69 35
        if (count($data) > 1) {
70 26
            $byKeys = $this->intersectKeyMultiple($data);
71 26
            $byKeysAndValues = $this->intersectAssocMultiple($data);
72 26
            if ($byKeys != $byKeysAndValues) {
73 22
                if ($resolve) {
74 15
                    $diff = array_diff($byKeys, $byKeysAndValues);
75
                    array_walk($data, function (&$unitData, $code) use ($diff) {
76 15
                        foreach ($unitData as $key => $val) {
77 15
                            if (isset($diff[$key])) {
78 14
                                unset($unitData[$key]);
79 14
                                $unitData[$code . '_' . $key] = $val;
80 14
                            }
81 15
                        }
82 15
                    });
83 22
                } elseif (!$force) {
84 17
                    throw new ConflictException(
85 17
                        sprintf("Conflict with data %s", json_encode($data))
86 17
                    );
87
                }
88 15
            }
89 19
        }
90 28
        return call_user_func_array('array_replace', $data);
91
    }
92
93
    /**
94
     * @param array $data
95
     * @return mixed
96
     */
97 26
    public function intersectKeyMultiple(array $data)
98
    {
99 26
        $res = [];
100 26
        foreach ($data as $outerArray) {
101 26
            foreach ($data as $innerArray) {
102 26
                if ($innerArray !== $outerArray) {
103 26
                    $res[] = array_intersect_key($outerArray, $innerArray);
104 26
                }
105 26
            }
106 26
        }
107 26
        if (!empty($res)) {
108 26
            return call_user_func_array('array_replace', $res);
109
        }
110 11
        return [];
111
    }
112
113
    /**
114
     * @param array $data
115
     * @return mixed
116
     */
117 26
    public function intersectAssocMultiple(array $data)
118
    {
119 26
        $res = [];
120 26
        foreach ($data as $outerArray) {
121 26
            foreach ($data as $innerArray) {
122 26
                if ($innerArray !== $outerArray) {
123 26
                    $res[] = array_intersect_assoc($outerArray, $innerArray);
124 26
                }
125 26
            }
126 26
        }
127 26
        if (!empty($res)) {
128 26
            return call_user_func_array('array_replace', $res);
129
        }
130 11
        return [];
131
    }
132
133
    /**
134
     * Same as assemble, but will not raise exception when values don't match
135
     * instead will adjust keys by pre-pending unit code
136
     * @param array $data
137
     * @return array
138
     */
139 19
    public function assembleResolve(array $data)
140
    {
141 19
        return $this->assemble($data, false, true);
142
    }
143
144
    /**
145
     * Convert all values to nulls persisting keys
146
     * @param array $data
147
     * @return array
148
     */
149
    public function getNullsData(array $data)
150
    {
151 5
        return array_map(function () {
152 5
            return null;
153 5
        }, $data);
154
    }
155
}
156