Completed
Push — master ( 9fbe45...817727 )
by Kevin
03:24
created

Link::removeInvalidSelf()   D

Complexity

Conditions 9
Paths 12

Size

Total Lines 41
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 21
CRAP Score 9

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 41
ccs 21
cts 21
cp 1
rs 4.909
cc 9
eloc 19
nc 12
nop 1
crap 9
1
<?php
2
3
namespace Groundskeeper\Tokens\Elements;
4
5
use Groundskeeper\Configuration;
6
use Groundskeeper\Tokens\Element;
7
use Groundskeeper\Tokens\ElementTypes\ClosedElement;
8
use Groundskeeper\Tokens\ElementTypes\MetadataContent;
9
use Psr\Log\LoggerInterface;
10
11
class Link extends ClosedElement implements MetadataContent
12
{
13 6
    protected function getAllowedAttributes()
14
    {
15
        $linkAllowedAttributes = array(
16 6
            '/^href$/i' => Element::ATTR_URI,
17 6
            '/^crossorigin$/i' => Element::ATTR_CS_STRING,
18 6
            '/^rel$/i' => Element::ATTR_CI_SSENUM . '("alternate","author","help","icon","license","next","pingback","prefetch","prev","search","stylesheet")',
19 6
            '/^media$/i' => Element::ATTR_CI_STRING,
20 6
            '/^hreflang$/i' => Element::ATTR_CS_STRING,
21 6
            '/^type$/i' => Element::ATTR_CI_STRING,
22
            '/^sizes$/i' => Element::ATTR_CI_STRING
23 6
        );
24
25 6
        return array_merge(
26 6
            $linkAllowedAttributes,
27 6
            parent::getAllowedAttributes()
28 6
        );
29
    }
30
31 6
    protected function removeInvalidSelf(LoggerInterface $logger)
32
    {
33
        // Must have "href" attribute.
34 6
        if (!$this->hasAttribute('href')) {
35 1
            $logger->debug($this . ' requires "href" attribute.');
36
37 1
            return true;
38
        }
39
40
        // Must have either "rel" or "itemprop" attribute, but not both.
41 5
        $attrCount = 0;
42 5
        foreach ($this->attributes as $key => $value) {
43 5
            if ($key == 'rel' || $key == 'itemprop') {
44 4
                ++$attrCount;
45 4
            }
46
47 5
            if ($attrCount > 1) {
48
                // If both, then we don't know which one should be kept,
49
                // so we recommend to delete the entire element.
50 1
                $logger->debug($this . ' requires either "rel" or "itemprop" attribute, but not both.');
51
52 1
                return true;
53
            }
54 5
        }
55
56 4
        if ($attrCount == 0) {
57 1
            $logger->debug($this . ' requires either "rel" or "itemprop" attribute.');
58
59 1
            return true;
60
        }
61
62
        // If inside "body" element, then we check if allowed.
63 3
        $body = new Body($this->configuration, 'body');
64 3
        if ($this->hasAncestor($body) && !$this->isAllowedInBody()) {
65 1
            $logger->debug($this . ' does not have the correct attributes to be allowed inside the "body" element.');
66
67 1
            return true;
68
        }
69
70 2
        return false;
71
    }
72
73
    /**
74
     * Is this element allowed inside a body element?
75
     *
76
     * https://html.spec.whatwg.org/multipage/semantics.html#allowed-in-the-body
77
     *
78
     * @return bool True if allowed.
79
     */
80 2
    public function isAllowedInBody()
81
    {
82 2
        if ($this->hasAttribute('itemprop')) {
83 1
            return true;
84
        }
85
86 2
        if ($this->hasAttribute('rel') &&
87 2
            ($this->attributes['rel'] == 'pingback' ||
88 2
             $this->attributes['rel'] == 'prefetch' ||
89 2
             $this->attributes['rel'] == 'stylesheet')) {
90 1
            return true;
91
        }
92
93 1
        return false;
94
    }
95
}
96