HtmlMinifier   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 122
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 34
c 1
b 0
f 0
dl 0
loc 122
ccs 48
cts 48
cp 1
rs 10
wmc 13

5 Methods

Rating   Name   Duplication   Size   Complexity  
A restore() 0 10 2
A childbearing() 0 14 4
A remove() 0 23 4
A minify() 0 9 1
A filter() 0 20 2
1
<?php
2
3
namespace Staticka\Filters;
4
5
use Staticka\Contracts\FilterContract;
6
7
/**
8
 * HTML Minifier
9
 *
10
 * @package Staticka
11
 * @author  Rougin Gutib <[email protected]>
12
 */
13
class HtmlMinifier implements FilterContract
14
{
15
    /**
16
     * @var array
17
     */
18
    protected $data = array();
19
20
    /**
21
     * Filters the specified code.
22
     *
23
     * @param  string $code
24
     * @return string
25
     */
26 9
    public function filter($code)
27
    {
28 9
        if (strpos($code, '<html') === false)
29 3
        {
30 6
            return $this->minify($code);
31
        }
32
33 3
        $utf8 = (string) '<?xml encoding="UTF-8">';
34
35 3
        $dom = new \DOMDocument;
36
37 3
        @$dom->loadHTML((string) $utf8 . $code);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for loadHTML(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

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

37
        /** @scrutinizer ignore-unhandled */ @$dom->loadHTML((string) $utf8 . $code);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
38
39 3
        $elements = $dom->getElementsByTagName('*');
40
41 3
        $this->remove($elements);
42
43 3
        $html = $this->minify($dom->saveHTML());
44
45 3
        return $this->restore((string) $html);
46
    }
47
48
    /**
49
     * Checks if a specified node has children.
50
     *
51
     * @param  \DOMNode $node
52
     * @return boolean
53
     */
54 3
    protected function childbearing(\DOMNode $node)
55
    {
56 3
        if ($node->hasChildNodes())
57 1
        {
58 3
            foreach ($node->childNodes as $child)
59
            {
60 3
                if ($child->nodeType === XML_ELEMENT_NODE)
61 1
                {
62 3
                    return true;
63
                }
64 1
            }
65 1
        }
66
67 3
        return false;
68
    }
69
70
    /**
71
     * Minifies the specified HTML.
72
     *
73
     * @param  string $html
74
     * @return string
75
     */
76 9
    protected function minify($html)
77
    {
78 9
        $html = str_replace('<?xml encoding="UTF-8">', '', $html);
79
80 9
        $html = trim(preg_replace('/\s+/', ' ', $html));
81
82 9
        $html = str_replace('> <', '><', $html);
83
84 9
        return str_replace(array(' />', '/>'), '>', $html);
85
    }
86
87
    /**
88
     * Removes the content of single elements.
89
     *
90
     * @param  \DOMNodeList $elements
91
     * @return void
92
     */
93 3
    protected function remove(\DOMNodeList $elements)
94
    {
95 3
        $encoded = array('textarea', 'code');
96
97 3
        foreach ($elements as $element)
98
        {
99 3
            if ($this->childbearing($element))
100 1
            {
101 3
                continue;
102
            }
103
104 3
            $output = (string) $element->nodeValue;
105
106 3
            if (in_array($element->nodeName, $encoded))
107 1
            {
108 3
                $output = htmlentities($element->nodeValue);
109 1
            }
110
111 3
            array_push($this->data, (string) $output);
112
113 3
            $current = count($this->data) - 1;
114
115 3
            $element->nodeValue = '$' . $current . '$';
116 1
        }
117 3
    }
118
119
    /**
120
     * Restores the data into the minified HTML.
121
     *
122
     * @param  string $html
123
     * @return string
124
     */
125 3
    protected function restore($html)
126
    {
127 3
        foreach ($this->data as $index => $item)
128
        {
129 3
            $key = (string) '$' . $index . '$';
130
131 3
            $html = str_replace($key, $item, $html);
132 1
        }
133
134 3
        return (string) $html;
135
    }
136
}
137