Completed
Pull Request — master (#27)
by Asmir
15:08 queued 05:10
created

SchemaReader::createOrUseSchemaForNs()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 15
ccs 4
cts 4
cp 1
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 11
nc 2
nop 2
crap 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace GoetasWebservices\XML\XSDReader;
6
7
use Closure;
8
use DOMDocument;
9
use DOMElement;
10
use DOMNode;
11
use GoetasWebservices\XML\XSDReader\Documentation\DocumentationReader;
12
use GoetasWebservices\XML\XSDReader\Documentation\StandardDocumentationReader;
13
use GoetasWebservices\XML\XSDReader\Exception\IOException;
14
use GoetasWebservices\XML\XSDReader\Exception\TypeException;
15
use GoetasWebservices\XML\XSDReader\Schema\Attribute\Attribute;
16
use GoetasWebservices\XML\XSDReader\Schema\Attribute\AttributeContainer;
17
use GoetasWebservices\XML\XSDReader\Schema\Attribute\AttributeDef;
18
use GoetasWebservices\XML\XSDReader\Schema\Attribute\AttributeItem;
19
use GoetasWebservices\XML\XSDReader\Schema\Attribute\Group as AttributeGroup;
20
use GoetasWebservices\XML\XSDReader\Schema\Element\Element;
21
use GoetasWebservices\XML\XSDReader\Schema\Element\ElementContainer;
22
use GoetasWebservices\XML\XSDReader\Schema\Element\ElementDef;
23
use GoetasWebservices\XML\XSDReader\Schema\Element\ElementRef;
24
use GoetasWebservices\XML\XSDReader\Schema\Element\Group;
25
use GoetasWebservices\XML\XSDReader\Schema\Element\InterfaceSetMinMax;
26
use GoetasWebservices\XML\XSDReader\Schema\Element\GroupRef;
27
use GoetasWebservices\XML\XSDReader\Schema\Exception\TypeNotFoundException;
28
use GoetasWebservices\XML\XSDReader\Schema\Inheritance\Base;
29
use GoetasWebservices\XML\XSDReader\Schema\Inheritance\Extension;
30
use GoetasWebservices\XML\XSDReader\Schema\Inheritance\Restriction;
31
use GoetasWebservices\XML\XSDReader\Schema\Item;
32
use GoetasWebservices\XML\XSDReader\Schema\Schema;
33
use GoetasWebservices\XML\XSDReader\Schema\SchemaItem;
34
use GoetasWebservices\XML\XSDReader\Schema\Type\BaseComplexType;
35
use GoetasWebservices\XML\XSDReader\Schema\Type\ComplexType;
36
use GoetasWebservices\XML\XSDReader\Schema\Type\ComplexTypeSimpleContent;
37
use GoetasWebservices\XML\XSDReader\Schema\Type\SimpleType;
38
use GoetasWebservices\XML\XSDReader\Schema\Type\Type;
39
use GoetasWebservices\XML\XSDReader\Utils\UrlUtils;
40
41
class SchemaReader
42
{
43
    public const XSD_NS = 'http://www.w3.org/2001/XMLSchema';
44
45
    public const XML_NS = 'http://www.w3.org/XML/1998/namespace';
46
47
    /**
48
     * @var DocumentationReader
49
     */
50
    private $documentationReader;
51
52
    /**
53
     * @var Schema[]
54
     */
55
    private $loadedFiles = array();
56
57
    /**
58
     * @var Schema[][]
59
     */
60
    private $loadedSchemas = array();
61
62
    /**
63
     * @var string[]
64
     */
65
    protected $knownLocationSchemas = [
66
        'http://www.w3.org/2001/xml.xsd' => (
67
            __DIR__.'/Resources/xml.xsd'
68
        ),
69
        'http://www.w3.org/2001/XMLSchema.xsd' => (
70
            __DIR__.'/Resources/XMLSchema.xsd'
71
        ),
72
        'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' => (
73
            __DIR__.'/Resources/oasis-200401-wss-wssecurity-secext-1.0.xsd'
74
        ),
75
        'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd' => (
76
            __DIR__.'/Resources/oasis-200401-wss-wssecurity-utility-1.0.xsd'
77
        ),
78
        'https://www.w3.org/TR/xmldsig-core/xmldsig-core-schema.xsd' => (
79
            __DIR__.'/Resources/xmldsig-core-schema.xsd'
80
        ),
81
        'http://www.w3.org/TR/xmldsig-core/xmldsig-core-schema.xsd' => (
82
            __DIR__.'/Resources/xmldsig-core-schema.xsd'
83
        ),
84
    ];
85
86
    /**
87
     * @var string[]
88
     */
89 56
    protected static $globalSchemaInfo = array(
90
        self::XML_NS => 'http://www.w3.org/2001/xml.xsd',
91 56
        self::XSD_NS => 'http://www.w3.org/2001/XMLSchema.xsd',
92 56
    );
93
94 56
    public function __construct(DocumentationReader $documentationReader = null)
95 56
    {
96
        if (null === $documentationReader) {
97
            $documentationReader = new StandardDocumentationReader();
98
        }
99
        $this->documentationReader = $documentationReader;
100
    }
101
102 47
    public function addKnownSchemaLocation(string $remote, string $local): void
103
    {
104
        $this->knownLocationSchemas[$remote] = $local;
105
    }
106 47
107 47
    private function loadAttributeGroup(
108 47
        Schema $schema,
109
        DOMElement $node
110 47
    ): Closure {
111 47
        $attGroup = new AttributeGroup($schema, $node->getAttribute('name'));
112 47
        $attGroup->setDoc($this->getDocumentation($node));
113 47
        $schema->addAttributeGroup($attGroup);
114
115
        return function () use ($schema, $node, $attGroup) {
116
            SchemaReader::againstDOMNodeList(
117 47
                $node,
118 47
                function (
119
                    DOMElement $node,
120 47
                    DOMElement $childNode
121 47
                ) use (
122 47
                    $schema,
123 47
                    $attGroup
124 47
                ) {
125 47
                    switch ($childNode->localName) {
126
                        case 'attribute':
127 47
                            $attribute = $this->getAttributeFromAttributeOrRef(
128 47
                                $childNode,
129 47
                                $schema,
130 1
                                $node
131 1
                            );
132 1
                            $attGroup->addAttribute($attribute);
133 1
                            break;
134 1
                        case 'attributeGroup':
135
                            $this->findSomethingLikeAttributeGroup(
136 1
                                $schema,
137
                                $node,
138 47
                                $childNode,
139
                                $attGroup
140 47
                            );
141
                            break;
142
                    }
143 47
                }
144
            );
145
        };
146
    }
147
148 47
    private function getAttributeFromAttributeOrRef(
149 47
        DOMElement $childNode,
150
        Schema $schema,
151
        DOMElement $node
152
    ): AttributeItem {
153
        if ($childNode->hasAttribute('ref')) {
154 47
            $attribute = $this->findAttributeItem($schema, $node, $childNode->getAttribute('ref'));
155
        } else {
156
            /**
157 47
             * @var Attribute
158
             */
159
            $attribute = $this->loadAttribute($schema, $childNode);
160 47
        }
161
162
        return $attribute;
163
    }
164 47
165 47
    private function loadAttribute(
166 47
        Schema $schema,
167
        DOMElement $node
168 47
    ): Attribute {
169 1
        $attribute = new Attribute($schema, $node->getAttribute('name'));
170
        $attribute->setDoc($this->getDocumentation($node));
171 47
        $this->fillItem($attribute, $node);
172 1
173
        if ($node->hasAttribute('nillable')) {
174 47
            $attribute->setNil($node->getAttribute('nillable') == 'true');
175 47
        }
176
        if ($node->hasAttribute('form')) {
177
            $attribute->setQualified($node->getAttribute('form') == 'qualified');
178 47
        }
179
        if ($node->hasAttribute('use')) {
180
            $attribute->setUse($node->getAttribute('use'));
181 47
        }
182
183
        return $attribute;
184
    }
185
186 47
    private function loadAttributeOrElementDef(
187 47
        Schema $schema,
188 47
        DOMElement $node,
189 47
        bool $attributeDef
190
    ): Closure {
191 47
        $name = $node->getAttribute('name');
192 47
        if ($attributeDef) {
193
            $attribute = new AttributeDef($schema, $name);
194
            $schema->addAttribute($attribute);
195 47
        } else {
196 47
            $attribute = new ElementDef($schema, $name);
197 47
            $schema->addElement($attribute);
198
        }
199
200 47
        return function () use ($attribute, $node) {
201
            $this->fillItem($attribute, $node);
202 47
        };
203
    }
204
205 47
    private function loadAttributeDef(Schema $schema, DOMElement $node): Closure
206
    {
207 47
        return $this->loadAttributeOrElementDef($schema, $node, true);
208
    }
209
210
    private function getDocumentation(DOMElement $node): string
211
    {
212
        return $this->documentationReader->get($node);
213 47
    }
214
215 47
    /**
216 47
     * @return Closure[]
217
     */
218 47
    private function schemaNode(Schema $schema, DOMElement $node, Schema $parent = null): array
219 47
    {
220 47
        $this->setSchemaThingsFromNode($schema, $node, $parent);
221
        $functions = array();
222
223
        static::againstDOMNodeList(
0 ignored issues
show
Bug introduced by
Since againstDOMNodeList() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of againstDOMNodeList() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
224 47
            $node,
225 47
            function (
226
                DOMElement $node,
227 47
                DOMElement $childNode
228
            ) use (
229 47
                $schema,
230 47
                &$functions
231 47
            ) {
232 47
                $callback = null;
233 47
234 47
                switch ($childNode->localName) {
235 47
                    case 'attributeGroup':
236 47
                        $callback = $this->loadAttributeGroup($schema, $childNode);
237 47
                        break;
238 47
                    case 'include':
239 47
                    case 'import':
240 47
                        $callback = $this->loadImport($schema, $childNode);
241 47
                        break;
242 47
                    case 'element':
243 47
                        $callback = $this->loadElementDef($schema, $childNode);
244 47
                        break;
245 47
                    case 'attribute':
246 47
                        $callback = $this->loadAttributeDef($schema, $childNode);
247 47
                        break;
248 47
                    case 'group':
249 47
                        $callback = $this->loadGroup($schema, $childNode);
250 47
                        break;
251 47
                    case 'complexType':
252
                        $callback = $this->loadComplexType($schema, $childNode);
253
                        break;
254 47
                    case 'simpleType':
255 47
                        $callback = $this->loadSimpleType($schema, $childNode);
256
                        break;
257 47
                }
258
259
                if ($callback instanceof Closure) {
260 47
                    $functions[] = $callback;
261
                }
262
            }
263 47
        );
264
265 47
        return $functions;
266 47
    }
267
268 47
    private function loadGroupRef(Group $referenced, DOMElement $node): GroupRef
269 47
    {
270
        $ref = new GroupRef($referenced);
271 47
        $ref->setDoc($this->getDocumentation($node));
272
273
        self::maybeSetMax($ref, $node);
274 47
        self::maybeSetMin($ref, $node);
275
276
        return $ref;
277 47
    }
278
279 47
    private static function maybeSetMax(InterfaceSetMinMax $ref, DOMElement $node): InterfaceSetMinMax
280
    {
281
        if (
282 47
            $node->hasAttribute('maxOccurs')
283
        ) {
284
            $ref->setMax($node->getAttribute('maxOccurs') == 'unbounded' ? -1 : (int) $node->getAttribute('maxOccurs'));
285 47
        }
286
287 47
        return $ref;
288 47
    }
289
290
    private static function maybeSetMin(InterfaceSetMinMax $ref, DOMElement $node): InterfaceSetMinMax
291 47
    {
292
        if ($node->hasAttribute('minOccurs')) {
293
            $ref->setMin((int) $node->getAttribute('minOccurs'));
294 47
        }
295
296
        return $ref;
297
    }
298 47
299 47
    private function loadSequence(ElementContainer $elementContainer, DOMElement $node, int $max = null): void
300 47
    {
301
        $max =
302 47
        (
303 47
            (is_int($max) && (bool) $max) ||
304
            $node->getAttribute('maxOccurs') == 'unbounded' ||
305 47
            $node->getAttribute('maxOccurs') > 1
306 47
        )
307 47
            ? 2
308
            : null;
309
310
        static::againstDOMNodeList(
0 ignored issues
show
Bug introduced by
Since againstDOMNodeList() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of againstDOMNodeList() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
311 47
            $node,
312 47
            function (
313
                DOMElement $node,
314 47
                DOMElement $childNode
315 47
            ) use (
316 47
                $elementContainer,
317 47
                $max
318 47
            ) {
319
                $this->loadSequenceChildNode(
320 47
                    $elementContainer,
321
                    $node,
322 47
                    $childNode,
323
                    $max
324
                );
325
            }
326
        );
327 47
    }
328
329
    /**
330
     * @param int|null $max
331
     */
332
    private function loadSequenceChildNode(
333 47
        ElementContainer $elementContainer,
334 47
        DOMElement $node,
335 47
        DOMElement $childNode,
336 47
        $max
337 47
    ): void {
338 47
        switch ($childNode->localName) {
339 47
            case 'sequence':
340 47
            case 'choice':
341
            case 'all':
342 47
                $this->loadSequence(
343 47
                    $elementContainer,
344 47
                    $childNode,
345 47
                    $max
346 47
                );
347 47
                break;
348 47
            case 'element':
349
                $this->loadSequenceChildNodeLoadElement(
350 47
                    $elementContainer,
351 47
                    $node,
352 47
                    $childNode,
353 47
                    $max
354 47
                );
355 47
                break;
356 47
            case 'group':
357
                $this->addGroupAsElement(
358 47
                    $elementContainer->getSchema(),
359
                    $node,
360 47
                    $childNode,
361
                    $elementContainer
362
                );
363
                break;
364
        }
365 47
    }
366
367
    /**
368
     * @param int|null $max
369
     */
370
    private function loadSequenceChildNodeLoadElement(
371 47
        ElementContainer $elementContainer,
372 47
        DOMElement $node,
373 47
        DOMElement $childNode,
374
        $max
375 47
    ): void {
376
        if ($childNode->hasAttribute('ref')) {
377 47
            $element = new ElementRef(
378 47
                $this->findElement($elementContainer->getSchema(), $node, $childNode->getAttribute('ref'))
379 47
            );
380
            $element->setDoc($this->getDocumentation($childNode));
381
382 47
            self::maybeSetMax($element, $childNode);
383 47
            self::maybeSetMin($element, $childNode);
384
            if ($childNode->hasAttribute('nillable')) {
385
                $element->setNil($childNode->getAttribute('nillable') == 'true');
386 47
            }
387 47
            if ($childNode->hasAttribute('form')) {
388 47
                $element->setQualified($childNode->getAttribute('form') == 'qualified');
389
            }
390
        } else {
391 47
            $element = $this->loadElement(
392
                $elementContainer->getSchema(),
393
                $childNode
394
            );
395
        }
396
        if ($max > 1) {
397 47
            /*
398
            * although one might think the typecast is not needed with $max being `? int $max` after passing > 1,
399 47
            * phpstan@a4f89fa still thinks it's possibly null.
400 47
            * see https://github.com/phpstan/phpstan/issues/577 for related issue
401
            */
402 47
            $element->setMax((int) $max);
403
        }
404
        $elementContainer->addElement($element);
405
    }
406
407
    private function addGroupAsElement(
408 47
        Schema $schema,
409 47
        DOMElement $node,
410 47
        DOMElement $childNode,
411 47
        ElementContainer $elementContainer
412
    ): void {
413
        $referencedGroup = $this->findGroup(
414 47
            $schema,
415 47
            $node,
416 47
            $childNode->getAttribute('ref')
417
        );
418 47
419
        $group = $this->loadGroupRef($referencedGroup, $childNode);
420 47
        $elementContainer->addElement($group);
421 47
    }
422
423 47
    private function loadGroup(Schema $schema, DOMElement $node): Closure
424
    {
425
        $group = new Group($schema, $node->getAttribute('name'));
426
        $group->setDoc($this->getDocumentation($node));
427
428
        if ($node->hasAttribute('maxOccurs')) {
429 47
            /**
430
             * @var GroupRef
431
             */
432
            $group = self::maybeSetMax(new GroupRef($group), $node);
433
        }
434
        if ($node->hasAttribute('minOccurs')) {
435
            /**
436
             * @var GroupRef
437
             */
438
            $group = self::maybeSetMin(
439 47
                $group instanceof GroupRef ? $group : new GroupRef($group),
0 ignored issues
show
Bug introduced by
It seems like $group defined by self::maybeSetMin($group...roupRef($group), $node) on line 438 can also be of type object<GoetasWebservices...ent\InterfaceSetMinMax>; however, GoetasWebservices\XML\XS...GroupRef::__construct() does only seem to accept object<GoetasWebservices...r\Schema\Element\Group>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
440
                $node
441 47
            );
442 47
        }
443 47
444 47
        $schema->addGroup($group);
0 ignored issues
show
Bug introduced by
It seems like $group can also be of type object<GoetasWebservices...ent\InterfaceSetMinMax>; however, GoetasWebservices\XML\XS...hema\Schema::addGroup() does only seem to accept object<GoetasWebservices...r\Schema\Element\Group>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
445 47
446 47
        return function () use ($group, $node) {
447 47
            static::againstDOMNodeList(
0 ignored issues
show
Bug introduced by
Since againstDOMNodeList() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of againstDOMNodeList() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
448 47
                $node,
449 47
                function (DOMelement $node, DOMElement $childNode) use ($group) {
450 47
                    switch ($childNode->localName) {
451
                        case 'sequence':
452 47
                        case 'choice':
453
                        case 'all':
454 47
                            $this->loadSequence($group, $childNode);
0 ignored issues
show
Bug introduced by
It seems like $group can also be of type object<GoetasWebservices...ent\InterfaceSetMinMax>; however, GoetasWebservices\XML\XS...aReader::loadSequence() does only seem to accept object<GoetasWebservices...ement\ElementContainer>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
455
                            break;
456
                    }
457 47
                }
458
            );
459
        };
460
    }
461
462 47
    private function loadComplexType(Schema $schema, DOMElement $node, Closure $callback = null): Closure
463
    {
464 47
        /**
465 47
         * @var bool
466 47
         */
467
        $isSimple = false;
468
469
        static::againstDOMNodeList(
0 ignored issues
show
Bug introduced by
Since againstDOMNodeList() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of againstDOMNodeList() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
470 47
            $node,
471
            function (
472 47
                DOMElement $node,
473 1
                DOMElement $childNode
474
            ) use (
475 47
                &$isSimple
476 2
            ) {
477
                if ($isSimple) {
478 47
                    return;
479
                }
480
                if ($childNode->localName === 'simpleContent') {
481 47
                    $isSimple = true;
482
                }
483 47
            }
484 47
        );
485 47
486
        $type = $isSimple ? new ComplexTypeSimpleContent($schema, $node->getAttribute('name')) : new ComplexType($schema, $node->getAttribute('name'));
487
488 47
        $type->setDoc($this->getDocumentation($node));
489 47
        if ($node->getAttribute('name')) {
490
            $schema->addType($type);
491 47
        }
492 47
493 47
        return function () use ($type, $node, $schema, $callback) {
494
            $this->fillTypeNode($type, $node, true);
495
496
            static::againstDOMNodeList(
0 ignored issues
show
Bug introduced by
Since againstDOMNodeList() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of againstDOMNodeList() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
497 47
                $node,
498 47
                function (
499
                    DOMElement $node,
500 47
                    DOMElement $childNode
501 47
                ) use (
502 47
                    $schema,
503 47
                    $type
504 47
                ) {
505
                    $this->loadComplexTypeFromChildNode(
506 47
                        $type,
507
                        $node,
508
                        $childNode,
509 47
                        $schema
510 47
                    );
511
                }
512 47
            );
513
514
            if ($callback instanceof Closure) {
515 47
                call_user_func($callback, $type);
516
            }
517
        };
518
    }
519
520
    private function loadComplexTypeFromChildNode(
521 47
        BaseComplexType $type,
522 47
        DOMElement $node,
523 47
        DOMElement $childNode,
524 47
        Schema $schema
525 47
    ): void {
526 47
        switch ($childNode->localName) {
527 47
            case 'sequence':
528 47
            case 'choice':
529
            case 'all':
530
                if ($type instanceof ElementContainer) {
531 47
                    $this->loadSequence(
532 47
                        $type,
533 47
                        $childNode
534 47
                    );
535 47
                }
536 47
                break;
537 47
            case 'attribute':
538
                $this->addAttributeFromAttributeOrRef(
539 47
                    $type,
540 47
                    $childNode,
541 2
                    $schema,
542 2
                    $node
543 2
                );
544 2
                break;
545 2
            case 'attributeGroup':
546
                $this->findSomethingLikeAttributeGroup(
547 2
                    $schema,
548 47
                    $node,
549
                    $childNode,
550 1
                    $type
551
                );
552 1
                break;
553 1
            case 'group':
554 1
                if (
555 1
                    $type instanceof ComplexType
556 1
                ) {
557
                    $this->addGroupAsElement(
558
                        $schema,
559 1
                        $node,
560
                        $childNode,
561 47
                        $type
562
                    );
563 47
                }
564
                break;
565 47
        }
566 47
    }
567 47
568 47
    private function loadSimpleType(Schema $schema, DOMElement $node, Closure $callback = null): Closure
569
    {
570
        $type = new SimpleType($schema, $node->getAttribute('name'));
571 47
        $type->setDoc($this->getDocumentation($node));
572 47
        if ($node->getAttribute('name')) {
573
            $schema->addType($type);
574 47
        }
575 47
576 47
        return function () use ($type, $node, $callback) {
577 47
            $this->fillTypeNode($type, $node, true);
578 47
579 47
            static::againstDOMNodeList(
0 ignored issues
show
Bug introduced by
Since againstDOMNodeList() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of againstDOMNodeList() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
580 47
                $node,
581 47
                function (DOMElement $node, DOMElement $childNode) use ($type) {
582 47
                    switch ($childNode->localName) {
583 47
                        case 'union':
584
                            $this->loadUnion($type, $childNode);
585 47
                            break;
586
                        case 'list':
587
                            $this->loadList($type, $childNode);
588 47
                            break;
589 47
                    }
590
                }
591 47
            );
592
593
            if ($callback instanceof Closure) {
594 47
                call_user_func($callback, $type);
595
            }
596 47
        };
597
    }
598
599
    private function loadList(SimpleType $type, DOMElement $node): void
600 47
    {
601 47
        if ($node->hasAttribute('itemType')) {
602
            /**
603 47
             * @var SimpleType
604 47
             */
605 47
            $listType = $this->findSomeType($type, $node, 'itemType');
606
            $type->setList($listType);
0 ignored issues
show
Documentation introduced by
$listType is of type object<GoetasWebservices...ader\Schema\SchemaItem>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
607
        } else {
608
            self::againstDOMNodeList(
609 47
                $node,
610
                function (
611 47
                    DOMElement $node,
612 47
                    DOMElement $childNode
613 47
                ) use (
614 47
                    $type
615 47
                ) {
616 47
                    $this->loadTypeWithCallback(
617
                        $type->getSchema(),
618 47
                        $childNode,
619
                        function (SimpleType $list) use ($type) {
620
                            $type->setList($list);
0 ignored issues
show
Documentation introduced by
$list is of type object<GoetasWebservices...Schema\Type\SimpleType>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
621 47
                        }
622
                    );
623 47
                }
624
            );
625
        }
626
    }
627
628 47
    private function findSomeType(
629 47
        SchemaItem $fromThis,
630 47
        DOMElement $node,
631 47
        string $attributeName
632
    ): SchemaItem {
633
        return $this->findSomeTypeFromAttribute(
634
            $fromThis,
635 47
            $node,
636
            $node->getAttribute($attributeName)
637
        );
638
    }
639
640 47
    private function findSomeTypeFromAttribute(
641 47
        SchemaItem $fromThis,
642 47
        DOMElement $node,
643 47
        string $attributeName
644
    ): SchemaItem {
645
        $out = $this->findType(
646 47
            $fromThis->getSchema(),
647
            $node,
648
            $attributeName
649 47
        );
650
651 47
        return $out;
652 47
    }
653 47
654
    private function loadUnion(SimpleType $type, DOMElement $node): void
655
    {
656
        if ($node->hasAttribute('memberTypes')) {
657 47
            $types = preg_split('/\s+/', $node->getAttribute('memberTypes'));
658 47
            foreach ($types as $typeName) {
659 47
                /**
660 47
                 * @var SimpleType
661
                 */
662 47
                $unionType = $this->findSomeTypeFromAttribute(
663
                    $type,
664
                    $node,
665 47
                    $typeName
666 47
                );
667 47
                $type->addUnion($unionType);
0 ignored issues
show
Documentation introduced by
$unionType is of type object<GoetasWebservices...ader\Schema\SchemaItem>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
668
            }
669
        }
670
        self::againstDOMNodeList(
671 47
            $node,
672
            function (
673 47
                DOMElement $node,
674 47
                DOMElement $childNode
675 47
            ) use (
676 47
                $type
677 47
            ) {
678 47
                $this->loadTypeWithCallback(
679
                    $type->getSchema(),
680 47
                    $childNode,
681
                    function (SimpleType $unType) use ($type) {
682 47
                        $type->addUnion($unType);
0 ignored issues
show
Documentation introduced by
$unType is of type object<GoetasWebservices...Schema\Type\SimpleType>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
683
                    }
684 47
                );
685
            }
686 47
        );
687 47
    }
688
689
    private function fillTypeNode(Type $type, DOMElement $node, bool $checkAbstract = false): void
690 47
    {
691 47
        if ($checkAbstract) {
692 47
            $type->setAbstract($node->getAttribute('abstract') === 'true' || $node->getAttribute('abstract') === '1');
693 47
        }
694 47
695 47
        static::againstDOMNodeList(
0 ignored issues
show
Bug introduced by
Since againstDOMNodeList() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of againstDOMNodeList() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
696 47
            $node,
697 47
            function (DOMElement $node, DOMElement $childNode) use ($type) {
698 47
                switch ($childNode->localName) {
699 47
                    case 'restriction':
700
                        $this->loadRestriction($type, $childNode);
701 47
                        break;
702 47
                    case 'extension':
703 47
                        if ($type instanceof BaseComplexType) {
704 47
                            $this->loadExtension($type, $childNode);
705 47
                        }
706
                        break;
707 47
                    case 'simpleContent':
708
                    case 'complexContent':
709 47
                        $this->fillTypeNode($type, $childNode);
710
                        break;
711 47
                }
712
            }
713 47
        );
714 47
    }
715
716 47
    private function loadExtension(BaseComplexType $type, DOMElement $node): void
717 47
    {
718 47
        $extension = new Extension();
719 47
        $type->setExtension($extension);
720 47
721
        if ($node->hasAttribute('base')) {
722
            $this->findAndSetSomeBase(
723 47
                $type,
724 47
                $extension,
725
                $node
726 47
            );
727
        }
728
        $this->loadExtensionChildNodes($type, $node);
729
    }
730
731
    private function findAndSetSomeBase(
732
        Type $type,
733
        Base $setBaseOnThis,
734 47
        DOMElement $node
735 47
    ): void {
736 47
        /**
737
         * @var Type
738 47
         */
739
        $parent = $this->findSomeType($type, $node, 'base');
740
        $setBaseOnThis->setBase($parent);
0 ignored issues
show
Compatibility introduced by
$parent of type object<GoetasWebservices...ader\Schema\SchemaItem> is not a sub-type of object<GoetasWebservices...eader\Schema\Type\Type>. It seems like you assume a concrete implementation of the interface GoetasWebservices\XML\XSDReader\Schema\SchemaItem to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
741
    }
742 47
743 47
    private function loadExtensionChildNodes(
744 47
        BaseComplexType $type,
745
        DOMElement $node
746
    ) {
747
        static::againstDOMNodeList(
0 ignored issues
show
Bug introduced by
Since againstDOMNodeList() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of againstDOMNodeList() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
748 47
            $node,
749
            function (
750 47
                DOMElement $node,
751 47
                DOMElement $childNode
752 47
            ) use (
753 47
                $type
754 47
            ) {
755 47
                switch ($childNode->localName) {
756 47
                    case 'sequence':
757 47
                    case 'choice':
758
                    case 'all':
759
                        if ($type instanceof ElementContainer) {
760 47
                            $this->loadSequence(
761 47
                                $type,
762 47
                                $childNode
763 47
                            );
764 47
                        }
765 47
                        break;
766 47
                    case 'attribute':
767
                        $this->addAttributeFromAttributeOrRef(
768 47
                            $type,
769 47
                            $childNode,
770 47
                            $type->getSchema(),
771 47
                            $node
772 47
                        );
773 47
                        break;
774 47
                    case 'attributeGroup':
775
                        $this->findSomethingLikeAttributeGroup(
776 47
                            $type->getSchema(),
777
                            $node,
778 47
                            $childNode,
779
                            $type
780 47
                        );
781
                        break;
782 47
                }
783
            }
784 47
        );
785 47
    }
786 47
787 47
    private function loadRestriction(Type $type, DOMElement $node): void
788
    {
789 47
        $restriction = new Restriction();
790 47
        $type->setRestriction($restriction);
791 47
        if ($node->hasAttribute('base')) {
792
            $this->findAndSetSomeBase($type, $restriction, $node);
793
        } else {
794
            self::againstDOMNodeList(
795 47
                $node,
796 47
                function (
797
                    DOMElement $node,
798 47
                    DOMElement $childNode
799 47
                ) use (
800 47
                    $type,
801 47
                    $restriction
802 47
                ) {
803 47
                    $this->loadTypeWithCallback(
804
                        $type->getSchema(),
805 47
                        $childNode,
806
                        function (Type $restType) use ($restriction) {
807
                            $restriction->setBase($restType);
808 47
                        }
809 47
                    );
810 47
                }
811
            );
812
        }
813
        self::againstDOMNodeList(
814 47
            $node,
815
            function (
816
                DOMElement $node,
817 47
                DOMElement $childNode
818 47
            ) use (
819
                $restriction
820 47
            ) {
821
                if (
822
                    in_array(
823
                        $childNode->localName,
824
                        [
825
                            'enumeration',
826
                            'pattern',
827
                            'length',
828
                            'minLength',
829
                            'maxLength',
830
                            'minInclusive',
831
                            'maxInclusive',
832
                            'minExclusive',
833 47
                            'maxExclusive',
834
                            'fractionDigits',
835
                            'totalDigits',
836 47
                            'whiteSpace',
837 47
                        ],
838
                        true
839 47
                    )
840 47
                ) {
841
                    $restriction->addCheck(
842
                        $childNode->localName,
843
                        [
844 47
                            'value' => $childNode->getAttribute('value'),
845
                            'doc' => $this->getDocumentation($childNode),
846 47
                        ]
847
                    );
848
                }
849
            }
850
        );
851 47
    }
852
853 47
    /**
854 47
     * @return mixed[]
855 47
     */
856 47
    private static function splitParts(DOMElement $node, string $typeName): array
857
    {
858
        $prefix = null;
859 47
        $name = $typeName;
860
        if (strpos($typeName, ':') !== false) {
861
            list($prefix, $name) = explode(':', $typeName);
862 47
        }
863 47
864 47
        $namespace = $node->lookupNamespaceUri($prefix ?: '');
865
866
        return array(
867
            $name,
868 47
            $namespace,
869
            $prefix,
870 47
        );
871
    }
872 47
873
    private function findAttributeItem(Schema $schema, DOMElement $node, string $typeName): AttributeItem
874
    {
875 47
        list($name, $namespace) = static::splitParts($node, $typeName);
0 ignored issues
show
Bug introduced by
Since splitParts() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of splitParts() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
876
877
        $namespace = $namespace ?: $schema->getTargetNamespace();
878
879
        try {
880
            return $schema->findAttribute($name, $namespace);
881
        } catch (TypeNotFoundException $e) {
882
            throw new TypeException(
883
                sprintf(
884
                    "Can't find %s named {%s}#%s, at line %d in %s ",
885
                    'attribute',
886
                    $namespace,
887
                    $name,
888
                    $node->getLineNo(),
889
                    $node->ownerDocument->documentURI
890
                ),
891
                0,
892 47
                $e
893
            );
894 47
        }
895
    }
896 47
897
    private function findAttributeGroup(Schema $schema, DOMElement $node, string $typeName): AttributeGroup
898
    {
899 47
        list($name, $namespace) = static::splitParts($node, $typeName);
0 ignored issues
show
Bug introduced by
Since splitParts() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of splitParts() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
900
901
        $namespace = $namespace ?: $schema->getTargetNamespace();
902
903
        try {
904
            return $schema->findAttributeGroup($name, $namespace);
905
        } catch (TypeNotFoundException $e) {
906
            throw new TypeException(
907
                sprintf(
908
                    "Can't find %s named {%s}#%s, at line %d in %s ",
909
                    'attributegroup',
910
                    $namespace,
911
                    $name,
912
                    $node->getLineNo(),
913
                    $node->ownerDocument->documentURI
914
                ),
915
                0,
916 47
                $e
917
            );
918 47
        }
919
    }
920 47
921
    private function findElement(Schema $schema, DOMElement $node, string $typeName): ElementDef
922
    {
923 47
        list($name, $namespace) = static::splitParts($node, $typeName);
0 ignored issues
show
Bug introduced by
Since splitParts() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of splitParts() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
924
925
        $namespace = $namespace ?: $schema->getTargetNamespace();
926
927
        try {
928
            return $schema->findElement($name, $namespace);
929
        } catch (TypeNotFoundException $e) {
930
            throw new TypeException(
931
                sprintf(
932
                    "Can't find %s named {%s}#%s, at line %d in %s ",
933
                    'element',
934
                    $namespace,
935
                    $name,
936
                    $node->getLineNo(),
937
                    $node->ownerDocument->documentURI
938
                ),
939
                0,
940 47
                $e
941
            );
942 47
        }
943
    }
944 47
945
    private function findGroup(Schema $schema, DOMElement $node, string $typeName): Group
946
    {
947 47
        list($name, $namespace) = static::splitParts($node, $typeName);
0 ignored issues
show
Bug introduced by
Since splitParts() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of splitParts() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
948
949
        $namespace = $namespace ?: $schema->getTargetNamespace();
950
951
        try {
952
            return $schema->findGroup($name, $namespace);
953
        } catch (TypeNotFoundException $e) {
954
            throw new TypeException(
955
                sprintf(
956
                    "Can't find %s named {%s}#%s, at line %d in %s ",
957
                    'group',
958
                    $namespace,
959
                    $name,
960
                    $node->getLineNo(),
961
                    $node->ownerDocument->documentURI
962
                ),
963
                0,
964 47
                $e
965
            );
966 47
        }
967
    }
968 47
969
    private function findType(Schema $schema, DOMElement $node, string $typeName): SchemaItem
970
    {
971 47
        list($name, $namespace) = static::splitParts($node, $typeName);
0 ignored issues
show
Bug introduced by
Since splitParts() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of splitParts() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
972
973
        $namespace = $namespace ?: $schema->getTargetNamespace();
974
975
        try {
976
            return $schema->findType($name, $namespace);
977
        } catch (TypeNotFoundException $e) {
978
            throw new TypeException(
979
                sprintf(
980
                    "Can't find %s named {%s}#%s, at line %d in %s ",
981
                    'type',
982
                    $namespace,
983
                    $name,
984
                    $node->getLineNo(),
985
                    $node->ownerDocument->documentURI
986
                ),
987
                0,
988
                $e
989
            );
990
        }
991 47
    }
992
993 47
    /**
994
     * @return Closure
995
     */
996 47
    private function loadElementDef(Schema $schema, DOMElement $node): Closure
997
    {
998
        return $this->loadAttributeOrElementDef($schema, $node, false);
999
    }
1000
1001 47
    private function fillItem(Item $element, DOMElement $node)
1002 47
    {
1003 47
        /**
1004 47
         * @var bool
1005
         */
1006
        $skip = false;
1007
        static::againstDOMNodeList(
0 ignored issues
show
Bug introduced by
Since againstDOMNodeList() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of againstDOMNodeList() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
1008 47
            $node,
1009 47
            function (
1010
                DOMElement $node,
1011
                DOMElement $childNode
1012 47
            ) use (
1013 47
                $element,
1014 47
                &$skip
1015
            ) {
1016 47
                if (
1017
                    !$skip &&
1018
                    in_array(
1019 47
                        $childNode->localName,
1020
                        [
1021
                            'complexType',
1022 47
                            'simpleType',
1023 47
                        ],
1024 47
                        true
1025 47
                    )
1026 47
                ) {
1027 47
                    $this->loadTypeWithCallback(
1028
                        $element->getSchema(),
1029 47
                        $childNode,
1030
                        function (Type $type) use ($element) {
1031 47
                            $element->setType($type);
1032
                        }
1033 47
                    );
1034 47
                    $skip = true;
1035
                }
1036 47
            }
1037 47
        );
1038
        if ($skip) {
1039 47
            return;
1040
        }
1041 47
        $this->fillItemNonLocalType($element, $node);
1042
    }
1043
1044
    private function fillItemNonLocalType(Item $element, DOMElement $node): void
1045 47
    {
1046
        if ($node->getAttribute('type')) {
1047
            /**
1048
             * @var Type
1049
             */
1050 47
            $type = $this->findSomeType($element, $node, 'type');
1051 47
        } else {
1052 47
            /**
1053 47
             * @var Type
1054
             */
1055
            $type = $this->findSomeTypeFromAttribute(
1056
                $element,
1057 47
                $node,
1058 47
                ($node->lookupPrefix(self::XSD_NS).':anyType')
1059
            );
1060 47
        }
1061
1062
        $element->setType($type);
0 ignored issues
show
Compatibility introduced by
$type of type object<GoetasWebservices...ader\Schema\SchemaItem> is not a sub-type of object<GoetasWebservices...eader\Schema\Type\Type>. It seems like you assume a concrete implementation of the interface GoetasWebservices\XML\XSDReader\Schema\SchemaItem to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
1063
    }
1064 47
1065 47
    private function loadImport(
1066
        Schema $schema,
1067 47
        DOMElement $node
1068
    ): Closure {
1069 47
1070
        $namespace = $node->getAttribute('namespace');
1071 47
        $schemaLocation = $node->getAttribute('schemaLocation');
1072 47
1073 47
        // postpone schema loading
1074
        if ($namespace && !$schemaLocation && !isset(self::$globalSchemaInfo[$namespace])) {
1075 47
            return function () use ($node, $schema, $namespace) {
1076 47
                if (!empty($this->loadedSchemas[$namespace])) {
1077
                    foreach ($this->loadedSchemas[$namespace] as $s) {
1078
                        $schema->addSchema($s, $namespace);
0 ignored issues
show
Documentation introduced by
$s is of type object<GoetasWebservices...SDReader\Schema\Schema>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1079
                    }
1080 1
                }
1081
            };
1082
        } elseif ($namespace && !$schemaLocation && isset(self::$globalSchemaInfo[$namespace])) {
1083
            $schema->addSchema(self::$globalSchemaInfo[$namespace]);
0 ignored issues
show
Documentation introduced by
self::$globalSchemaInfo[$namespace] is of type string, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1084
        }
1085
1086 47
        if ($node->hasAttribute('schemaLocation')) {
1087
            $base = urldecode($node->ownerDocument->documentURI);
1088
            $file = UrlUtils::resolveRelativeUrl($base, $node->getAttribute('schemaLocation'));
1089
1090 47
            if (isset($this->loadedFiles[$file])) {
1091
                $schema->addSchema($this->loadedFiles[$file]);
0 ignored issues
show
Documentation introduced by
$this->loadedFiles[$file] is of type object<GoetasWebservices...SDReader\Schema\Schema>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1092 47
                return function () {
1093
                };
1094 47
            }
1095 47
        }
1096
1097
        return $this->loadImportFresh($namespace, $schema, $file);
0 ignored issues
show
Bug introduced by
The variable $file does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1098 47
    }
1099 47
1100 47
    private function createOrUseSchemaForNs(
1101
        Schema $schema,
1102
        string $namespace
1103 47
    ): Schema {
1104
1105 47
        if (('' !== trim($namespace))) {
1106
            $newSchema = new Schema();
1107
            $newSchema->addSchema($this->getGlobalSchema());
0 ignored issues
show
Documentation introduced by
$this->getGlobalSchema() is of type object<GoetasWebservices...SDReader\Schema\Schema>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1108 1
            $schema->addSchema($newSchema);
0 ignored issues
show
Documentation introduced by
$newSchema is of type object<GoetasWebservices...SDReader\Schema\Schema>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1109
        } else {
1110
            $newSchema = $schema;
1111
        }
1112
1113
        return $newSchema;
1114
    }
1115
1116 1
    private function loadImportFresh(
1117 1
        string $namespace,
1118 1
        Schema $schema,
1119
        string $file
1120
    ): Closure {
1121 1
        return function () use ($namespace, $schema, $file) {
1122
1123
            $dom = $this->getDOM(
1124
            isset($this->knownLocationSchemas[$file])
1125
                ? $this->knownLocationSchemas[$file]
1126 1
                : $file
1127
            );
1128
1129
            $schemaNew = $this->createOrUseSchemaForNs($schema, $namespace);
1130
1131
            $this->setLoadedFile($file, $schemaNew);
1132 1
1133
            $callbacks = $this->schemaNode($schemaNew, $dom->documentElement, $schema);
1134
1135
            foreach ($callbacks as $callback) {
1136
                $callback();
1137
            }
1138
        };
1139
    }
1140 1
1141
    /**
1142 1
     * @var Schema|null
1143 1
     */
1144 1
    protected $globalSchema;
1145 1
1146 1
    /**
1147
     * @return Schema
1148 1
     */
1149 1
    private function getGlobalSchema(): Schema
1150
    {
1151 1
        if (!($this->globalSchema instanceof Schema)) {
1152 1
            $callbacks = array();
1153 1
            $globalSchemas = array();
1154
            /**
1155
             * @var string $namespace
1156
             */
1157
            foreach (self::$globalSchemaInfo as $namespace => $uri) {
1158
                $this->setLoadedFile(
1159
                    $uri,
1160
                    $globalSchemas[$namespace] = $schema = new Schema()
1161
                );
1162 1
                if ($namespace === self::XSD_NS) {
0 ignored issues
show
Unused Code Bug introduced by
The strict comparison === seems to always evaluate to false as the types of $namespace (integer) and self::XSD_NS (string) can never be identical. Maybe you want to use a loose comparison == instead?
Loading history...
1163
                    $this->globalSchema = $schema;
1164 1
                }
1165 1
                $xml = $this->getDOM($this->knownLocationSchemas[$uri]);
1166 1
                $callbacks = array_merge($callbacks, $this->schemaNode($schema, $xml->documentElement));
1167 1
            }
1168
1169
            $globalSchemas[(string) static::XSD_NS]->addType(new SimpleType($globalSchemas[(string) static::XSD_NS], 'anySimpleType'));
1170 1
            $globalSchemas[(string) static::XSD_NS]->addType(new SimpleType($globalSchemas[(string) static::XSD_NS], 'anyType'));
1171
1172 1
            $globalSchemas[(string) static::XML_NS]->addSchema(
1173
                $globalSchemas[(string) static::XSD_NS],
1174
                (string) static::XSD_NS
1175
            );
1176
            $globalSchemas[(string) static::XSD_NS]->addSchema(
1177
                $globalSchemas[(string) static::XML_NS],
1178
                (string) static::XML_NS
1179
            );
1180
1181
            /**
1182
             * @var Closure
1183 47
             */
1184
            foreach ($callbacks as $callback) {
1185 47
                $callback();
1186
            }
1187
        }
1188
1189
        /**
1190
         * @var Schema
1191 47
         */
1192
        $out = $this->globalSchema;
1193 47
1194 47
        if (!($out instanceof Schema)) {
1195 47
            throw new TypeException('Globa schema not discoverd');
1196
        }
1197
1198
        return $out;
1199 47
    }
1200 47
1201 47
    public function readNodes(array $nodes, string $file = null)
1202 47
    {
1203
        $rootSchema = new Schema();
1204 47
        $rootSchema->addSchema($this->getGlobalSchema());
0 ignored issues
show
Documentation introduced by
$this->getGlobalSchema() is of type object<GoetasWebservices...SDReader\Schema\Schema>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1205 47
1206
        $all = array();
1207 47
        foreach ($nodes as $k => $node) {
1208 47
            if (($node instanceof \DOMElement) && $node->namespaceURI === self::XSD_NS && $node->localName == 'schema') {
1209
1210
                $holderSchema = new Schema();
1211 47
                $holderSchema->addSchema($this->getGlobalSchema());
0 ignored issues
show
Documentation introduced by
$this->getGlobalSchema() is of type object<GoetasWebservices...SDReader\Schema\Schema>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1212 47
1213
                $this->setLoadedSchema($node, $holderSchema);
1214 47
1215 47
                $rootSchema->addSchema($holderSchema);
0 ignored issues
show
Documentation introduced by
$holderSchema is of type object<GoetasWebservices...SDReader\Schema\Schema>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1216 47
1217
                $callbacks = $this->schemaNode($holderSchema, $node);
1218 47
                $all = array_merge($callbacks, $all);
1219 47
            }
1220 47
        }
1221
1222
        if ($file) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $file of type null|string 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...
1223
            $this->setLoadedFile($file, $rootSchema);
1224
        }
1225
1226 47
        foreach ($all as $callback) {
1227 47
            call_user_func($callback);
1228
        }
1229
        return $rootSchema;
1230
    }
1231
1232
    public function readNode(DOMElement $node, string $file = null): Schema
1233
    {
1234 47
        $rootSchema = new Schema();
1235
        $rootSchema->addSchema($this->getGlobalSchema());
0 ignored issues
show
Documentation introduced by
$this->getGlobalSchema() is of type object<GoetasWebservices...SDReader\Schema\Schema>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1236 47
1237
        if ($file) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $file of type null|string 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...
1238
            $this->setLoadedFile($file, $rootSchema);
1239
        }
1240 47
1241
        $this->setLoadedSchema($node, $rootSchema);
1242
1243 47
1244
        $callbacks = $this->schemaNode($rootSchema, $node);
1245 47
1246 47
        foreach ($callbacks as $callback) {
1247
            call_user_func($callback);
1248 47
        }
1249 47
1250
        return $rootSchema;
1251 47
    }
