Passed
Push — master ( 622e79...efafc0 )
by Andreas
03:31
created

xmlreader::add_property()   B

Complexity

Conditions 9
Paths 28

Size

Total Lines 40
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 31
CRAP Score 9

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 9
eloc 31
c 2
b 0
f 0
nc 28
nop 3
dl 0
loc 40
ccs 31
cts 31
cp 1
crap 9
rs 8.0555
1
<?php
2
/**
3
 * @author CONTENT CONTROL http://www.contentcontrol-berlin.de/
4
 * @copyright CONTENT CONTROL http://www.contentcontrol-berlin.de/
5
 * @license http://www.gnu.org/licenses/gpl.html GNU General Public License
6
 */
7
8
namespace midgard\portable;
9
10
use midgard\portable\mgdschema\property;
11
use midgard\portable\mgdschema\type;
12
use midgard\portable\mgdschema\mixin;
13
use SimpleXMLElement;
14
15
class xmlreader
16
{
17
    /**
18
     *
19
     * @var array
20
     */
21
    private $mixins = [];
22
23 15
    public function parse(string $filename) : array
24
    {
25 15
        $types = [];
26 15
        $parser = simplexml_load_file($filename);
27 15
        $parser->registerXPathNamespace('r', "http://www.midgard-project.org/repligard/1.4");
28 15
        $nodes = $parser->xpath('/r:Schema/r:type');
29 15
        foreach ($nodes as $node) {
30 15
            $type = $this->parse_type($node);
31 15
            if (empty($type->table)) {
32
                throw new \LogicException('"table" attribute is missing in ' . $type->name . ' (' . $filename . ')');
33
            }
34 15
            $types[$type->name] = $type;
35
        }
36 15
        return $types;
37
    }
38
39 15
    private function parse_type(SimpleXMLElement $node) : type
40
    {
41 15
        $type = new type($node->attributes());
42 15
        $node->registerXPathNamespace('r', "http://www.midgard-project.org/repligard/1.4");
43 15
        $properties = $node->xpath('r:property');
44 15
        foreach ($properties as $property) {
45 15
            $this->add_property($type, $property);
46
        }
47 15
        $guid = new property($type, 'guid', 'guid');
48 15
        $guid->unique = true;
49 15
        $type->add_property($guid);
50 15
        if ($type->has_metadata) {
51 15
            $this->add_mixin('metadata', $type);
52
        }
53 15
        return $type;
54
    }
55
56 15
    private function add_property(type $type, SimpleXMLElement $node, string $prefix = '')
57
    {
58 15
        if ($prefix !== '') {
59 15
            $prefix .= '_';
60
        }
61 15
        $attributes = $node->attributes();
62 15
        $property_name = null;
63 15
        $property_type = null;
64 15
        $property_attributes = [];
65 15
        foreach ($attributes as $name => $value) {
66 15
            $value = (string) $value;
67 15
            switch ($name) {
68 15
                case 'primaryfield':
69 15
                case 'upfield':
70 15
                    $type->$name = $value;
71 15
                    break;
72 15
                case 'name':
73 15
                    $property_name = $prefix . $value;
74 15
                    break;
75 15
                case 'type':
76 15
                    $property_type = $value;
77 15
                    break;
78 15
                case 'field':
79 15
                    $value = $prefix . $value;
80
                    //fall-through
81
                default:
82 15
                    $property_attributes[$name] = $value;
83 15
                    break;
84
            }
85
        }
86 15
        $node->registerXPathNamespace('r', "http://www.midgard-project.org/repligard/1.4");
87 15
        $description = $node->xpath('r:description');
88 15
        if ($description) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $description of type SimpleXMLElement[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
89 15
            $property_attributes['description'] = (string) $description[0];
90
        }
91
92 15
        $property = new property($type, $property_name, $property_type);
93 15
        $property->set_multiple($property_attributes);
94
95 15
        $type->add_property($property);
96 15
    }
97
98 15
    private function add_mixin(string $name, type $type)
99
    {
100 15
        if (empty($this->mixins[$name])) {
101 15
            $schema = simplexml_load_file(dirname(__DIR__) . '/xml/' . $name . '.xml');
102 15
            $schema->registerXPathNamespace('r', 'http://www.midgard-project.org/repligard/1.4');
103 15
            $nodes = $schema->xpath('/r:Schema/r:mixin');
104 15
            $this->mixins[$name] = new mixin($nodes[0]->attributes());
105 15
            foreach ($schema->xpath('/r:Schema/r:mixin/r:property') as $property) {
106 15
                $this->add_property($this->mixins[$name], $property, $name);
107
            }
108
        }
109 15
        $type->add_property($this->mixins[$name], $name);
110 15
        foreach ($this->mixins[$name]->get_properties() as $field => $property) {
111 15
            $type->add_property($property, $field);
112
        }
113 15
    }
114
}
115