Completed
Push — master ( 8c4081...342540 )
by Joschi
02:42
created

RdfaLiteElementProcessor::getPropertyChildValue()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 13
ccs 6
cts 6
cp 1
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 7
nc 2
nop 2
crap 3
1
<?php
2
3
/**
4
 * rdfa-lite-microdata
5
 *
6
 * @category Jkphl
7
 * @package Jkphl\RdfaLiteMicrodata
8
 * @subpackage Jkphl\RdfaLiteMicrodata\Infrastructure
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\RdfaLiteMicrodata\Infrastructure\Parser;
38
39
use Jkphl\RdfaLiteMicrodata\Application\Context\ContextInterface;
40
use Jkphl\RdfaLiteMicrodata\Application\Context\RdfaLiteContext;
41
use Jkphl\RdfaLiteMicrodata\Application\Parser\RootThing;
42
use Jkphl\RdfaLiteMicrodata\Domain\Thing\ThingInterface;
43
use Jkphl\RdfaLiteMicrodata\Domain\Vocabulary\Vocabulary;
44
use Jkphl\RdfaLiteMicrodata\Domain\Vocabulary\VocabularyInterface;
45
46
/**
47
 * RDFa Lite 1.1 element processor
48
 *
49
 * @package Jkphl\RdfaLiteMicrodata
50
 * @subpackage Jkphl\RdfaLiteMicrodata\Infrastructure
51
 */
52
class RdfaLiteElementProcessor extends AbstractElementProcessor
53
{
54
    /**
55
     * Process a DOM element
56
     *
57
     * @param \DOMElement $element DOM element
58
     * @param ContextInterface $context Inherited Context
59
     * @return ContextInterface Local context for this element
60
     */
61 11
    public function processElement(\DOMElement $element, ContextInterface $context)
62
    {
63
        // Process default vocabulary registrations
64 11
        $context = $this->processVocab($element, $context);
65
66
        // Register vocabulary prefixes
67 11
        $context = $this->processPrefix($element, $context);
68
69
        // Create a property
70 11
        return $this->processProperty($element, $context);
71
    }
72
73
    /**
74
     * Process changes of the default vocabulary
75
     *
76
     * @param \DOMElement $element DOM element
77
     * @param ContextInterface $context Inherited Context
78
     * @return ContextInterface Local context for this element
79
     */
80 11
    protected function processVocab(\DOMElement $element, ContextInterface $context)
81
    {
82 11
        if ($element->hasAttribute('vocab') && ($context instanceof RdfaLiteContext)) {
83 8
            $defaultVocabulary = new Vocabulary($element->getAttribute('vocab'));
84 8
            $context = $context->setDefaultVocabulary($defaultVocabulary);
85
        }
86
87 11
        return $context;
88
    }
89
90
    /**
91
     * Process vocabulary prefixes
92
     *
93
     * @param \DOMElement $element DOM element
94
     * @param ContextInterface $context Inherited Context
95
     * @return ContextInterface Local context for this element
96
     */
97 11
    protected function processPrefix(\DOMElement $element, ContextInterface $context)
98
    {
99 11
        if ($element->hasAttribute('prefix') && ($context instanceof RdfaLiteContext)) {
100 8
            $prefixes = preg_split('/\s+/', $element->getAttribute('prefix'));
101 8
            while (count($prefixes)) {
102 8
                $prefix = rtrim(array_shift($prefixes), ':');
103 8
                $uri = array_shift($prefixes);
104 8
                $context = $context->registerVocabulary($prefix, $uri);
105
            }
106
        }
107
108 11
        return $context;
109
    }
110
111
    /**
112
     * Create a property
113
     *
114
     * @param \DOMElement $element DOM element
115
     * @param ContextInterface $context Inherited Context
116
     * @return ContextInterface Local context for this element
117
     */
118 11
    protected function processProperty(\DOMElement $element, ContextInterface $context)
119
    {
120 11
        if ($element->hasAttribute('property') && !($context->getParentThing() instanceof RootThing)) {
121 5
            $properties = preg_split('/\s+/', $element->getAttribute('property'));
122 5
            foreach ($properties as $index => $property) {
123 5
                $firstProperty = ($index ? 0 : self::PROPERTY_FIRST);
124 5
                $lastProperty = ($index == (count($properties) - 1)) ? self::PROPERTY_LAST : 0;
125 5
                list($prefix, $name) = $this->getPrefixName($property);
126 5
                $context = $this->processPropertyPrefixName(
127
                    $prefix,
128
                    $name,
129
                    $element,
130
                    $context,
131 5
                    $firstProperty | $lastProperty
132
                );
133
            }
134
        }
135
136 11
        return $context;
137
    }
138
139
    /**
140
     * Split a value into a vocabulary prefix and a name
141
     *
142
     * @param string $prefixName Prefixed name
143
     * @return array Prefix and name
144
     */
145 11
    protected function getPrefixName($prefixName)
146
    {
147 11
        $prefixName = explode(':', $prefixName);
148 11
        $name = array_pop($prefixName);
149 11
        $prefix = array_pop($prefixName);
150 11
        return [$prefix, $name];
151
    }
152
153
    /**
154
     * Create a nested child
155
     *
156
     * @param \DOMElement $element DOM element
157
     * @param ContextInterface $context Context
158
     * @return ContextInterface Context for children
159
     */
160 11
    protected function processChild(\DOMElement $element, ContextInterface $context)
161
    {
162 11
        if ($element->hasAttribute('typeof')
163 11
            && (empty($element->getAttribute('property')) || $context->getParentThing() instanceof RootThing)
164
        ) {
165 11
            $thing = $this->getThing(
166 11
                $element->getAttribute('typeof'),
167 11
                trim($element->getAttribute('resource')) ?: null,
168
                $context
169
            );
170
171
            // Add the new thing as a child to the current context
172
            // and set the thing as parent thing for nested iterations
173 5
            $context = $context->addChild($thing)->setParentThing($thing);
174
        }
175
176 11
        return $context;
177
    }
178
179
    /**
180
     * Return a property child value
181
     *
182
     * @param \DOMElement $element DOM element
183
     * @param ContextInterface $context Context
184
     * @return ThingInterface|null Property child value
185
     */
186 5
    protected function getPropertyChildValue(\DOMElement $element, ContextInterface $context)
187
    {
188
        // If the property creates a new thing
189 5
        if ($element->hasAttribute('typeof')) {
190 2
            return $this->getThing(
191 2
                $element->getAttribute('typeof'),
192 2
                trim($element->getAttribute('resource')) ?: null,
193
                $context
194
            );
195
        }
196
197 5
        return null;
198
    }
199
200
    /**
201
     * Return the resource ID
202
     *
203
     * @param \DOMElement $element DOM element
204
     * @return string|null Resource ID
205
     */
206 5
    protected function getResourceId(\DOMElement $element)
207
    {
208 5
        return trim($element->getAttribute('resource')) ?: null;
209
    }
210
211
    /**
212
     * Return a vocabulary by prefix with fallback to the default vocabulary
213
     *
214
     * @param string $prefix Vocabulary prefix
215
     * @param ContextInterface $context Context
216
     * @return VocabularyInterface Vocabulary
217
     */
218 11
    protected function getVocabulary($prefix, ContextInterface $context)
219
    {
220 11
        return (empty($prefix) || !($context instanceof RdfaLiteContext)) ?
221 11
            $context->getDefaultVocabulary() : $context->getVocabulary($prefix);
222
    }
223
}
224