1252 41
1253
    /**
1254
     * It is possible that a single file contains multiple <xsd:schema/> nodes, for instance in a WSDL file.
1255 47
     *
1256
     * Each of these  <xsd:schema/> nodes typically target a specific namespace. Append the target namespace to the
1257
     * file to distinguish between multiple schemas in a single file.
1258
     */
1259
    private function getNamespaceSpecificFileIndex(string $file, string $targetNamespace): string
1260
    {
1261
        return $file.'#'.$targetNamespace;
1262
    }
1263
1264 47
    /**
1265
     * @throws IOException
1266 47
     */
1267
    public function readString(string $content, string $file = 'schema.xsd'): Schema
1268
    {
1269
        $xml = new DOMDocument('1.0', 'UTF-8');
1270
        if (!$xml->loadXML($content)) {
1271
            throw new IOException("Can't load the schema");
1272 46
        }
1273
        $xml->documentURI = $file;
1274 46
1275 46
        return $this->readNode($xml->documentElement, $file);
1276
    }
1277
1278 46
    public function readFile(string $file): Schema
1279
    {
1280 46
        $xml = $this->getDOM($file);
1281
1282
        return $this->readNode($xml->documentElement, $file);
1283 1
    }
1284
1285 1
    /**
1286
     * @throws IOException
1287 1
     */
