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
|
|
|
private array $mixins = []; |
18
|
|
|
|
19
|
|
|
/** |
20
|
|
|
* @return type[] |
21
|
|
|
*/ |
22
|
12 |
|
public function parse(string $filename) : array |
23
|
|
|
{ |
24
|
12 |
|
$types = []; |
25
|
12 |
|
$parser = simplexml_load_file($filename); |
26
|
12 |
|
$parser->registerXPathNamespace('r', "http://www.midgard-project.org/repligard/1.4"); |
27
|
12 |
|
$nodes = $parser->xpath('/r:Schema/r:type'); |
28
|
12 |
|
foreach ($nodes as $node) { |
29
|
12 |
|
$type = $this->parse_type($node); |
30
|
12 |
|
if (empty($type->table)) { |
31
|
|
|
throw new \LogicException('"table" attribute is missing in ' . $type->name . ' (' . $filename . ')'); |
32
|
|
|
} |
33
|
12 |
|
$types[$type->name] = $type; |
34
|
|
|
} |
35
|
12 |
|
return $types; |
36
|
|
|
} |
37
|
|
|
|
38
|
12 |
|
private function parse_type(SimpleXMLElement $node) : type |
39
|
|
|
{ |
40
|
12 |
|
$type = new type($node->attributes()); |
41
|
12 |
|
$node->registerXPathNamespace('r', "http://www.midgard-project.org/repligard/1.4"); |
42
|
12 |
|
$properties = $node->xpath('r:property'); |
43
|
12 |
|
foreach ($properties as $property) { |
44
|
12 |
|
$this->add_property($type, $property); |
45
|
|
|
} |
46
|
12 |
|
$guid = new property($type, 'guid', 'guid'); |
47
|
12 |
|
$guid->unique = true; |
48
|
12 |
|
$type->add_property($guid); |
49
|
12 |
|
if ($type->has_metadata) { |
50
|
12 |
|
$this->add_mixin('metadata', $type); |
51
|
|
|
} |
52
|
12 |
|
return $type; |
53
|
|
|
} |
54
|
|
|
|
55
|
12 |
|
private function add_property(type $type, SimpleXMLElement $node, string $prefix = '') |
56
|
|
|
{ |
57
|
12 |
|
if ($prefix !== '') { |
58
|
12 |
|
$prefix .= '_'; |
59
|
|
|
} |
60
|
12 |
|
$attributes = $node->attributes(); |
61
|
12 |
|
$property_name = null; |
62
|
12 |
|
$property_type = null; |
63
|
12 |
|
$property_attributes = []; |
64
|
12 |
|
foreach ($attributes as $name => $value) { |
65
|
12 |
|
$value = (string) $value; |
66
|
|
|
switch ($name) { |
67
|
12 |
|
case 'primaryfield': |
68
|
12 |
|
case 'upfield': |
69
|
12 |
|
$type->$name = $value; |
70
|
12 |
|
break; |
71
|
12 |
|
case 'name': |
72
|
12 |
|
$property_name = $prefix . $value; |
73
|
12 |
|
break; |
74
|
12 |
|
case 'type': |
75
|
12 |
|
$property_type = $value; |
76
|
12 |
|
break; |
77
|
12 |
|
case 'field': |
78
|
12 |
|
$value = $prefix . $value; |
79
|
|
|
//fall-through |
80
|
|
|
default: |
81
|
12 |
|
$property_attributes[$name] = $value; |
82
|
12 |
|
break; |
83
|
|
|
} |
84
|
|
|
} |
85
|
12 |
|
$node->registerXPathNamespace('r', "http://www.midgard-project.org/repligard/1.4"); |
86
|
12 |
|
$description = $node->xpath('r:description'); |
87
|
12 |
|
if ($description) { |
|
|
|
|
88
|
12 |
|
$property_attributes['description'] = (string) $description[0]; |
89
|
|
|
} |
90
|
|
|
|
91
|
12 |
|
$property = new property($type, $property_name, $property_type); |
|
|
|
|
92
|
12 |
|
$property->set_multiple($property_attributes); |
93
|
|
|
|
94
|
12 |
|
$type->add_property($property); |
95
|
|
|
} |
96
|
|
|
|
97
|
12 |
|
private function add_mixin(string $name, type $type) |
98
|
|
|
{ |
99
|
12 |
|
if (empty($this->mixins[$name])) { |
100
|
12 |
|
$schema = simplexml_load_file(dirname(__DIR__) . '/xml/' . $name . '.xml'); |
101
|
12 |
|
$schema->registerXPathNamespace('r', 'http://www.midgard-project.org/repligard/1.4'); |
102
|
12 |
|
$nodes = $schema->xpath('/r:Schema/r:mixin'); |
103
|
12 |
|
$this->mixins[$name] = new mixin($nodes[0]->attributes()); |
104
|
12 |
|
foreach ($schema->xpath('/r:Schema/r:mixin/r:property') as $property) { |
105
|
12 |
|
$this->add_property($this->mixins[$name], $property, $name); |
106
|
|
|
} |
107
|
|
|
} |
108
|
12 |
|
$type->add_property($this->mixins[$name], $name); |
109
|
12 |
|
foreach ($this->mixins[$name]->get_properties() as $field => $property) { |
110
|
12 |
|
$type->add_property($property, $field); |
111
|
|
|
} |
112
|
|
|
} |
113
|
|
|
} |
114
|
|
|
|
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.