Test Failed
Push — master ( 811c27...aa94e6 )
by Alexander
06:04
created

XmlExportService::export()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 26
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 26
ccs 14
cts 14
cp 1
rs 8.8571
cc 1
eloc 17
nc 1
nop 0
crap 1
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: horat1us
5
 * Date: 5/11/17
6
 * Time: 6:23 PM
7
 */
8
9
namespace Horat1us\Services;
10
11
12
use Horat1us\Arrays\Collection;
13
use Horat1us\XmlConvertibleInterface;
14
15
/**
16
 * Class XmlExportService
17
 * @package Horat1us\Services
18
 */
19
class XmlExportService
20
{
21
    /**
22
     * @var XmlConvertibleInterface
23
     */
24
    public $object;
25
26
    /**
27
     * @var \DOMDocument
28
     */
29
    public $document;
30
31
    /**
32
     * XmlExportService constructor.
33
     * @param XmlConvertibleInterface $object
34
     * @param \DOMDocument|null $document
35
     */
36 14
    public function __construct(XmlConvertibleInterface $object, \DOMDocument $document = null)
37
    {
38 14
        $this->setDocument($document)
39 14
            ->setObject($object);
40 14
    }
41
42
    /**
43
     * Converting object to \DOMElement
44
     *
45
     * @return \DOMElement
46
     */
47 14
    public function export()
48
    {
49 14
        $xml = $this->createElement();
50
51 14
        Collection::from($this->getObject()->getXmlChildren() ?? [])
52 13
            ->map($this->mapChild())
53
            ->forEach(function (\DOMNode $child) use ($xml) {
54 6
                $xml->appendChild($child);
55 13
            });
56
57
        $reduce = function (Collection $properties, string $property) {
58 13
            $properties[$property] = $this->{$property};
59
            return $properties;
60 7
        };
61 7
62 13
        Collection::from($this->getObject()->getXmlProperties())
63 13
            ->reduce(function (Collection $collection, string $property) use ($reduce) {
64
                return $reduce->call($this->getObject(), $collection, $property);
65 6
            }, Collection::create())
66 13
            ->filter($this->getIsAttribute())
67
            ->forEach(function ($value, string $property) use ($xml) {
68 13
                $xml->setAttribute($property, $value);
69
            });
70
71
        return $xml;
72
    }
73
74
    /**
75
     * Creating new element to put object into
76 14
     *
77
     * @return \DOMElement
78 14
     */
79 14
    protected function createElement(): \DOMElement
80
    {
81
        return $this->getDocument()->createElement(
82
            $this->getObject()->getXmlElementName()
83
        );
84
    }
85
86
    /**
87
     * Preparing all children to export
88 13
     *
89
     * @return \Closure
90
     */
91 6
    protected function mapChild(): \Closure
92 5
    {
93 6
        return function ($child) {
94 13
            return $child instanceof XmlConvertibleInterface
95
                ? $child->toXml($this->document)
96
                : $child;
97
        };
98
    }
99
100
    /**
101
     * Can we put current attribute to XML
102
     *
103 13
     * @return \Closure
104 7
     */
105 13
    protected function getIsAttribute(): \Closure
106
    {
107
        return function ($value): bool {
108
            return !is_array($value) && !is_object($value) && !is_null($value);
109
        };
110
    }
111 14
112
    /**
113 14
     * @return XmlConvertibleInterface
114
     */
115
    public function getObject(): XmlConvertibleInterface
116
    {
117
        return $this->object;
118
    }
119
120 14
    /**
121
     * @param XmlConvertibleInterface $object
122 14
     * @return $this
123 14
     */
124
    public function setObject(XmlConvertibleInterface $object)
125
    {
126
        $this->object = $object;
127
        return $this;
128
    }
129 14
130
    /**
131 14
     * @return \DOMDocument
132
     */
133
    public function getDocument(): \DOMDocument
134
    {
135
        return $this->document;
136
    }
137
138 14
    /**
139
     * @param \DOMDocument $document
140 14
     * @return $this
141 14
     */
142
    public function setDocument(\DOMDocument $document = null)
143
    {
144
        $this->document = $document ?? new \DOMDocument();
145
        return $this;
146
    }
147
}