1288
    private function getDOM(string $file): DOMDocument
1289
    {
1290
        $xml = new DOMDocument('1.0', 'UTF-8');
1291
        if (!$xml->load($file)) {
1292
            throw new IOException("Can't load the file $file");
1293 47
        }
1294
1295 47
        return $xml;
1296 47
    }
1297
1298
    private static function againstDOMNodeList(
1299
        DOMElement $node,
1300 47
        Closure $againstNodeList
1301
    ) {
1302
        $limit = $node->childNodes->length;
1303 47
        for ($i = 0; $i < $limit; $i += 1) {
1304
            /**
1305
             * @var DOMNode
1306
             */
1307 47
            $childNode = $node->childNodes->item($i);
1308 47
1309
            if ($childNode instanceof DOMElement) {
1310
                $againstNodeList(
1311
                    $node,
1312 47
                    $childNode
1313
                );
1314 47
            }
1315 47
        }
1316 47
    }
1317 47
1318
    private function loadTypeWithCallback(
1319
        Schema $schema,
1320
        DOMElement $childNode,
1321 47
        Closure $callback
1322
    ) {
1323 47
        /**
1324
         * @var Closure|null $func
1325
         */
1326
        $func = null;
1327
1328
        switch ($childNode->localName) {
1329
            case 'complexType':
1330
                $func = $this->loadComplexType($schema, $childNode, $callback);
1331 47
                break;
1332
            case 'simpleType':
1333 47
                $func = $this->loadSimpleType($schema, $childNode, $callback);
1334 47
                break;
1335 47
        }
1336 47
1337 47
        if ($func instanceof Closure) {
1338 47
            call_user_func($func);
1339 47
        }
1340
    }
