Completed
Pull Request — master (#21)
by Greg
03:15
created

XmlSchema::addXmlData()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 10
rs 9.4285
cc 2
eloc 7
nc 2
nop 4
1
<?php
2
3
namespace Consolidation\OutputFormatters\StructuredData\Xml;
4
5
class XmlSchema implements XmlSchemaInterface
6
{
7
    protected $eleentList;
8
9
    public function __construct($elementList = [])
10
    {
11
        $defaultElementList =
12
        [
13
            '*' => ['description'],
14
        ];
15
        $this->elementList = array_merge_recursive($elementList, $defaultElementList);
0 ignored issues
show
Bug introduced by
The property elementList does not seem to exist. Did you mean eleentList?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
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_array($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 = is_numeric($key) ? $childElementName : $key;
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 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...
56
    {
57
        return 'document';
58
    }
59
60
    protected function getDefaultElementName($parentElementName)
61
    {
62
        $singularName = $this->singularForm($parentElementName);
63
        if ($singularName) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $singularName of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
64
            return $singularName;
65
        }
66
        return 'item';
67
    }
68
69
    protected function isAttribute($parentElementName, $elementName, $value)
70
    {
71
        if (!is_string($value)) {
72
            return false;
73
        }
74
        return !$this->inElementList($parentElementName, $elementName) && !$this->inElementList('*', $elementName);
75
    }
76
77
    protected function inElementList($parentElementName, $elementName)
78
    {
79
        if (!array_key_exists($parentElementName, $this->elementList)) {
0 ignored issues
show
Bug introduced by
The property elementList does not seem to exist. Did you mean eleentList?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
80
            return false;
81
        }
82
        return in_array($elementName, $this->elementList[$parentElementName]);
0 ignored issues
show
Bug introduced by
The property elementList does not seem to exist. Did you mean eleentList?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
83
    }
84
85
    protected function singularForm($name)
86
    {
87
        if (substr($name, strlen($name) - 1) == "s") {
88
            return substr($name, 0, strlen($name) - 1);
89
        }
90
    }
91
92
    protected function isAssoc($data)
93
    {
94
        return array_keys($data) == range(0, count($data));
95
    }
96
}
97