XmlValidator::__construct()   A
last analyzed

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 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
cc 1
nc 1
nop 0
crap 1
1
<?php
2
3
namespace Bmatovu\LaravelXml\Support;
4
5
use DOMDocument;
6
7
/**
8
 * Class XmlValidator.
9
 *
10
 * Validates XML against XSD
11
 *
12
 * @see ValidatingXML https://medium.com/@Sirolad/validating-xml-against-xsd-in-php-5607f725955a
13
 */
14
class XmlValidator
15
{
16
    /**
17
     * DOM Document.
18
     *
19
     * @var \DOMDocument
20
     */
21
    protected $domDocument = '';
22
23
    /**
24
     * XML Schema Definition.
25
     *
26
     * @var string
27
     */
28
    protected $xsd = '';
29
30
    /**
31
     * Constructor.
32
     */
33 4
    public function __construct()
34
    {
35 4
        $this->domDocument = new DOMDocument();
36
    }
37
38
    /**
39
     * Check if a string is valid XML.
40
     *
41
     * @see https://stackoverflow.com/a/31240779/2732184
42
     *
43
     * @param string $xmlStr
44
     * @param bool $ignoreHtml
45
     *
46
     * @return bool
47
     */
48 2
    public function is_valid($xmlStr, $ignoreHtml = true)
49
    {
50 2
        $xmlStr = trim($xmlStr);
51
52 2
        if ('' === $xmlStr) {
53 1
            return false;
54
        }
55
56 2
        if ($ignoreHtml && false !== stripos($xmlStr, '<!DOCTYPE html>')) {
57 1
            return false;
58
        }
59
60 2
        libxml_use_internal_errors(true);
61
62 2
        simplexml_load_string($xmlStr);
63
64 2
        $errors = libxml_get_errors();
65
66 2
        libxml_clear_errors();
67
68 2
        return empty($errors);
69
    }
70
71
    /**
72
     * Validate XML string.
73
     *
74
     * @see https://www.php.net/manual/en/class.simplexmlelement.php#107869
75
     *
76
     * @param string $xmlStr
77
     * @param string $xsdFilePath
78
     * @param int $flags
79
     * @param bool $checkXml
80
     *
81
     * @throws \Exception
82
     *
83
     * @return array
84
     */
85 3
    public function validate($xmlStr, $xsdFilePath, $flags = 0, $checkXml = false)
86
    {
87 3
        libxml_use_internal_errors(true);
88
89 3
        if ('' === $xmlStr || ($checkXml && ! $this->is_valid($xmlStr))) {
90 1
            throw new \Exception('Malformed XML.');
91
        }
92
93 2
        $this->domDocument->loadXML($xmlStr);
94
95 2
        $errors = [];
96 2
        if (! $this->domDocument->schemaValidate($xsdFilePath, $flags)) {
97 1
            foreach (libxml_get_errors() as $error) {
98 1
                $errors[$this->getElement($error->message)][] = $this->getMessage($error->message);
99
            }
100 1
            libxml_clear_errors();
101
        }
102
103 1
        return $errors;
104
    }
105
106
    /**
107
     * Get element from message.
108
     *
109
     * @param $message
110
     *
111
     * @return mixed
112
     */
113 1
    protected function getElement($message)
114
    {
115 1
        $matches = [];
116 1
        preg_match("/'([-_\\w]+)'/", $message, $matches);
117
118 1
        return array_pop($matches);
119
    }
120
121
    /**
122
     * Get refined message.
123
     *
124
     * @param $message
125
     *
126
     * @return string
127
     */
128 1
    protected function getMessage($message)
129
    {
130 1
        $parts = explode(':', $message);
131
132 1
        return trim(array_pop($parts));
133
    }
134
}
135