1341
1342 47
    private function loadElement(
1343 47
        Schema $schema,
1344
        DOMElement $node
1345 47
    ): Element {
1346
        $element = new Element($schema, $node->getAttribute('name'));
1347 47
        $element->setDoc($this->getDocumentation($node));
1348
1349
        $this->fillItem($element, $node);
1350
1351 47
        self::maybeSetMax($element, $node);
1352 47
        self::maybeSetMin($element, $node);
1353
1354 47
        $xp = new \DOMXPath($node->ownerDocument);
1355
        $xp->registerNamespace('xs', 'http://www.w3.org/2001/XMLSchema');
1356 47
1357 47
        if ($xp->query('ancestor::xs:choice', $node)->length) {
1358
            $element->setMin(0);
1359 47
        }
1360 47
1361
        if ($node->hasAttribute('nillable')) {
1362 47
            $element->setNil($node->getAttribute('nillable') == 'true');
1363 47
        }
1364
        if ($node->hasAttribute('form')) {
1365
            $element->setQualified($node->getAttribute('form') == 'qualified');
1366 47
        }
1367 3
1368
        return $element;
1369 47
    }
1370 3
1371
    private function addAttributeFromAttributeOrRef(
1372
        BaseComplexType $type,
1373 47
        DOMElement $childNode,
1374
        Schema $schema,
1375
        DOMElement $node
1376 47
    ): void {
1377
        $attribute = $this->getAttributeFromAttributeOrRef(
1378
            $childNode,
1379
            $schema,
1380
            $node
1381
        );
1382 47
1383 47
        $type->addAttribute($attribute);
1384 47
    }
