Completed
Push — master ( 5a065a...8bfcf4 )
by Tomasz
02:12
created

XmlFormat   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 85
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 1

Importance

Changes 4
Bugs 1 Features 1
Metric Value
wmc 19
c 4
b 1
f 1
lcom 0
cbo 1
dl 0
loc 85
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A serialize() 0 4 1
A doSerialize() 0 11 4
B serializeValue() 0 24 6
A unserialize() 0 9 1
C parse() 0 30 7
1
<?php
2
namespace Thunder\Serializard\Format;
3
4
use Thunder\Serializard\HandlerContainer\HandlerContainerInterface as Handlers;
5
6
/**
7
 * @author Tomasz Kowalczyk <[email protected]>
8
 */
9
final class XmlFormat implements FormatInterface
10
{
11
    public function serialize($var, Handlers $handlers)
12
    {
13
        return $this->doSerialize($var, $handlers);
14
    }
15
16
    private function doSerialize($var, Handlers $handlers, $doc = null, $parent = null, $key = null)
17
    {
18
        $isRoot = ($doc === null);
19
        $doc = $doc ?: new \DOMDocument('1.0', 'utf-8');
20
        $doc->formatOutput = true;
21
        $parent = $parent ?: $doc;
22
23
        $this->serializeValue($var, $handlers, $doc, $parent, $key);
24
25
        return $isRoot ? $doc->saveXML() : null;
26
    }
27
28
    private function serializeValue($var, Handlers $handlers, $doc, $parent, $key)
29
    {
30
        /** @var \DOMDocument|\DOMElement $doc */
31
        /** @var \DOMDocument|\DOMElement $parent */
32
        if(is_object($var)) {
33
            $handler = $handlers->getHandler(get_class($var));
34
            $arr = $handler($var);
35
            $this->doSerialize($arr, $handlers, $doc, $parent, $handlers->getRoot(get_class($var)));
36
37
            return;
38
        }
39
40
        if(is_array($var)) {
41
            $item = $key ? $doc->createElement($key) : $parent;
42
            foreach($var as $index => $value) {
43
                $this->doSerialize($value, $handlers, $doc, $item, $index);
44
            }
45
            !$key ?: $parent->appendChild($item);
46
47
            return;
48
        }
49
50
        $parent->appendChild($doc->createElement($key, $var));
51
    }
52
53
    public function unserialize($var, $class, Handlers $handlers)
54
    {
55
        $doc = new \DOMDocument();
56
        $doc->loadXML($var);
57
        $data = $this->parse($doc, $doc);
58
        $hydrator = $handlers->getHandler($class);
59
60
        return $hydrator($data[$handlers->getRoot($class)], $handlers);
61
    }
62
63
    private function parse(\DOMDocument $doc, $parent = null)
64
    {
65
        $ret = array();
66
        /** @var \DOMElement $parent */
67
        /** @var \DOMElement $node */
68
        $tags = array();
69
        foreach($parent->childNodes as $node) {
70
            if($node->nodeName === '#text') {
71
                continue;
72
            }
73
            if($node->childNodes->length === 1 && $node->childNodes->item(0) instanceof \DOMText) {
74
                $ret[$node->tagName] = $node->childNodes->item(0)->nodeValue;
75
                continue;
76
            }
77
            $result = $this->parse($doc, $node);
78
            if(array_key_exists($node->tagName, $ret)) {
79
                $tags[] = $node->tagName;
80
                $ret = array($ret[$node->tagName]);
81
                $ret[] = $result;
82
                continue;
83
            }
84
            if(in_array($node->tagName, $tags)) {
85
                $ret[] = $result;
86
                continue;
87
            }
88
            $ret[$node->tagName] = $result;
89
        }
90
91
        return $ret;
92
    }
93
}
94