Completed
Push — master ( bf8145...92c5ca )
by Gerben
02:22
created

Validator::parseErrors()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 8
ccs 6
cts 6
cp 1
rs 10
c 0
b 0
f 0
cc 3
nc 3
nop 1
crap 3
1
<?php declare(strict_types=1);
2
3
namespace Hyperized\Xml;
4
5
use DOMDocument;
6
use Hyperized\Xml\Constants\ErrorMessages;
7
use Hyperized\Xml\Constants\Strings;
8
use Hyperized\Xml\Exceptions\FileCouldNotBeOpenedException;
9
use Hyperized\Xml\Exceptions\InvalidXml;
10
11
/**
12
 * Class Validator
13
 *
14
 * @package Hyperized\Xml
15
 * Based on: http://stackoverflow.com/a/30058598/1757763
16
 */
17
final class Validator implements ValidatorInterface
18
{
19
    /**
20
     * @var string
21
     */
22
    private $version = Strings::VERSION;
23
    /**
24
     * @var string
25
     */
26
    private $encoding = Strings::UTF_8;
27
28
    /**
29
     * @param  string      $xmlPath
30
     * @param  string|null $xsdPath
31
     * @return bool
32
     * @throws FileCouldNotBeOpenedException
33
     * @throws InvalidXml
34
     */
35 10
    public function isXMLFileValid(string $xmlPath, string $xsdPath = null): bool
36
    {
37 10
        return $this->isXMLStringValid(self::getFileContent($xmlPath), $xsdPath);
38
    }
39
40
    /**
41
     * @param  string      $xml
42
     * @param  string|null $xsdPath
43
     * @return bool
44
     * @throws InvalidXml
45
     */
46 14
    public function isXMLStringValid(string $xml, string $xsdPath = null): bool
47
    {
48 14
        if (\is_string($xsdPath)) {
49 4
            return $this->isXMLValid($xml, $xsdPath);
50
        }
51 10
        return $this->isXMLValid($xml);
52
    }
53
54
    /**
55
     * @param  string      $xmlContent
56
     * @param  string|null $xsdPath
57
     * @return bool
58
     * @throws InvalidXml
59
     */
60 14
    private function isXMLValid(string $xmlContent, string $xsdPath = null): bool
61
    {
62 14
        self::checkEmptyWhenTrimmed($xmlContent);
63
64 12
        libxml_use_internal_errors(true);
65
66 12
        $document = new DOMDocument($this->version, $this->encoding);
67 12
        $document->loadXML($xmlContent);
68 12
        if (isset($xsdPath)) {
69 4
            $document->schemaValidate($xsdPath);
70
        }
71
72 12
        $errors = libxml_get_errors();
73 12
        libxml_clear_errors();
74 12
        self::parseErrors($errors);
75 6
        return true;
76
    }
77
78
    /**
79
     * @param  string $xmlContent
80
     * @throws InvalidXml
81
     */
82 14
    private static function checkEmptyWhenTrimmed(string $xmlContent): void
83
    {
84 14
        if (trim($xmlContent) === '') {
85 2
            throw new InvalidXml(ErrorMessages::XML_EMPTY_TRIMMED);
86
        }
87 12
    }
88
89
    /**
90
     * @param  array $errors
91
     * @throws InvalidXml
92
     */
93 12
    private static function parseErrors(array $errors): void
94
    {
95 12
        if (!empty($errors)) {
96 6
            $return = [];
97 6
            foreach ($errors as $error) {
98 6
                $return[] = trim($error->message);
99
            }
100 6
            throw new InvalidXml(implode(Strings::NEW_LINE, $return));
101
        }
102 6
    }
103
104
    /**
105
     * @param  string $fileName
106
     * @return string
107
     * @throws FileCouldNotBeOpenedException
108
     */
109 10
    private static function getFileContent(string $fileName): string
110
    {
111
        try {
112 10
            $contents = file_get_contents($fileName);
113 2
        } catch (\Exception $exception) {
114 2
            throw new FileCouldNotBeOpenedException(ErrorMessages::NO_FILE_CONTENTS);
115
        }
116 8
        if (!\is_string($contents)) {
0 ignored issues
show
introduced by
The condition is_string($contents) is always true.
Loading history...
117
            throw new FileCouldNotBeOpenedException(ErrorMessages::NO_FILE_CONTENTS);
118
        }
119 8
        return $contents;
120
    }
121
122
    /**
123
     * @return string
124
     */
125 2
    public function getVersion(): string
126
    {
127 2
        return $this->version;
128
    }
129
130
    /**
131
     * @param string $version
132
     */
133 2
    public function setVersion(string $version): void
134
    {
135 2
        $this->version = $version;
136 2
    }
137
138
    /**
139
     * @return string
140
     */
141 2
    public function getEncoding(): string
142
    {
143 2
        return $this->encoding;
144
    }
145
146
    /**
147
     * @param string $encoding
148
     */
149 2
    public function setEncoding(string $encoding): void
150
    {
151 2
        $this->encoding = $encoding;
152 2
    }
153
}
154