Completed
Push — master ( 510a86...677c8f )
by Alexander
02:33
created

XmlDifferenceService::setSource()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 3
cts 3
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
crap 1
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: horat1us
5
 * Date: 5/11/17
6
 * Time: 6:41 PM
7
 */
8
9
namespace Horat1us\Services;
10
11
use Horat1us\Arrays\Collection;
12
use Horat1us\XmlConvertibleInterface;
13
use Horat1us\XmlConvertibleObject;
14
15
16
/**
17
 * Class XmlDifferenceService
18
 * @package Horat1us\Services
19
 */
20
class XmlDifferenceService
21
{
22
    /**
23
     * @var XmlConvertibleInterface
24
     */
25
    protected $source;
26
27
    /**
28
     * @var XmlConvertibleInterface
29
     */
30
    protected $target;
31
32
33
    /**
34
     * XmlDifferenceService constructor.
35
     * @param XmlConvertibleInterface $source
36
     * @param XmlConvertibleInterface $target
37
     */
38 4
    public function __construct(
39
        XmlConvertibleInterface $source,
40
        XmlConvertibleInterface $target
41
    )
42
    {
43
        $this
44 4
            ->setSource($source)
45 4
            ->setTarget($target);
46 4
    }
47
48
    /**
49
     * @return XmlConvertibleInterface|null
50
     */
51 4
    public function difference()
52
    {
53 4
        $current = $this->getSource();
54 4
        $compared = $this->getTarget();
55
56
        if (
57 4
            $current->getXmlElementName() !== $compared->getXmlElementName()
58 4
            || empty($current->getXmlChildren()) && !empty($compared->getXmlChildren())
59 3
            || array_reduce(
60 3
                $current->getXmlProperties(),
61
                function (bool $carry, string $property) use ($compared, $current) : bool {
62 3
                    return $carry
63 3
                        || (!property_exists($compared, $property))
64 3
                        || $current->{$property} !== $compared->{$property};
65 3
                },
66 4
                false
67
            )
68
        ) {
69 4
            return clone $current;
70
        }
71
72
73 2
        $newChildren = Collection::from($current->getXmlChildren() ?? [])
74
            ->map(function ($child) use ($compared) {
75 2
                return array_reduce(
76 2
                    $compared->getXmlChildren() ?? [],
77
                    function ($carry, $comparedChild) use ($child) {
78 2
                        if ($carry) {
79
                            return $carry;
80
                        }
81
82 2
                        $source = $child instanceof XmlConvertibleInterface
83 2
                            ? $child
84 2
                            : XmlConvertibleObject::fromXml($child);
85
86 2
                        $target = $comparedChild instanceof XmlConvertibleInterface
87 2
                            ? $comparedChild
88 2
                            : XmlConvertibleObject::fromXml($comparedChild);
89
90 2
                        return $source->xmlDiff($target);
91 2
                    });
92 2
            })
93 2
            ->filter(function ($child) {
94 2
                return $child !== null;
95 2
            })
96 2
            ->array;
97
98 2
        if (empty($newChildren)) {
99 2
            return null;
100
        }
101
102 2
        $target = clone $current;
103 2
        $target->setXmlChildren($newChildren);
104
105 2
        return clone $target;
106
    }
107
108
    /**
109
     * @return XmlConvertibleInterface
110
     */
111 4
    public function getSource(): XmlConvertibleInterface
112
    {
113 4
        return $this->source;
114
    }
115
116
    /**
117
     * @param XmlConvertibleInterface $source
118
     * @return $this
119
     */
120 4
    public function setSource(XmlConvertibleInterface $source)
121
    {
122 4
        $this->source = $source;
123
124 4
        return $this;
125
    }
126
127
    /**
128
     * @return XmlConvertibleInterface
129
     */
130 4
    public function getTarget(): XmlConvertibleInterface
131
    {
132 4
        return $this->target;
133
    }
134
135
    /**
136
     * @param XmlConvertibleInterface $target
137
     * @return $this
138
     */
139 4
    public function setTarget(XmlConvertibleInterface $target)
140
    {
141 4
        $this->target = $target;
142
143 4
        return $this;
144
    }
145
}