Completed
Push — master ( e0ac7a...8eddfc )
by Kevin
03:21
created

A   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 81
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 92.45%

Importance

Changes 2
Bugs 1 Features 2
Metric Value
wmc 21
c 2
b 1
f 2
lcom 1
cbo 4
dl 0
loc 81
ccs 49
cts 53
cp 0.9245
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A getAllowedAttributes() 0 18 1
C doClean() 0 49 18
A isInteractiveContent() 0 4 1
A isTransparentElement() 0 4 1
1
<?php
2
3
namespace Groundskeeper\Tokens\Elements;
4
5
use Groundskeeper\Configuration;
6
use Groundskeeper\Tokens\Element;
7
use Groundskeeper\Tokens\ElementTypes\FlowContent;
8
use Groundskeeper\Tokens\ElementTypes\InlineElement;
9
use Groundskeeper\Tokens\ElementTypes\InteractiveContent;
10
use Groundskeeper\Tokens\ElementTypes\OpenElement;
11
use Groundskeeper\Tokens\ElementTypes\PhrasingContent;
12
use Groundskeeper\Tokens\ElementTypes\TransparentElement;
13
use Groundskeeper\Tokens\Token;
14
use Psr\Log\LoggerInterface;
15
16
/**
17
 * "a" element
18
 *
19
 * https://html.spec.whatwg.org/multipage/semantics.html#the-a-element
20
 */
21
class A extends OpenElement implements FlowContent, InteractiveContent, PhrasingContent, InlineElement, TransparentElement
22
{
23 5
    protected function getAllowedAttributes()
24
    {
25
        $aAllowedAttributes = array(
26 5
            '/^href$/i' => Element::ATTR_URI,
27 5
            '/^target$/i' => Element::ATTR_CS_STRING,
28 5
            '/^download$/i' => Element::ATTR_CS_STRING,
29 5
            '/^ping$/i' => Element::ATTR_URI,
30 5
            '/^rel$/i' => Element::ATTR_CS_STRING,
31 5
            '/^hreflang$/i' => Element::ATTR_CS_STRING,
32 5
            '/^type$/i' => Element::ATTR_CS_STRING,
33
            '/^referrerpolicy$/i' => Element::ATTR_CS_STRING
34 5
        );
35
36 5
        return array_merge(
37 5
            $aAllowedAttributes,
38 5
            parent::getAllowedAttributes()
39 5
        );
40
    }
41
42 5
    protected function doClean(LoggerInterface $logger)
43
    {
44
        // If the "itemprop" attribute is specified on an "a" element, then
45
        // the "href" attribute must also be specified.
46 5
        if ($this->hasAttribute('itemprop') && !$this->hasAttribute('href')) {
47 1
            $logger->debug('Element "a" with "itemprop" attribute requires the "href" attribute also.  Adding empty "href" attribute.');
48 1
            $this->addAttribute('href', '');
49 1
        }
50
51 5
        if ($this->configuration->get('clean-strategy') != Configuration::CLEAN_STRATEGY_LENIENT) {
52
            // There must be no interactive content or "a" element descendants.
53 5
            foreach ($this->children as $child) {
54 5
                if ($child->getType() == Token::COMMENT) {
55 1
                    continue;
56
                }
57
58 5
                if ($child->getType() == Token::ELEMENT &&
59 1
                    ($child->getName() == 'a' ||
60 5
                     ($child instanceof InteractiveContent && $child->isInteractiveContent()))) {
61 1
                    $logger->debug('Removing ' . $child . '. Element "a" cannot contain "a" or interactive content elements.');
62 1
                    $this->removeChild($child);
63 1
                }
64 5
            }
65
66
            // The target, download, ping, rel, hreflang, type, and
67
            // referrerpolicy attributes must be omitted if the href
68
            // attribute is not present.
69 5
            if (!$this->hasAttribute('href')) {
70 1
                if ($this->hasAttribute('target') ||
71 1
                    $this->hasAttribute('download') ||
72 1
                    $this->hasAttribute('ping') ||
73 1
                    $this->hasAttribute('rel') ||
74 1
                    $this->hasAttribute('hreflang') ||
75 1
                    $this->hasAttribute('type') ||
76 1
                    $this->hasAttribute('referrerpolicy')) {
77 1
                    $logger->debug('Removing invalid attributes.  Element "a" without "href" attribute cannot contain "target", "download", "ping", "rel", "hreflang", "type", or "referrerpolicy" attributes.');
78 1
                    $this->removeAttribute('target');
79 1
                    $this->removeAttribute('download');
80 1
                    $this->removeAttribute('ping');
81 1
                    $this->removeAttribute('rel');
82 1
                    $this->removeAttribute('hreflang');
83 1
                    $this->removeAttribute('type');
84 1
                    $this->removeAttribute('referrerpolicy');
85 1
                }
86 1
            }
87 5
        }
88
89 5
        return true;
90
    }
91
92
    public function isInteractiveContent()
93
    {
94
        return $this->hasAttribute('href');
95
    }
96
97
    public function isTransparentElement()
98
    {
99
        return true;
100
    }
101
}
102