Issues (134)

src/xmlreader.php (3 issues)

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) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $description of type array<mixed,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...
88 12
            $property_attributes['description'] = (string) $description[0];
89
        }
90
91 12
        $property = new property($type, $property_name, $property_type);
0 ignored issues
show
It seems like $property_name can also be of type null; however, parameter $name of midgard\portable\mgdschema\property::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

91
        $property = new property($type, /** @scrutinizer ignore-type */ $property_name, $property_type);
Loading history...
It seems like $property_type can also be of type null; however, parameter $type of midgard\portable\mgdschema\property::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

91
        $property = new property($type, $property_name, /** @scrutinizer ignore-type */ $property_type);
Loading history...
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