Passed
Push — static-analysis ( 1958c5...5a8282 )
by SignpostMarv
10:41 queued 08:16
created

Schema::getSchemas()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 1
nc 1
nop 0
crap 1
1
<?php
2
3
namespace GoetasWebservices\XML\XSDReader\Schema;
4
5
use DOMElement;
6
use RuntimeException;
7
use GoetasWebservices\XML\XSDReader\SchemaReader;
8
use GoetasWebservices\XML\XSDReader\Schema\Type\Type;
9
use GoetasWebservices\XML\XSDReader\Schema\Attribute\Group as AttributeGroup;
10
use GoetasWebservices\XML\XSDReader\Schema\Element\Group;
11
use GoetasWebservices\XML\XSDReader\Schema\Element\ElementDef;
12
use GoetasWebservices\XML\XSDReader\Schema\Element\ElementItem;
13
use GoetasWebservices\XML\XSDReader\Schema\Exception\TypeNotFoundException;
14
use GoetasWebservices\XML\XSDReader\Schema\Exception\SchemaException;
15
use GoetasWebservices\XML\XSDReader\Schema\Attribute\AttributeItem;
16
use GoetasWebservices\XML\XSDReader\Schema\Attribute\AttributeDef;
17
18
class Schema
19
{
20
    /**
21
     * @param string $getter
22
     * @param string $name
23
     * @param string $namespace
24
     * @param bool[] $calling
25
     * @param bool   $throw
26
     *
27
     * @return SchemaItem|null
28
     */
29 45
    protected function findSomethingNoThrow(
30
        $getter,
31
        $name,
32
        $namespace = null,
33
        array &$calling = array()
34
    ) {
35 45
        $calling[spl_object_hash($this)] = true;
36 45
        $cid = "$getter, $name, $namespace";
37
38 45
        if (isset($this->typeCache[$cid])) {
39 45
            return $this->typeCache[$cid];
40
        } elseif (
41 45
            $this->getTargetNamespace() === $namespace
42 45
        ) {
43
            /**
44
             * @var SchemaItem|null
45
             */
46 45
            $item = $this->$getter($name);
47
48 45
            if ($item instanceof SchemaItem) {
49 45
                return $this->typeCache[$cid] = $item;
50
            }
51
        }
52
53 45
        return $this->findSomethingNoThrowSchemas(
54 45
            $this->getSchemas(),
55 45
            $cid,
56 45
            $getter,
57 45
            $name,
58 45
            $namespace,
59
            $calling
60 45
        );
61
    }
62
63
    /**
64
     * @param Schema[] $schemas
65
     * @param string   $cid
66
     * @param string   $getter
67
     * @param string   $name
68
     * @param string   $namespace
69
     * @param bool[]   $calling
70
     * @param bool     $throw
71
     *
72
     * @return SchemaItem|null
73
     */
74 45
    protected function findSomethingNoThrowSchemas(
75
        array $schemas,
76
        $cid,
77
        $getter,
78
        $name,
79
        $namespace = null,
80
        array &$calling = array()
81
    ) {
82 45
        foreach ($schemas as $childSchema) {
83 45
            if (!isset($calling[spl_object_hash($childSchema)])) {
84
                /**
85
                 * @var SchemaItem|null
86
                 */
87 45
                $in = $childSchema->findSomethingNoThrow($getter, $name, $namespace, $calling);
88
89 45
                if ($in instanceof SchemaItem) {
90 45
                    return $this->typeCache[$cid] = $in;
91
                }
92 7
            }
93 7
        }
94 7
    }
95
96
    /**
97
     * @param string $getter
98
     * @param string $name
99
     * @param string $namespace
100
     * @param bool[] $calling
101
     * @param bool   $throw
102
     *
103
     * @throws TypeNotFoundException
104
     *
105
     * @return SchemaItem
106
     */
107 45
    protected function findSomething($getter, $name, $namespace = null, &$calling = array())
108
    {
109 45
        $in = $this->findSomethingNoThrow(
110 45
            $getter,
111 45
            $name,
112 45
            $namespace,
113
            $calling
114 45
        );
115
116 45
        if ($in instanceof SchemaItem) {
117 45
            return $in;
118
        }
119
120 5
        throw new TypeNotFoundException(sprintf("Can't find the %s named {%s}#%s.", substr($getter, 3), $namespace, $name));
121
    }
122
123
    /**
124
     * @var bool
125
     */
126
    protected $elementsQualification = false;
127
128
    /**
129
     * @var bool
130
     */
131
    protected $attributesQualification = false;
132
133
    /**
134
     * @var string|null
135
     */
136
    protected $targetNamespace;
137
138
    /**
139
     * @var Schema[]
140
     */
141
    protected $schemas = array();
142
143
    /**
144
     * @var Type[]
145
     */
146
    protected $types = array();
147
148
    /**
149
     * @var ElementDef[]
150
     */
151
    protected $elements = array();
152
153
    /**
154
     * @var Group[]
155
     */
156
    protected $groups = array();
157
158
    /**
159
     * @var AttributeGroup[]
160
     */
161
    protected $attributeGroups = array();
162
163
    /**
164
     * @var AttributeDef[]
165
     */
166
    protected $attributes = array();
167
168
    /**
169
     * @var string|null
170
     */
171
    protected $doc;
172
173
    /**
174
     * @var \GoetasWebservices\XML\XSDReader\Schema\SchemaItem[]
175
     */
176
    protected $typeCache = array();
177
178
    /**
179
     * @return bool
180
     */
181
    public function getElementsQualification()
182
    {
183
        return $this->elementsQualification;
184
    }
185
186
    /**
187
     * @param bool $elementsQualification
188
     */
189 45
    public function setElementsQualification($elementsQualification)
190
    {
191 45
        $this->elementsQualification = $elementsQualification;
192 45
    }
193
194
    /**
195
     * @return bool
196
     */
197
    public function getAttributesQualification()
198
    {
199
        return $this->attributesQualification;
200
    }
201
202
    /**
203
     * @param bool $attributesQualification
204
     */
205 45
    public function setAttributesQualification($attributesQualification)
206
    {
207 45
        $this->attributesQualification = $attributesQualification;
208 45
    }
209
210
    /**
211
     * @return string|null
212
     */
213 45
    public function getTargetNamespace()
214
    {
215 45
        return $this->targetNamespace;
216
    }
217
218
    /**
219
     * @param string|null $targetNamespace
220
     */
221 45
    public function setTargetNamespace($targetNamespace)
222
    {
223 45
        $this->targetNamespace = $targetNamespace;
224 45
    }
225
226
    /**
227
     * @return Type[]
228
     */
229 5
    public function getTypes()
230
    {
231 5
        return $this->types;
232
    }
233
234
    /**
235
     * @return ElementDef[]
236
     */
237 3
    public function getElements()
238
    {
239 3
        return $this->elements;
240
    }
241
242
    /**
243
     * @return Schema[]
244
     */
245 45
    public function getSchemas()
246
    {
247 45
        return $this->schemas;
248
    }
249
250
    /**
251
     * @return AttributeDef[]
252
     */
253 1
    public function getAttributes()
254
    {
255 1
        return $this->attributes;
256
    }
257
258
    /**
259
     * @return Group[]
260
     */
261 2
    public function getGroups()
262
    {
263 2
        return $this->groups;
264
    }
265
266
    /**
267
     * @return string|null
268
     */
269
    public function getDoc()
270
    {
271
        return $this->doc;
272
    }
273
274
    /**
275
     * @param string $doc
276
     */
277 45
    public function setDoc($doc)
278
    {
279 45
        $this->doc = $doc;
280 45
    }
281
282 45
    public function addType(Type $type)
283
    {
284 45
        $this->types[$type->getName()] = $type;
285 45
    }
286
287 45
    public function addElement(ElementDef $element)
288
    {
289 45
        $this->elements[$element->getName()] = $element;
290 45
    }
291
292
    /**
293
     * @param string|null $namespace
294
     */
295 45
    public function addSchema(Schema $schema, $namespace = null)
296
    {
297 45
        if ($namespace !== null) {
298 45
            if ($schema->getTargetNamespace() !== $namespace) {
299
                throw new SchemaException(
300
                    sprintf(
301
                        "The target namespace ('%s') for schema, does not match the declared namespace '%s'",
302
                        $schema->getTargetNamespace(),
303
                        $namespace
304
                    )
305
                );
306
            }
307 45
            $this->schemas[$namespace] = $schema;
308 45
        } else {
309 45
            $this->schemas[] = $schema;
310
        }
311 45
    }
312
313 45
    public function addAttribute(AttributeDef $attribute)
314
    {
315 45
        $this->attributes[$attribute->getName()] = $attribute;
316 45
    }
317
318 45
    public function addGroup(Group $group)
319
    {
320 45
        $this->groups[$group->getName()] = $group;
321 45
    }
322
323 45
    public function addAttributeGroup(AttributeGroup $group)
324
    {
325 45
        $this->attributeGroups[$group->getName()] = $group;
326 45
    }
327
328
    /**
329
     * @return AttributeGroup[]
330
     */
331 1
    public function getAttributeGroups()
332
    {
333 1
        return $this->attributeGroups;
334
    }
335
336
    /**
337
     * @param string $name
338
     *
339
     * @return Group|false
340
     */
341 45
    public function getGroup($name)
342
    {
343 45
        if (isset($this->groups[$name])) {
344 45
            return $this->groups[$name];
345
        }
346
347
        return false;
348
    }
349
350
    /**
351
     * @param string $name
352
     *
353
     * @return ElementItem|false
354
     */
355 45
    public function getElement($name)
356
    {
357 45
        if (isset($this->elements[$name])) {
358 45
            return $this->elements[$name];
359
        }
360
361
        return false;
362
    }
363
364
    /**
365
     * @param string $name
366
     *
367
     * @return Type|false
368
     */
369 45
    public function getType($name)
370
    {
371 45
        if (isset($this->types[$name])) {
372 45
            return $this->types[$name];
373
        }
374
375
        return false;
376
    }
377
378
    /**
379
     * @param string $name
380
     *
381
     * @return AttributeItem|false
382
     */
383 45
    public function getAttribute($name)
384
    {
385 45
        if (isset($this->attributes[$name])) {
386 45
            return $this->attributes[$name];
387
        }
388
389
        return false;
390
    }
391
392
    /**
393
     * @param string $name
394
     *
395
     * @return AttributeGroup|false
396
     */
397 45
    public function getAttributeGroup($name)
398
    {
399 45
        if (isset($this->attributeGroups[$name])) {
400 45
            return $this->attributeGroups[$name];
401
        }
402
403
        return false;
404
    }
405
406
    public function __toString()
407
    {
408
        return sprintf('Target namespace %s', $this->getTargetNamespace());
409
    }
410
411
    /**
412
     * @param string $name
413
     * @param string $namespace
414
     *
415
     * @return Type
416
     */
417 45
    public function findType($name, $namespace = null)
418
    {
419
        /**
420
         * @var Type
421
         */
422 45
        $out = $this->findSomething('getType', $name, $namespace);
423
424 45
        return $out;
425
    }
426
427
    /**
428
     * @param string $name
429
     * @param string $namespace
430
     *
431
     * @return Group
432
     */
433 45
    public function findGroup($name, $namespace = null)
434
    {
435
        /**
436
         * @var Group
437
         */
438 45
        $out = $this->findSomething('getGroup', $name, $namespace);
439
440 45
        return $out;
441
    }
442
443
    /**
444
     * @param string $name
445
     * @param string $namespace
446
     *
447
     * @return ElementDef
448
     */
449 45
    public function findElement($name, $namespace = null)
450
    {
451
        /**
452
         * @var ElementDef
453
         */
454 45
        $out = $this->findSomething('getElement', $name, $namespace);
455
456 45
        return $out;
457
    }
458
459
    /**
460
     * @param string $name
461
     * @param string $namespace
462
     *
463
     * @return AttributeItem
464
     */
465 45
    public function findAttribute($name, $namespace = null)
466
    {
467
        /**
468
         * @var AttributeItem
469
         */
470 45
        $out = $this->findSomething('getAttribute', $name, $namespace);
471
472 45
        return $out;
473
    }
474
475
    /**
476
     * @param string $name
477
     * @param string $namespace
478
     *
479
     * @return AttributeGroup
480
     */
481 45
    public function findAttributeGroup($name, $namespace = null)
482
    {
483
        /**
484
         * @var AttributeGroup
485
         */
486 45
        $out = $this->findSomething('getAttributeGroup', $name, $namespace);
487
488 45
        return $out;
489
    }
490
491
    /**
492
     * @var Schema[]
493
     */
494
    protected static $loadedFiles = array();
495
496
    /**
497
     * @param string ...$keys
498
     *
499
     * @return bool
500
     */
501 45
    public static function hasLoadedFile(...$keys)
502
    {
503 45
        foreach ($keys as $key) {
504 45
            if (isset(self::$loadedFiles[$key])) {
505 45
                return true;
506
            }
507 1
        }
508
509 1
        return false;
510
    }
511
512
    /**
513
     * @param string ...$keys
514
     *
515
     * @return Schema
516
     *
517
     * @throws RuntimeException if loaded file not found
518
     */
519 45
    public static function getLoadedFile(...$keys)
520
    {
521 45
        foreach ($keys as $key) {
522 45
            if (isset(self::$loadedFiles[$key])) {
523 45
                return self::$loadedFiles[$key];
524
            }
525
        }
526
527
        throw new RuntimeException('Loaded file was not found!');
528
    }
529
530
    /**
531
     * @param string $key
532
     *
533
     * @return Schema
534
     */
535 45
    public static function setLoadedFile($key, Schema $schema)
536
    {
537 45
        self::$loadedFiles[$key] = $schema;
538
539 45
        return $schema;
540
    }
541
542 45
    public function setSchemaThingsFromNode(
543
        DOMElement $node,
544
        Schema $parent = null
545
    ) {
546 45
        $this->setDoc(SchemaReader::getDocumentation($node));
547
548 45
        if ($node->hasAttribute('targetNamespace')) {
549 45
            $this->setTargetNamespace($node->getAttribute('targetNamespace'));
550 45
        } elseif ($parent) {
551
            $this->setTargetNamespace($parent->getTargetNamespace());
552
        }
553 45
        $this->setElementsQualification($node->getAttribute('elementFormDefault') == 'qualified');
554 45
        $this->setAttributesQualification($node->getAttribute('attributeFormDefault') == 'qualified');
555 45
        $this->setDoc(SchemaReader::getDocumentation($node));
556 45
    }
557
}
558