Issues (26)

src/snippet/SnippetLoader.php (2 issues)

1
<?php declare(strict_types = 1);
2
namespace Templado\Engine;
3
4
use DOMDocument;
5
6
class SnippetLoader {
7 33
    public function load(FileName $fileName): Snippet {
8 33
        $this->ensureFileExists($fileName);
9 30
        $this->ensureIsReadableFile($fileName);
10
11 24
        $mimeType = $fileName->getMimeType();
12
13 24
        switch ($mimeType) {
14 24
            case 'text/x-php':
15 21
            case 'text/plain':
16 6
                return $this->loadAsText($fileName);
17
18 18
            case 'application/xml':
19 18
            case 'text/xml':
20 3
            case 'text/html':
21 15
                return $this->loadAsSnippet($fileName);
22
        }
23
24 3
        throw new SnippetLoaderException(
25 3
            \sprintf('Unsupported mime-type "%s"', $mimeType)
26
        );
27
    }
28
29 6
    private function loadAsText(FileName $fileName): TextSnippet {
30 6
        return new TextSnippet(
31 6
            $fileName->getName(),
32 6
            (new DOMDocument())->createTextNode(\file_get_contents($fileName->asString()))
33
        );
34
    }
35
36
    /**
37
     * @throws SnippetLoaderException
38
     */
39 15
    private function loadAsSnippet(FileName $fileName): Snippet {
40 15
        $dom = $this->loadFile($fileName);
41
42 12
        if ($this->isTempladoSnippetDocument($dom)) {
43 3
            return $this->parseAsTempladoSnippet($dom);
44
        }
45
46 9
        if ($this->isHtmlDocument($dom)) {
47 6
            return $this->parseAsHTML($dom);
48
        }
49
50 3
        throw new SnippetLoaderException('Document does not seem to be a valid HtmlSnippet or (X)HTML file.');
51
    }
52
53
    /**
54
     * @throws SnippetLoaderException
55
     */
56 15
    private function loadFile(FileName $fileName): DOMDocument {
57 15
        \libxml_use_internal_errors(true);
58 15
        \libxml_clear_errors();
59 15
        $dom                     = new DOMDocument();
60 15
        $dom->preserveWhiteSpace = false;
61 15
        $tmp                     = $dom->load($fileName->asString());
62
63 15
        if (!$tmp || \libxml_get_last_error()) {
64 3
            $error = \libxml_get_errors()[0];
65
66 3
            throw new SnippetLoaderException(
67 3
                \sprintf(
68 3
                    "Loading file '%s' failed: %s (line %d)",
69 3
                    $fileName->asString(),
70 3
                    \trim($error->message),
71 3
                    $error->line
72
                )
73
            );
74
        }
75
76 12
        return $dom;
77
    }
78
79 12
    private function isTempladoSnippetDocument(DOMDocument $dom): bool {
80 12
        $root = $dom->documentElement;
81
82
        return (
83 12
            $root->namespaceURI === 'https://templado.io/snippets/1.0' &&
84 12
            $root->localName === 'snippet' &&
85 12
            $root->hasChildNodes()
86
        );
87
    }
88
89 9
    private function isHtmlDocument(DOMDocument $dom): bool {
90 9
        $root = $dom->documentElement;
91
92
        return (
93 9
            $root->namespaceURI === 'http://www.w3.org/1999/xhtml' ||
94 9
            (string)$root->namespaceURI === ''
95
        );
96
    }
97
98
    /**
99
     * @throws SnippetLoaderException
100
     */
101 33
    private function ensureFileExists(FileName $fileName): void {
102 33
        if (!$fileName->exists()) {
103 3
            throw new SnippetLoaderException(
104 3
                \sprintf('File "%s" not found.', $fileName->asString())
105
            );
106
        }
107 30
    }
108
109
    /**
110
     * @throws SnippetLoaderException
111
     */
112 30
    private function ensureIsReadableFile(FileName $fileName): void {
113 30
        if (!$fileName->isFile()) {
114 3
            throw new SnippetLoaderException(
115 3
                \sprintf('File "%s" not a file.', $fileName->asString())
116
            );
117
        }
118
119 27
        if (!$fileName->isReadable()) {
120 3
            throw new SnippetLoaderException(
121 3
                \sprintf('File "%s" can not be read.', $fileName->asString())
122
            );
123
        }
124 24
    }
125
126 3
    private function parseAsTempladoSnippet(DOMDocument $dom): TempladoSnippet {
127 3
        return new TempladoSnippet($dom->documentElement->getAttribute('id'), $dom);
128
    }
129
130 6
    private function parseAsHTML(DOMDocument $dom): SimpleSnippet {
131 6
        $id = $dom->documentElement->getAttribute('id');
132
133 6
        if ($id === '') {
134 3
            $id = \pathinfo($dom->documentURI, \PATHINFO_FILENAME);
0 ignored issues
show
It seems like $dom->documentURI can also be of type null; however, parameter $path of pathinfo() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

134
            $id = \pathinfo(/** @scrutinizer ignore-type */ $dom->documentURI, \PATHINFO_FILENAME);
Loading history...
135
        }
136
137 6
        return new SimpleSnippet($id, $dom->documentElement);
0 ignored issues
show
It seems like $id can also be of type array; however, parameter $targetId of Templado\Engine\SimpleSnippet::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

137
        return new SimpleSnippet(/** @scrutinizer ignore-type */ $id, $dom->documentElement);
Loading history...
138
    }
139
}
140