Completed
Push — v2 ( 094005...546f8a )
by Joschi
04:35
created

Item::getPropertyValue()   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
c 0
b 0
f 0
ccs 3
cts 3
cp 1
rs 9.4285
cc 2
eloc 3
nc 2
nop 1
crap 2
1
<?php
2
3
/**
4
 * micrometa
5
 *
6
 * @category Jkphl
7
 * @package Jkphl\Micrometa
8
 * @subpackage Jkphl\Micrometa\Ports
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\Ports\Item;
38
39
use Jkphl\Micrometa\Application\Contract\ValueInterface;
40
use Jkphl\Micrometa\Application\Factory\AliasFactory;
41
use Jkphl\Micrometa\Application\Factory\PropertyListFactory;
42
use Jkphl\Micrometa\Application\Item\ItemInterface as ApplicationItemInterface;
43
use Jkphl\Micrometa\Application\Item\PropertyListInterface;
44
use Jkphl\Micrometa\Domain\Exceptions\OutOfBoundsException as DomainOutOfBoundsException;
45
use Jkphl\Micrometa\Domain\Item\Iri;
46
use Jkphl\Micrometa\Infrastructure\Factory\ItemFactory;
47
use Jkphl\Micrometa\Infrastructure\Factory\ProfiledNamesFactory;
48
use Jkphl\Micrometa\Infrastructure\Parser\ProfiledNamesList;
49
use Jkphl\Micrometa\Ports\Exceptions\InvalidArgumentException;
50
use Jkphl\Micrometa\Ports\Exceptions\OutOfBoundsException;
51
52
/**
53
 * Micro information item
54
 *
55
 * @package Jkphl\Micrometa
56
 * @subpackage Jkphl\Micrometa\Ports
57
 */
