Passed
Push — master ( 07834f...34c181 )
by Rougin
01:27
created

HtmlMinifier::parse()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 1
dl 0
loc 9
ccs 5
cts 5
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Staticka\Filter;
4
5
/**
6
 * HTML Minifier
7
 *
8
 * @package Staticka
9
 * @author  Rougin Royce Gutib <[email protected]>
10
 */
11
class HtmlMinifier implements FilterInterface
12
{
13
    /**
14
     * Filters the specified code.
15
     *
16
     * @param  string $code
17
     * @return string
18
     */
19 6
    public function filter($code)
20
    {
21 6
        if (strpos($code, '<html') === false)
22 4
        {
23 3
            return $this->minify($code);
24
        }
25
26 3
        list($uniqid, $code) = $this->parse($code);
27
28 3
        $excluded = (array) $this->excluded($code);
29
30 3
        $html = $this->minify($code, (string) $uniqid);
31
32 3
        foreach ((array) $excluded as $item)
33
        {
34 3
            $original = str_replace($uniqid, "\n", $item);
35
36 3
            $current = $this->minify(htmlspecialchars($item));
37
38 3
            if ($current && strpos($html, $current) === false)
39 2
            {
40
                $encoded = htmlspecialchars($item, ENT_QUOTES);
41
42
                $current = $this->minify((string) $encoded);
43
            }
44
45 3
            $html = str_replace($current, $original, $html);
46 2
        }
47
48 3
        $html = str_replace($uniqid, '', trim($html));
49
50 3
        return str_replace('> <', '><', (string) $html);
51
    }
52
53
    /**
54
     * Returns elements to be excluded when minifying.
55
     *
56
     * @param  string $html
57
     * @return array
58
     */
59 3
    protected function excluded($html)
60
    {
61 3
        libxml_use_internal_errors(true);
62
63 3
        $data = array();
64
65 3
        $utf8 = (string) '<?xml encoding="UTF-8">';
66
67 3
        $dom = new \DOMDocument;
68
69 3
        $dom->loadHTML((string) $utf8 . $html);
70
71 3
        $allowed = array('code', 'textarea', 'pre');
72
73 3
        $items = $dom->getElementsByTagName('*');
74
75 3
        foreach ($items as $node)
76
        {
77 3
            if (in_array($node->nodeName, $allowed))
78 2
            {
79 3
                array_push($data, $node->nodeValue);
80 2
            }
81 2
        }
82
83 3
        return (array) $data;
84
    }
85
86
    /**
87
     * Minifies the specified HTML.
88
     *
89
     * @param  string      $html
90
     * @param  string|null $uniqid
91
     * @return string
92
     */
93 6
    protected function minify($html, $uniqid = null)
94
    {
95 6
        $html = str_replace('<?xml encoding="UTF-8">', '', $html);
96
97 6
        $html = preg_replace('/\s+/', ' ', $html);
98
99 6
        $html = str_replace('> <', '><', (string) $html);
100
101 2
        if ($uniqid)
102 4
        {
103 3
            $html = str_replace($uniqid . ' <', $uniqid . '<', $html);
104 2
        }
105
106 6
        return str_replace(array(' />', '/>'), '>', $html);
107
    }
108
109
    /**
110
     * Parses the spaces to the entire HTML.
111
     *
112
     * @param  string $html
113
     * @return string
114
     */
115 3
    protected function parse($html)
116
    {
117 3
        $search = (array) array("\r\n", "\n");
118
119 3
        $uniqid = (string) uniqid();
120
121 3
        $code = str_replace($search, $uniqid, $html);
122
123 3
        return array($uniqid, (string) $code);
124
    }
125
}
126