Completed
Push — master ( 7575c0...020310 )
by ARCANEDEV
04:08
created

Comparator::make()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 2
crap 1
1
<?php namespace Arcanesoft\Settings\Helpers;
2
3
use Arcanedev\Support\Collection;
4
5
/**
6
 * Class     Comparator
7
 *
8
 * @package  Arcanesoft\Settings\Helpers
9
 * @author   ARCANEDEV <[email protected]>
10
 */
11
class Comparator
12
{
13
    /* ------------------------------------------------------------------------------------------------
14
     |  Properties
15
     | ------------------------------------------------------------------------------------------------
16
     */
17
    /**
18
     * Unsaved data.
19
     *
20
     * @var \Arcanedev\Support\Collection
21
     */
22
    private $unsaved;
23
24
    /**
25
     * Saved data.
26
     *
27
     * @var \Arcanedev\Support\Collection
28
     */
29
    private $saved;
30
31
    /* ------------------------------------------------------------------------------------------------
32
     |  Constructor
33
     | ------------------------------------------------------------------------------------------------
34
     */
35
    /**
36
     * Comparator constructor.
37
     *
38
     * @param  array  $unsaved
39
     * @param  array  $saved
40
     */
41 28
    public function __construct(array $unsaved, array $saved)
42
    {
43 28
        $this->unsaved = Collection::make($unsaved);
44 28
        $this->saved   = Collection::make($saved);
45 28
    }
46
47
    /* ------------------------------------------------------------------------------------------------
48
     |  Main Functions
49
     | ------------------------------------------------------------------------------------------------
50
     */
51
    /**
52
     * Compare the changes.
53
     *
54
     * @param  array  $unsaved
55
     * @param  array  $saved
56
     *
57
     * @return array
58
     */
59 28
    public static function compare(array $unsaved, array $saved)
60
    {
61 28
        return (new self($unsaved, $saved))->compareChanges();
62
    }
63
64
    /**
65
     * Compare the changes.
66
     *
67
     * @return array
68
     */
69 28
    private function compareChanges()
70
    {
71 28
        $inserted = $updated = [];
72
73 28
        foreach ($this->unsaved as $domain => $values) {
74 24
            foreach ($values as $key => $value) {
75 24
                if ($this->isSaved($domain, $key)) {
76 8
                    if ($this->isUpdated($domain, $key, $value)) {
77 5
                        $updated[$domain][$key] = $value; // Updated
78 3
                    }
79 6
                }
80
                else {
81 24
                    $inserted[$domain][$key] = $value; // Inserted
82
                }
83 18
            }
84 21
        }
85
86 28
        $deleted = $this->getDeleted();
87
88 28
        return compact('inserted', 'updated', 'deleted');
89
    }
90
91
    /**
92
     * Compare the deleted entries.
93
     *
94
     * @return array
95
     */
96 28
    private function getDeleted()
97
    {
98 28
        if ($this->unsaved->isEmpty()) {
99
            // Delete all saved settings.
100 16
            return $this->saved->map(function (array $settings) {
101 12
                return array_keys($settings);
102 16
            })->toArray();
103
        }
104
105 24
        $deleted = [];
106
107 24
        foreach ($this->unsaved as $domain => $values) {
108 24
            $diff = array_diff(
109 24
                array_keys($this->saved->get($domain, [])),
110 18
                array_keys($values)
111 18
            );
112
113 24
            if ( ! empty($diff)) {
114 9
                $deleted[$domain] = $diff;
115 3
            }
116 18
        }
117
118 24
        return $deleted;
119
    }
120
121
    /**
122
     * Check if the entry is saved.
123
     *
124
     * @param  string  $domain
125
     * @param  string  $key
126
     *
127
     * @return bool
128
     */
129 24
    private function isSaved($domain, $key)
130
    {
131 24
        return Arr::has($this->saved->get($domain, []), $key);
132
    }
133
134
    /**
135
     * Check if the entry is updated.
136
     *
137
     * @param  string  $domain
138
     * @param  string  $key
139
     * @param  mixed   $value
140
     *
141
     * @return bool
142
     */
143 8
    private function isUpdated($domain, $key, $value)
144
    {
145 8
        return array_get($this->saved->get($domain, []), $key) !== $value;
146
    }
147
}
148