1385 47
1386
    private function findSomethingLikeAttributeGroup(
1387
        Schema $schema,
1388 47
        DOMElement $node,
1389 47
        DOMElement $childNode,
1390
        AttributeContainer $addToThis
1391 47
    ): void {
1392
        $attribute = $this->findAttributeGroup($schema, $node, $childNode->getAttribute('ref'));
1393
        $addToThis->addAttribute($attribute);
1394
    }
1395
1396
    private function setLoadedFile(string $key, Schema $schema): void
1397 47
    {
1398 47
        $this->loadedFiles[$key] = $schema;
1399 47
    }
1400
1401 47
    private function setLoadedSchema(DOMNode $node, Schema $schema): void
1402
    {
1403 47
        if ($node->hasAttribute('targetNamespace')) {
0 ignored issues
show
Bug introduced by
The method hasAttribute() does not exist on DOMNode. Did you maybe mean hasAttributes()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
1404
            $this->loadedSchemas[$node->getAttribute('targetNamespace')][] = $schema;
1405 47
        }
1406
    }
1407
1408 47
    private function setSchemaThingsFromNode(
1409
        Schema $schema,
1410
        DOMElement $node,
1411
        Schema $parent = null
1412
    ): void {
1413 47
        $schema->setDoc($this->getDocumentation($node));
1414
1415 47
        if ($node->hasAttribute('targetNamespace')) {
1416 47
            $schema->setTargetNamespace($node->getAttribute('targetNamespace'));
1417
        } elseif ($parent instanceof Schema) {
1418
            $schema->setTargetNamespace($parent->getTargetNamespace());
1419
        }
1420 47
        $schema->setElementsQualification($node->getAttribute('elementFormDefault') == 'qualified');
1421 47
        $schema->setAttributesQualification($node->getAttribute('attributeFormDefault') == 'qualified');
1422 47
        $schema->setDoc($this->getDocumentation($node));
1423 47
    }
1424
}
1425