58
class Item extends ItemList implements ItemInterface
59
{
60
    /**
61
     * Application item
62
     *
63
     * @var ApplicationItemInterface
64
     */
65
    protected $item;
66
67
    /**
68
     * Item constructor
69
     *
70
     * @param ApplicationItemInterface $item Application item
71
     */
72 14
    public function __construct(ApplicationItemInterface $item)
73
    {
74 14
        $this->item = $item;
75 14
        parent::__construct(ItemFactory::createFromApplicationItems($this->item->getChildren()));
76 14
    }
77
78
    /**
79
     * Get the first value of an item property
80
     *
81
     * @param string $name Item property name
82
     * @return array|string|ItemInterface First value of an item property
83
     * @api
84
     */
85 2
    public function __get($name)
86
    {
87 2
        return $this->getProperty($name, null, 0);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->getProperty($name, null, 0); of type array|Jkphl\Micrometa\Po...Contract\ValueInterface adds the type Jkphl\Micrometa\Applicat...Contract\ValueInterface to the return on line 87 which is incompatible with the return type declared by the interface Jkphl\Micrometa\Ports\Item\ItemInterface::__get of type array|string|Jkphl\Micro...orts\Item\ItemInterface.
Loading history...
88
    }
89
90
    /**
91
     * Get a single property (value)
92
     *
93
     * @param string|\stdClass|Iri $name Property name
94
     * @param string $profile Property profile
95
     * @param int $index Property value index
96
     * @return array|string|ItemInterface Property value(s)
97
     * @throws OutOfBoundsException If the property name is unknown
98
     * @throws OutOfBoundsException If the property value index is out of bounds
99
     * @api
100
     */
101 7
    public function getProperty($name, $profile = null, $index = null)
102
    {
103
        try {
104 7
            $propertyValues = $this->item->getProperty($name, $profile);
105 4
        } catch (DomainOutOfBoundsException $e) {
106 4
            throw new OutOfBoundsException($e->getMessage(), $e->getCode());
107
        }
108
109
        // If all property values should be returned
110 7
        if ($index === null) {
111 5
            return array_map([$this, 'getPropertyValue'], $propertyValues);
112
        }
113
114
        // If the property value index is out of bounds
115 6
        if (!isset($propertyValues[$index])) {
116 1
            throw new OutOfBoundsException(
117 1
                sprintf(OutOfBoundsException::INVALID_PROPERTY_VALUE_INDEX_STR, $index),
118 1
                OutOfBoundsException::INVALID_PROPERTY_VALUE_INDEX
119
            );
120
        }
121
122 5
        return $this->getPropertyValue($propertyValues[$index]);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->getPropertyValue($propertyValues[$index]); of type Jkphl\Micrometa\Ports\It...Contract\ValueInterface adds the type Jkphl\Micrometa\Applicat...Contract\ValueInterface to the return on line 122 which is incompatible with the return type declared by the interface Jkphl\Micrometa\Ports\It...mInterface::getProperty of type array|string|Jkphl\Micro...orts\Item\ItemInterface.
Loading history...
123
    }
124
125
    /**
126
     * Prepare a property value for returning it
127
     *
128
     * @param ValueInterface $value Property value
129
     * @return Item|mixed Returnable property value
130
     */
131 7
    protected function getPropertyValue(ValueInterface $value)
132
    {
133 7
        return ($value instanceof ApplicationItemInterface) ?
134 7
            ItemFactory::createFromApplicationItem($value) : $value;
135
    }
136
137
    /**
138
     * Return whether the item is of a particular type (or contained in a list of types)
139
     *
140
     * The item type(s) can be specified in a variety of ways, @see ProfiledNamesFactory::createFromArguments()
141
     *
142
     * @param array ...$types Item types
143
     * @return boolean Item type is contained in the list of types
144
     * @api
145
     */
146 5
    public function isOfType(...$types)
147
    {
148
        /** @var ProfiledNamesList $profiledTypes */
149 5
        $profiledTypes = ProfiledNamesFactory::createFromArguments($types);
150 5
        $aliasFactory = new AliasFactory();
151
152
        // Run through all item types
153
        /** @var \stdClass $itemType */
154 5
        foreach ($this->item->getType() as $itemType) {
155 5
            $itemTypeNames = $aliasFactory->createAliases($itemType->name);
156 5
            if ($this->isOfProfiledTypes($itemType->profile, $itemTypeNames, $profiledTypes)) {
157 5
                return true;
158
            }
159
        }
160
161 3
        return false;
162
    }
163
164
    /**
165
     * Return whether an aliased item type in contained in a set of query types
166
     *
167
     * @param string $profile Type profile
168
     * @param array $names Aliased type names
169
     * @param ProfiledNamesList $types Query types
170
     * @return bool Item type is contained in the set of query types
171
     */
172 5
    protected function isOfProfiledTypes($profile, array $names, ProfiledNamesList $types)
173
    {
174
        // Run through all query types
175
        /** @var \stdClass $queryType */
176 5
        foreach ($types as $queryType) {
177 5
            if (in_array($queryType->name, $names) &&
178 5
                (($queryType->profile === null) ? true : ($queryType->profile == $profile))
179
            ) {
180 5
                return true;
181
            }
182
        }
183 3
        return false;
184
    }
185
186
    /**
187
     * Get all values of the first available property in a stack
188
     *
189
     * The property stack can be specified in a variety of ways, @see ProfiledNamesFactory::createFromArguments()
190
     *
191
     * @param string $name Name
192
     * @param string $profile Profile
193
     * @return array|string|ItemInterface Property values
194
     * @throws InvalidArgumentException If no property name was given
195
     * @throws OutOfBoundsException If none of the requested properties is known
196
     * @api
197
     */
198 2
    public function getFirstProperty($name, $profile = null)
199
    {
200
        /** @var ProfiledNamesList $properties */
201 2
        $properties = ProfiledNamesFactory::createFromArguments(func_get_args());
202
203
        // Prepare a default exception
204 2
        $e = new OutOfBoundsException(
205 2
            OutOfBoundsException::NO_MATCHING_PROPERTIES_STR,
206 2
            OutOfBoundsException::NO_MATCHING_PROPERTIES
207
        );
208
209
        // Run through all properties
210 2
        foreach ($properties as $property) {
211
            try {
212 2
                return $this->getProperty($property->name, $property->profile);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->getProperty($prop...e, $property->profile); of type array|Jkphl\Micrometa\Po...Contract\ValueInterface adds the type Jkphl\Micrometa\Applicat...Contract\ValueInterface to the return on line 212 which is incompatible with the return type declared by the interface Jkphl\Micrometa\Ports\It...rface::getFirstProperty of type array|string|Jkphl\Micro...orts\Item\ItemInterface.
Loading history...
213 1
            } catch (OutOfBoundsException $e) {
214 1
                continue;
215
            }
216
        }
217
218 1
        throw $e;
219
    }
220
221
    /**
222
     * Return all properties
223
     *
224
     * @return PropertyListInterface Properties
225
     * @api
226
     */
227 1
    public function getProperties()
228
    {
229 1
        $propertyList = (new PropertyListFactory())->create();
230 1
        foreach ($this->item->getProperties() as $propertyName => $propertyValues) {
231 1
            $propertyList[$propertyName] = array_map([$this, 'getPropertyValue'], $propertyValues);
232
        }
233 1
        return $propertyList;
234
    }
235
236
    /**
237
     * Return an object representation of the item
238
     *
239
     * @return \stdClass Micro information item
240
     * @api
241
     */
242 2
    public function toObject()
243
    {
244 2
        return $this->item->export();
245
    }
246
247
    /**
248
     * Get the item type
249
     *
250
     * @return \stdClass[] Item type
251
     */
252 1
    public function getType()
253
    {
254 1
        return $this->item->getType();
255
    }
256
257
    /**
258
     * Get the item format
259
     *
260
     * @return int Item format
261
     */
262 1
    public function getFormat()
263
    {
264 1
        return $this->item->getFormat();
265
    }
266
267
    /**
268
     * Get the item ID
269
     *
270
     * @return string Item ID
271
     */
272
    public function getId()
273
    {
274
        return $this->item->getId();
275
    }
276
277
    /**
278
     * Get the item language
279
     *
280
     * @return string Item language
281
     */
282
    public function getLanguage()
283
    {
284
        return $this->item->getLanguage();
285
    }
286
287
    /**
288
     * Return the item value
289
     *
290
     * @return string Item value
291
     */
292
    public function getValue()
293
    {
294
        return $this->item->getValue();
295
    }
296
}
297