SchemaValidatableElementTrait::schemaValidate()   A
last analyzed

Complexity

Conditions 4
Paths 6

Size

Total Lines 28
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 15
c 3
b 0
f 0
dl 0
loc 28
rs 9.7666
cc 4
nc 6
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\XML;
6
7
use DOMDocument;
8
use SimpleSAML\Assert\Assert;
9
use SimpleSAML\XML\Exception\{IOException, SchemaViolationException};
10
11
use function array_unique;
12
use function defined;
13
use function file_exists;
14
use function implode;
15
use function libxml_clear_errors;
16
use function libxml_get_errors;
17
use function libxml_use_internal_errors;
18
use function sprintf;
19
use function trim;
20
21
/**
22
 * trait class to be used by all the classes that implement the SchemaValidatableElementInterface
23
 *
24
 * @package simplesamlphp/xml-common
25
 */
26
trait SchemaValidatableElementTrait
27
{
28
    /**
29
     * Validate the given DOMDocument against the schema set for this element
30
     *
31
     * @param \DOMDocument $document
32
     * @param string|null $schemaFile
33
     * @return \DOMDocument
34
     *
35
     * @throws \SimpleSAML\XML\Exception\IOException
36
     * @throws \SimpleSAML\XML\Exception\SchemaViolationException
37
     */
38
    public static function schemaValidate(DOMDocument $document, ?string $schemaFile = null): DOMDocument
39
    {
40
        $internalErrors = libxml_use_internal_errors(true);
41
        libxml_clear_errors();
42
43
        if ($schemaFile === null) {
44
            $schemaFile = self::getSchemaFile();
45
        }
46
47
        // Must suppress the warnings here in order to throw them as an error below.
48
        $result = @$document->schemaValidate($schemaFile);
49
50
        if ($result === false) {
51
            $msgs = [];
52
            foreach (libxml_get_errors() as $err) {
53
                $msgs[] = trim($err->message) . ' on line ' . $err->line;
54
            }
55
56
            throw new SchemaViolationException(sprintf(
57
                "XML schema validation errors:\n - %s",
58
                implode("\n - ", array_unique($msgs)),
59
            ));
60
        }
61
62
        libxml_use_internal_errors($internalErrors);
63
        libxml_clear_errors();
64
65
        return $document;
66
    }
67
68
69
    /**
70
     * Get the schema file that can validate this element.
71
     * The path must be relative to the project's base directory.
72
     *
73
     * @return string
74
     */
75
    public static function getSchemaFile(): string
76
    {
77
        if (defined('static::SCHEMA')) {
78
            $schemaFile = static::SCHEMA;
1 ignored issue
show
Bug introduced by
The constant SimpleSAML\XML\SchemaVal...bleElementTrait::SCHEMA was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
79
        }
80
81
        Assert::true(file_exists($schemaFile), sprintf("File not found: %s", $schemaFile), IOException::class);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $schemaFile does not seem to be defined for all execution paths leading up to this point.
Loading history...
82
        return $schemaFile;
83
    }
84
}
85