Completed
Push — master ( 16c231...cc821a )
by Greg
10s
created

XmlSchema::determineElementName()   B

Complexity

Conditions 8
Paths 9

Size

Total Lines 19
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 19
rs 7.7777
cc 8
eloc 12
nc 9
nop 3
1
<?php
2
3
namespace Consolidation\OutputFormatters\StructuredData\Xml;
4
5
class XmlSchema implements XmlSchemaInterface
6
{
7
    protected $elementList;
8
9
    public function __construct($elementList = [])
10
    {
11
        $defaultElementList =
12
        [
13
            '*' => ['description'],
14
        ];
15
        $this->elementList = array_merge_recursive($elementList, $defaultElementList);
16
    }
17
18
    public function arrayToXML($structuredData)
19
    {
20
        $dom = new \DOMDocument('1.0', 'UTF-8');
21
        $topLevelElement = $this->getTopLevelElementName($structuredData);
22
        $this->addXmlData($dom, $dom, $topLevelElement, $structuredData);
23
        return $dom;
24
    }
25
26
    protected function addXmlData(\DOMDocument $dom, $xmlParent, $elementName, $structuredData)
27
    {
28
        $element = $dom->createElement($elementName);
29
        $xmlParent->appendChild($element);
30
        if (is_string($structuredData)) {
31
            $element->appendChild($dom->createTextNode($structuredData));
32
            return;
33
        }
34
        $this->addXmlChildren($dom, $element, $elementName, $structuredData);
35
    }
36
37
    protected function addXmlChildren(\DOMDocument $dom, $xmlParent, $elementName, $structuredData)
38
    {
39
        foreach ($structuredData as $key => $value) {
40
            $this->addXmlDataOrAttribute($dom, $xmlParent, $elementName, $key, $value);
41
        }
42
    }
43
44
    protected function addXmlDataOrAttribute(\DOMDocument $dom, $xmlParent, $elementName, $key, $value)
45
    {
46
        $childElementName = $this->getDefaultElementName($elementName);
47
        $elementName = $this->determineElementName($key, $childElementName, $value);
48
        if (($elementName != $childElementName) && $this->isAttribute($elementName, $key, $value)) {
49
            $xmlParent->setAttribute($key, $value);
50
            return;
51
        }
52
        $this->addXmlData($dom, $xmlParent, $elementName, $value);
53
    }
54
55
    protected function determineElementName($key, $childElementName, $value)
56
    {
57
        if (is_numeric($key)) {
58
            return $childElementName;
59
        }
60
        if (is_object($value)) {
61
            $value = (array)$value;
62
        }
63
        if (!is_array($value)) {
64
            return $key;
65
        }
66
        if (array_key_exists('id', $value) && ($value['id'] == $key)) {
67
            return $childElementName;
68
        }
69
        if (array_key_exists('name', $value) && ($value['name'] == $key)) {
70
            return $childElementName;
71
        }
72
        return $key;
73
    }
74
75
    protected function getTopLevelElementName($structuredData)
0 ignored issues
show
Unused Code introduced by
The parameter $structuredData is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
76
    {
77
        return 'document';
78
    }
79
80
    protected function getDefaultElementName($parentElementName)
81
    {
82
        $singularName = $this->singularForm($parentElementName);
83
        if (isset($singularName)) {
84
            return $singularName;
85
        }
86
        return 'item';
87
    }
88
89
    protected function isAttribute($parentElementName, $elementName, $value)
90
    {
91
        if (!is_string($value)) {
92
            return false;
93
        }
94
        return !$this->inElementList($parentElementName, $elementName) && !$this->inElementList('*', $elementName);
95
    }
96
97
    protected function inElementList($parentElementName, $elementName)
98
    {
99
        if (!array_key_exists($parentElementName, $this->elementList)) {
100
            return false;
101
        }
102
        return in_array($elementName, $this->elementList[$parentElementName]);
103
    }
104
105
    protected function singularForm($name)
106
    {
107
        if (substr($name, strlen($name) - 1) == "s") {
108
            return substr($name, 0, strlen($name) - 1);
109
        }
110
    }
111
112
    protected function isAssoc($data)
113
    {
114
        return array_keys($data) == range(0, count($data));
115
    }
116
}
117