Completed
Push — v2 ( dad8a3...5e546d )
by Joschi
06:58
created

Item   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 182
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
dl 0
loc 182
rs 10
c 0
b 0
f 0
ccs 48
cts 48
cp 1
wmc 20
lcom 1
cbo 3

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 3
A validateTypes() 0 14 2
B validateProperties() 0 25 5
B validatePropertyValues() 0 22 4
A getType() 0 4 1
A getId() 0 4 1
A getProperties() 0 4 1
A getProperty() 0 12 2
A isEmpty() 0 4 1
1
<?php
2
3
/**
4
 * micrometa
5
 *
6
 * @category Jkphl
7
 * @package Jkphl\Micrometa
8
 * @subpackage Jkphl\Micrometa\Domain\Miom
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\Domain\Item;
38
39
use Jkphl\Micrometa\Domain\Exceptions\InvalidArgumentException;
40
use Jkphl\Micrometa\Domain\Exceptions\OutOfBoundsException;
41
use Jkphl\Micrometa\Domain\Value\ValueInterface;
42
43
/**
44
 * Micro information item
45
 *
46
 * @package Jkphl\Micrometa
47
 * @subpackage Jkphl\Micrometa\Domain
48
 */
49
class Item implements ItemInterface
50
{
51
    /**
52
     * Item type(s)
53
     *
54
     * @var string[]
55
     */
56
    protected $type;
57
58
    /**
59
     * Item properties
60
     *
61
     * @var array[]
62
     */
63
    protected $properties;
64
65
    /**
66
     * Item ID
67
     *
68
     * @var string
69
     */
70
    protected $itemId;
71
72
    /**
73
     * Item constructor
74
     *
75
     * @param string|array $type Item type(s)
76
     * @param array[] $properties Item properties
77
     * @param string|null $itemId Item id
78
     */
79 21
    public function __construct($type, array $properties = [], $itemId = null)
80
    {
81 21
        $this->type = $this->validateTypes(is_array($type) ? $type : [$type]);
82 20
        $this->properties = $this->validateProperties($properties);
83 18
        $this->itemId = trim($itemId) ?: null;
84 18
    }
85
86
    /**
87
     * Validate and sanitize the item types
88
     *
89
     * @param array $types Item types
90
     * @return array Validated item types
91
     * @throws InvalidArgumentException If there are no valid types
92
     */
93 21
    protected function validateTypes(array $types)
94
    {
95 21
        $nonEmptyTypes = array_filter(array_map('trim', $types));
96
97
        // If there are no valid types
98 21
        if (!count($nonEmptyTypes)) {
99 1
            throw new InvalidArgumentException(
100 1
                InvalidArgumentException::EMPTY_TYPES_STR,
101 1
                InvalidArgumentException::EMPTY_TYPES
102
            );
103
        }
104
105 20
        return array_values($nonEmptyTypes);
106
    }
107
108
    /**
109
     * Validate the item properties
110
     *
111
     * @param array $properties Item properties
112
     * @return array Validated item properties
113
     * @throws InvalidArgumentException If the property name is empty
114
     */
115 20
    protected function validateProperties(array $properties)
116
    {
117 20
        $nonEmptyProperties = [];
118
119
        // Run through all properties
120 20
        foreach ($properties as $name => $values) {
121 12
            if ($values) {
122 12
                $propertyName = trim($name);
123
124
                // If the property name is empty
125 12
                if (!strlen($propertyName)) {
126 1
                    throw new InvalidArgumentException(
127 1
                        InvalidArgumentException::EMPTY_PROPERTY_NAME_STR,
128 1
                        InvalidArgumentException::EMPTY_PROPERTY_NAME
129
                    );
130
                }
131
132 11
                $nonEmptyProperties[$propertyName] = $this->validatePropertyValues(
133 11
                    is_array($values) ? $values : [$values]
134
                );
135
            }
136
        }
137
138 18
        return $nonEmptyProperties;
139
    }
140
141
    /**
142
     * Validate a list of property values
143
     *
144
     * @param array $values Property values
145
     * @return array Validated property values
146
     * @throws InvalidArgumentException If the value is not a nested item
147
     */
148 11
    protected function validatePropertyValues(array $values)
149
    {
150 11
        $nonEmptyPropertyValues = [];
151
152
        // Run through all property values
153
        /** @var ValueInterface $value */
154 11
        foreach ($values as $value) {
155
            // If the value is not a nested item
156 11
            if (!($value instanceof ValueInterface)) {
157 1
                throw new InvalidArgumentException(
158 1
                    sprintf(InvalidArgumentException::INVALID_PROPERTY_VALUE_STR, gettype($value)),
159 1
                    InvalidArgumentException::INVALID_PROPERTY_VALUE
160
                );
161
            }
162
163 10
            if (!$value->isEmpty()) {
164 10
                $nonEmptyPropertyValues[] = $value;
165
            }
166
        }
167
168 10
        return $nonEmptyPropertyValues;
169
    }
170
171
    /**
172
     * Return the item types
173
     *
174
     * @return string[] Item types
175
     */
176 12
    public function getType()
177
    {
178 12
        return $this->type;
179
    }
180
181
    /**
182
     * Return the item ID (if any)
183
     *
184
     * @return string|null Item id
185
     */
186 11
    public function getId()
187
    {
188 11
        return $this->itemId;
189
    }
190
191
    /**
192
     * Return all item properties
193
     *
194
     * @return array[] Item properties list
195
     */
196 12
    public function getProperties()
197
    {
198 12
        return $this->properties;
199
    }
200
201
    /**
202
     * Return the values of a particular property
203
     *
204
     * @param string $name Property name
205
     * @return array Item property values
206
     * @throws OutOfBoundsException If the property is unknown
207
     */
208 2
    public function getProperty($name)
209
    {
210
        // If the property is unknown
211 2
        if (!isset($this->properties[$name])) {
212 1
            throw new OutOfBoundsException(
213 1
                sprintf(OutOfBoundsException::UNKNOWN_PROPERTY_NAME_STR, $name),
214 1
                OutOfBoundsException::UNKNOWN_PROPERTY_NAME
215
            );
216
        }
217
218 1
        return $this->properties[$name];
219
    }
220
221
    /**
222
     * Return whether the value should be considered empty
223
     *
224
     * @return boolean Value is empty
225
     */
226 4
    public function isEmpty()
227
    {
228 4
        return false;
229
    }
230
}
231