Completed
Push — master ( 132d64...2ffb4e )
by Alexander
02:37 queued 11s
created

XmlDifferenceService   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 157
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 21
lcom 1
cbo 3
dl 0
loc 157
ccs 53
cts 53
cp 1
rs 10
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 1
B difference() 0 23 6
A getDifferentChildren() 0 14 1
A getIsDifferentProperties() 0 13 4
A transform() 0 6 2
A findDifference() 0 14 3
A getSource() 0 4 1
A setSource() 0 6 1
A getTarget() 0 4 1
A setTarget() 0 6 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 4
            || $this->getIsDifferentProperties()
60
        ) {
61 4
            return clone $current;
62
        }
63
64 2
        $newChildren = $this->getDifferentChildren();
65 2
        if (empty($newChildren)) {
66 2
            return null;
67
        }
68
69 2
        $target = clone $current;
70 2
        $target->setXmlChildren($newChildren);
71
72 2
        return clone $target;
73
    }
74
75 2
    public function getDifferentChildren()
76
    {
77 2
        return Collection::from($this->getSource()->getXmlChildren() ?? [])
78
            ->map(function ($child) {
79 2
                return $this->transform($child);
80 2
            })
81
            ->map(function (XmlConvertibleInterface $child) {
82 2
                return $this->findDifference($child);
83 2
            })
84 2
            ->filter(function ($child) {
85 2
                return $child !== null;
86 2
            })
87 2
            ->array;
88
    }
89
90
    /**
91
     * Finding difference in properties
92
     *
93
     * @return bool
94
     */
95 3
    protected function getIsDifferentProperties()
96
    {
97 3
        foreach ($this->getSource()->getXmlProperties() as $property) {
98
            if (
99 3
                !property_exists($this->getTarget(), $property)
100 3
                || $this->getSource()->{$property} !== $this->getTarget()->{$property}
101
            ) {
102 3
                return true;
103
            }
104
        }
105
106 2
        return false;
107
    }
108
109
    /**
110
     * @param XmlConvertibleInterface|\DOMNode|\DOMDocument $object
111
     * @return XmlConvertibleInterface
112
     */
113 2
    protected function transform($object)
114
    {
115 2
        return $object instanceof XmlConvertibleInterface
116 2
            ? $object
117 2
            : XmlConvertibleObject::fromXml($object);
0 ignored issues
show
Documentation introduced by
$object is of type object<DOMNode>, but the function expects a object<DOMDocument>|object<DOMElement>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
118
    }
119
120
    /**
121
     * @param XmlConvertibleInterface $child
122
     * @return XmlConvertibleInterface|null
123
     */
124 2
    protected function findDifference(
125
        XmlConvertibleInterface $child
126
    )
127
    {
128 2
        foreach ($this->getTarget()->getXmlChildren() ?? [] as $comparedChild) {
129 2
            $target = $this->transform($comparedChild);
130
131 2
            if ($difference = $child->xmlDiff($target)) {
132 2
                return $difference;
133
            }
134
        }
135
136 2
        return null;
137
    }
138
139
    /**
140
     * @return XmlConvertibleInterface
141
     */
142 4
    public function getSource(): XmlConvertibleInterface
143
    {
144 4
        return $this->source;
145
    }
146
147
    /**
148
     * @param XmlConvertibleInterface $source
149
     * @return $this
150
     */
151 4
    public function setSource(XmlConvertibleInterface $source)
152
    {
153 4
        $this->source = $source;
154
155 4
        return $this;
156
    }
157
158
    /**
159
     * @return XmlConvertibleInterface
160
     */
161 4
    public function getTarget(): XmlConvertibleInterface
162
    {
163 4
        return $this->target;
164
    }
165
166
    /**
167
     * @param XmlConvertibleInterface $target
168
     * @return $this
169
     */
170 4
    public function setTarget(XmlConvertibleInterface $target)
171
    {
172 4
        $this->target = $target;
173
174 4
        return $this;
175
    }
176
}