Completed
Push — v2 ( 470733...24c99f )
by Joschi
04:43
created

LinkRel::parseDom()   C

Complexity

Conditions 7
Paths 13

Size

Total Lines 50
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 24
CRAP Score 7

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 24
c 1
b 0
f 0
nc 13
nop 1
dl 0
loc 50
ccs 24
cts 24
cp 1
crap 7
rs 6.7272
1
<?php
2
3
/**
4
 * micrometa
5
 *
6
 * @category Jkphl
7
 * @package Jkphl\Micrometa
8
 * @subpackage Jkphl\Micrometa\Infrastructure\Parser
9
 * @author Joschi Kuphal <[email protected]> / @jkphl
10
 * @copyright Copyright © 2017 Joschi Kuphal <[email protected]> / @jkphl
11
 * @license http://opensource.org/licenses/MIT The MIT License (MIT)
12
 */
13
14
/***********************************************************************************
15
 *  The MIT License (MIT)
16
 *
17
 *  Copyright © 2017 Joschi Kuphal <[email protected]> / @jkphl
18
 *
19
 *  Permission is hereby granted, free of charge, to any person obtaining a copy of
20
 *  this software and associated documentation files (the "Software"), to deal in
21
 *  the Software without restriction, including without limitation the rights to
22
 *  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
23
 *  the Software, and to permit persons to whom the Software is furnished to do so,
24
 *  subject to the following conditions:
25
 *
26
 *  The above copyright notice and this permission notice shall be included in all
27
 *  copies or substantial portions of the Software.
28
 *
29
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
31
 *  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
32
 *  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
33
 *  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
34
 *  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35
 ***********************************************************************************/
36
37
namespace Jkphl\Micrometa\Infrastructure\Parser;
38
39
use Jkphl\Micrometa\Application\Contract\ParsingResultInterface;
40
use Jkphl\Micrometa\Ports\Format;
41
42
/**
43
 * Link rel parser
44
 *
45
 * @package Jkphl\Micrometa
46
 * @subpackage Jkphl\Micrometa\Infrastructure
47
 */
48
class LinkRel extends AbstractParser
49
{
50
    /**
51
     * Format
52
     *
53
     * @var int
54
     */
55
    const FORMAT = Format::LINK_REL;
56
    /**
57
     * HTML namespace
58
     *
59
     * @var string
60
     */
61
    const HTML_PROFILE_URI = 'http://www.w3.org/1999/xhtml';
62
63
    /**
64
     * Parse a DOM document
65
     *
66
     * @param \DOMDocument $dom DOM Document
67
     * @return ParsingResultInterface Micro information items
68
     */
69 1
    public function parseDom(\DOMDocument $dom)
70
    {
71 1
        $items = [];
72
73
        // Resave to proper XML to get full namespace support
74 1
        $dom2 = $dom->saveXML();
75 1
        $dom = new \DOMDocument();
76 1
        $dom->loadXML($dom2);
77
78 1
        $xpath = new \DOMXPath($dom);
79 1
        $xpath->registerNamespace('html', self::HTML_PROFILE_URI);
80
81
        // Run through all <link> elements with a `rel` attribute
82
        /** @var \DOMElement $linkRel */
83 1
        foreach ($xpath->query('//html:link[@rel]') as $linkRel) {
84 1
            $item = new \stdClass();
85
86
            // Collect the item types
87 1
            $item->type = [];
88 1
            foreach (preg_split('/\040+/', $linkRel->getAttribute('rel')) as $rel) {
89 1
                $item->type[] = (object)['name' => $rel, 'profile' => self::HTML_PROFILE_URI];
90
            }
91
92
            // Get the item ID (if any)
93 1
            if ($linkRel->hasAttribute('id')) {
94 1
                $item->id = $linkRel->getAttribute('id');
95
            }
96
97
            // Run through all item attributes
98 1
            $item->properties = [];
99
            /**
100
             * @var string $attributeName Attribute name
101
             * @var \DOMAttr $attribute Attribute
102
             */
103 1
            foreach ($linkRel->attributes as $attributeName => $attribute) {
104 1
                if (!in_array($attributeName, ['rel', 'id'])) {
105 1
                    $profile = $attribute->lookupNamespaceUri($attribute->prefix ?: null);
106 1
                    $item->properties[] = (object)[
107 1
                        'name' => $attributeName,
108 1
                        'profile' => $profile,
109 1
                        'values' => $this->parseAttributeValue($profile, $attributeName, $attribute->value),
110
                    ];
111
                }
112
            }
113
114 1
            $items[] = $item;
115
        }
116
117 1
        return new ParsingResult(self::FORMAT, $items);
118
    }
119
120
    /**
121
     * Parse an attribute value
122
     *
123
     * @param string $profile Profile
124
     * @param string $attribute Attribute name
125
     * @param string $value Attribute value
126
     * @return array Attribute values
127
     */
128 1
    protected function parseAttributeValue($profile, $attribute, $value)
129
    {
130
        // If it's a HTML attribute
131 1
        if ($profile == LinkRel::HTML_PROFILE_URI) {
132
            switch ($attribute) {
133
                // Space delimited lists
134 1
                case 'sizes':
135 1
                    return array_filter(preg_split('/\040+/', $value));
136
                    break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
137
                // Space or comma delimited lists
138 1
                case 'charset':
139 1
                    return array_filter(preg_split('/[,\040]+/', $value));
140
                    break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
141
            }
142
        }
143
144 1
        return [$value];
145
    }
146
}
147