Completed
Push — master ( c0ba30...54b444 )
by Joschi
04:59
created

getPropertyContentAttrValue()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 3
cts 3
cp 1
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 3
nc 2
nop 1
crap 2
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\Domain\Exceptions\RuntimeException;
41
use Jkphl\RdfaLiteMicrodata\Domain\Property\Property;
42
use Jkphl\RdfaLiteMicrodata\Domain\Thing\ThingInterface;
43
use Jkphl\RdfaLiteMicrodata\Domain\Vocabulary\VocabularyInterface;
44
45
/**
46
 * Property processor methods
47
 *
48
 * @package Jkphl\RdfaLiteMicrodata
49
 * @subpackage Jkphl\RdfaLiteMicrodata\Infrastructure
50
 * @property boolean $html HTML mode
51
 * @property array $propertyCache Property cache
52
 */
53
trait PropertyProcessorTrait
54
{
55
    /**
56
     * Create a property by prefix and name
57
     *
58
     * @param string $prefix Property prefix
59
     * @param string $name Property name
60
     * @param \DOMElement $element DOM element
61
     * @param ContextInterface $context Inherited Context
62
     * @param boolean $last Last property
63
     * @return ContextInterface Local context for this element
64
     */
65 11
    protected function processPropertyPrefixName($prefix, $name, \DOMElement $element, ContextInterface $context, $last)
66
    {
67 11
        $vocabulary = $this->getVocabulary($prefix, $context);
68 11
        if ($vocabulary instanceof VocabularyInterface) {
69
            try {
70 11
                $context = $this->addProperty($element, $context, $name, $vocabulary, $last);
71 11
            } catch (RuntimeException $e) {
72
                // Skip invalid property
73
            }
74 11
        }
75
76 11
        return $context;
77
    }
78
79
    /**
80
     * Return a vocabulary by prefix with fallback to the default vocabulary
81
     *
82
     * @param string $prefix Vocabulary prefix
83
     * @param ContextInterface $context Context
84
     * @return VocabularyInterface Vocabulary
85
     */
86
    abstract protected function getVocabulary($prefix, ContextInterface $context);
87
88
    /**
89
     * Add a single property
90
     *
91
     * @param \DOMElement $element DOM element
92
     * @param ContextInterface $context Inherited Context
93
     * @param string $name Property name
94
     * @param VocabularyInterface $vocabulary Property vocabulary
95
     * @param boolean $last Last property
96
     * @return ContextInterface Local context for this element
97
     */
98 11
    protected function addProperty(
99
        \DOMElement $element,
100
        ContextInterface $context,
101
        $name,
102
        VocabularyInterface $vocabulary,
103
        $last
104
    ) {
105 11
        $resourceId = $this->getResourceId($element);
106
107
        // Get the property value
108 11
        $propertyValue = $this->getPropertyValue($element, $context);
109 11
        $property = new Property($name, $vocabulary, $propertyValue, $resourceId);
110
111
        // Add the property to the current parent thing
112 11
        $context->getParentThing()->addProperty($property);
113
114 11
        return $this->addPropertyChild($propertyValue, $context, $last);
115
    }
116
117
    /**
118
     * Return the resource ID
119
     *
120
     * @param \DOMElement $element DOM element
121
     * @return string|null Resource ID
122
     */
123
    abstract protected function getResourceId(\DOMElement $element);
124
125
    /**
126
     * Return a property value (type and tag name dependent)
127
     *
128
     * @param \DOMElement $element DOM element
129
     * @param ContextInterface $context Context
130
     * @return ThingInterface|string Property value
131
     */
132 11
    protected function getPropertyValue(\DOMElement $element, ContextInterface $context)
133
    {
134 11
        $value = $this->getPropertyCache($element);
135 11
        if ($value !== null) {
136 3
            return $value;
137
        }
138
139 11
        $propertyChild = $this->getPropertyChildValue($element, $context);
140 11
        if ($propertyChild instanceof ThingInterface) {
141 8
            return $this->setPropertyCache($element, $propertyChild);
142
        }
143
144
        // Return a string property value
145 11
        return $this->setPropertyCache($element, $this->getPropertyStringValue($element));
146
    }
147
148
    /**
149
     * Return a cached property value (if available)
150
     *
151
     * @param \DOMElement $element Element
152
     * @return mixed|null Property value
153
     */
154 11
    protected function getPropertyCache(\DOMElement $element)
155
    {
156 11
        $elementHash = $element->getNodePath();
157 11
        return isset($this->propertyCache[$elementHash]) ? $this->propertyCache[$elementHash] : null;
158
    }
159
160
    /**
161
     * Return a property child value
162
     *
163
     * @param \DOMElement $element DOM element
164
     * @param ContextInterface $context Context
165
     * @return ThingInterface|null Property child value
166
     */
167
    abstract protected function getPropertyChildValue(\DOMElement $element, ContextInterface $context);
168
169
    /**
170
     * Cache a property value
171
     *
172
     * @param \DOMElement $element DOM element
173
     * @param mixed $value Value
174
     * @return mixed $value Value
175
     */
176 11
    protected function setPropertyCache(\DOMElement $element, $value)
177
    {
178 11
        return $this->propertyCache[$element->getNodePath()] = $value;
179
    }
180
181
    /**
182
     * Return a property value (type and tag name dependent)
183
     *
184
     * @param \DOMElement $element DOM element
185
     * @return string Property value
186
     */
187 11
    protected function getPropertyStringValue(\DOMElement $element)
188
    {
189
        // If HTML mode is active
190 11
        if ($this->html) {
191 10
            $value = $this->getPropertyContentAttrValue($element);
192 10
            if ($value === null) {
193 10
                $value = $this->getPropertyHtmlValue($element);
194 10
            }
195 10
            if ($value !== null) {
196 10
                return $value;
197
            }
198 10
        }
199
200
        // Return the text content
201 11
        return $element->textContent;
202
    }
203
204
    /**
205
     * Return a content attribute property value
206
     *
207
     * @param \DOMElement $element DOM element
208
     * @return null|string Property value
209
     */
210 10
    protected function getPropertyContentAttrValue(\DOMElement $element)
211
    {
212 10
        $value = trim($element->getAttribute('content'));
213 10
        return strlen($value) ? $value : null;
214
    }
215
216
    /**
217
     * Return a property value (type and tag name dependent)
218
     *
219
     * @param \DOMElement $element DOM element
220
     * @return string|null Property value
221
     */
222 10
    protected function getPropertyHtmlValue(\DOMElement $element)
223
    {
224 10
        $tagName = strtoupper($element->tagName);
225
226
        // Map to an attribute (if applicable)
227 10
        if (array_key_exists($tagName, self::$tagNameAttributes)) {
228 9
            $value = strval($element->getAttribute(self::$tagNameAttributes[$tagName]));
229 9
            return (($tagName != 'TIME') || strlen($value)) ? $value : null;
230
        }
231
232 10
        return null;
233
    }
234
235
    /**
236
     * Add a property child
237
     *
238
     * @param string|ThingInterface Property value
239
     * @param ContextInterface $context Inherited Context
240
     * @param boolean $last Last property
241
     * @return ContextInterface Local context for this element
242
     */
243 11
    protected function addPropertyChild($propertyValue, ContextInterface $context, $last)
244
    {
245
        // If the property value is a thing and this is the element's last property
246 11
        if (($propertyValue instanceof ThingInterface) && $last) {
247
            // Set the thing as parent thing for nested iterations
248 8
            $context = $context->setParentThing($propertyValue);
249 8
        }
250
251 11
        return $context;
252
    }
253
254
    /**
255
     * Create a property
256
     *
257
     * @param \DOMElement $element DOM element
258
     * @param ContextInterface $context Inherited Context
259
     * @return ContextInterface Local context for this element
260
     */
261
    abstract protected function processProperty(\DOMElement $element, ContextInterface $context);
262
}
263