SchemaValidatableElementTrait   A
last analyzed

Complexity

Total Complexity 6

Size/Duplication

Total Lines 58
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 20
dl 0
loc 58
rs 10
c 0
b 0
f 0
wmc 6

2 Methods

Rating   Name   Duplication   Size   Complexity  
A schemaValidate() 0 28 4
A getSchemaFile() 0 9 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\XML;
6
7
use DOMDocument;
8
use SimpleSAML\XML\Assert\Assert;
9
use SimpleSAML\XML\Exception\IOException;
10
use SimpleSAML\XML\Exception\RuntimeException;
11
use SimpleSAML\XMLSchema\Exception\SchemaViolationException;
12
13
use function array_unique;
14
use function defined;
15
use function file_exists;
16
use function implode;
17
use function libxml_clear_errors;
18
use function libxml_get_errors;
19
use function libxml_use_internal_errors;
20
use function sprintf;
21
use function trim;
22
23
/**
24
 * trait class to be used by all the classes that implement the SchemaValidatableElementInterface
25
 *
26
 * @package simplesamlphp/xml-common
27
 */
28
trait SchemaValidatableElementTrait
29
{
30
    /**
31
     * Validate the given DOMDocument against the schema set for this element
32
     *
33
     * @param \DOMDocument $document
34
     * @param string|null $schemaFile
35
     * @return \DOMDocument
36
     *
37
     * @throws \SimpleSAML\XML\Exception\IOException
38
     * @throws \SimpleSAML\XMLSchema\Exception\SchemaViolationException
39
     */
40
    public static function schemaValidate(DOMDocument $document, ?string $schemaFile = null): DOMDocument
41
    {
42
        $internalErrors = libxml_use_internal_errors(true);
43
        libxml_clear_errors();
44
45
        if ($schemaFile === null) {
46
            $schemaFile = self::getSchemaFile();
47
        }
48
49
        // Must suppress the warnings here in order to throw them as an error below.
50
        $result = @$document->schemaValidate($schemaFile);
51
52
        if ($result === false) {
53
            $msgs = [];
54
            foreach (libxml_get_errors() as $err) {
55
                $msgs[] = trim($err->message) . ' on line ' . $err->line;
56
            }
57
58
            throw new SchemaViolationException(sprintf(
59
                "XML schema validation errors:\n - %s",
60
                implode("\n - ", array_unique($msgs)),
61
            ));
62
        }
63
64
        libxml_use_internal_errors($internalErrors);
65
        libxml_clear_errors();
66
67
        return $document;
68
    }
69
70
71
    /**
72
     * Get the schema file that can validate this element.
73
     * The path must be relative to the project's base directory.
74
     *
75
     * @return string
76
     */
77
    public static function getSchemaFile(): string
78
    {
79
        if (!defined('static::SCHEMA')) {
80
            throw new RuntimeException('A SCHEMA-constant was not set on this class.');
81
        }
82
        $schemaFile = static::SCHEMA;
83
84
        Assert::true(file_exists($schemaFile), sprintf("File not found: %s", $schemaFile), IOException::class);
85
        return $schemaFile;
86
    }
87
}
88