SchemaValidatableElementTrait   A
last analyzed

Complexity

Total Complexity 6

Size/Duplication

Total Lines 55
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 20
dl 0
loc 55
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
     *
36
     * @throws \SimpleSAML\XML\Exception\IOException
37
     * @throws \SimpleSAML\XMLSchema\Exception\SchemaViolationException
38
     */
39
    public static function schemaValidate(DOMDocument $document, ?string $schemaFile = null): DOMDocument
40
    {
41
        $internalErrors = libxml_use_internal_errors(true);
42
        libxml_clear_errors();
43
44
        if ($schemaFile === null) {
45
            $schemaFile = self::getSchemaFile();
46
        }
47
48
        // Must suppress the warnings here in order to throw them as an error below.
49
        $result = @$document->schemaValidate($schemaFile);
50
51
        if ($result === false) {
52
            $msgs = [];
53
            foreach (libxml_get_errors() as $err) {
54
                $msgs[] = trim($err->message) . ' on line ' . $err->line;
55
            }
56
57
            throw new SchemaViolationException(sprintf(
58
                "XML schema validation errors:\n - %s",
59
                implode("\n - ", array_unique($msgs)),
60
            ));
61
        }
62
63
        libxml_use_internal_errors($internalErrors);
64
        libxml_clear_errors();
65
66
        return $document;
67
    }
68
69
70
    /**
71
     * Get the schema file that can validate this element.
72
     * The path must be relative to the project's base directory.
73
     */
74
    public static function getSchemaFile(): string
75
    {
76
        if (!defined('static::SCHEMA')) {
77
            throw new RuntimeException('A SCHEMA-constant was not set on this class.');
78
        }
79
        $schemaFile = static::SCHEMA;
80
81
        Assert::true(file_exists($schemaFile), sprintf("File not found: %s", $schemaFile), IOException::class);
82
        return $schemaFile;
83
    }
84
}
85