Passed
Push — develop ( 80c72e...34afcd )
by Jens
10:32
created

Attribute::getValueAsLocalizedStringSet()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 4
cts 4
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 0
crap 1
1
<?php
2
/**
3
 * @author @jayS-de <[email protected]>
4
 * @created: 04.02.15, 17:46
5
 */
6
7
namespace Commercetools\Core\Model\Common;
8
9
use Commercetools\Core\Model\ProductType\AttributeDefinition;
10
use Commercetools\Core\Model\ProductType\AttributeType;
11
12
/**
13
 * @package Commercetools\Core\Model\Common
14
 * @link https://dev.commercetools.com/http-api-projects-products.html#attribute
15
 * @method string getName()
16
 * @method Attribute setName(string $name = null)
17
 * @method mixed getValue()
18
 * @method Attribute setValue($value = null)
19
 */
20
class Attribute extends JsonObject
21
{
22
    // identifiers for the Api Product Attribute Types:
23
    const T_UNKNOWN = 'unknown';  // zero, should evaluate to false
24
25
    const PROP_VALUE = "value";
26
    const PROP_KEY = "key";
27
    const PROP_NAME = "name";
28
    const PROP_CURRENCY_CODE = "currencyCode";
29
    const PROP_CENT_AMOUNT = "centAmount";
30
    const PROP_TYPE_ID = "typeId";
31
    const PROP_ID = "id";
32
    const PROP_LABEL = "label";
33
34
    const API_BOOL = 'boolean';
35
    const API_NUMBER = 'number';
36
    const API_TEXT = 'text';
37
    const API_LTEXT = 'ltext';
38
    const API_LENUM = 'lenum';
39
    const API_ENUM = 'enum';
40
    const API_MONEY = 'money';
41
    const API_DATE = 'date';
42
    const API_TIME = 'time';
43
    const API_DATETIME = 'datetime';
44
    const API_SET = 'set';
45
    const API_NESTED = 'nested';
46
    const API_REFERENCE = 'reference';
47
48
    protected static $types = [];
49
50 48
    public function fieldDefinitions()
51
    {
52
        return [
53 48
            static::PROP_NAME => [static::TYPE => 'string'],
54 48
            static::PROP_VALUE => [],
55
        ];
56
    }
57
58 48
    public function fieldDefinition($field)
59
    {
60 48
        if ($field == static::PROP_VALUE) {
61 47
            if (isset(static::$types[$this->getName()])) {
62 40
                $fieldDefinition = static::$types[$this->getName()];
63 40
                if (!$fieldDefinition instanceof AttributeDefinition) {
64
                    return null;
65
                }
66 40
                $fieldType = $fieldDefinition->getType();
67 40
                if (!$fieldType instanceof AttributeType) {
68
                    return null;
69
                }
70 40
                return $fieldType->fieldTypeDefinition();
71
            }
72 8
            return null;
73
        }
74 48
        return parent::fieldDefinition($field);
75
    }
76
77
    /**
78
     * @param $attributeName
79
     * @param $value
80
     * @return mixed
81
     */
82 40
    protected function getApiType($attributeName, $value)
83
    {
84 40
        if (isset(static::$types[$attributeName])) {
85 25
            return static::$types[$attributeName];
86
        }
87
88 15
        $apiType = $this->guessApiType($value);
89 15
        $elementType = null;
90 15
        if ($apiType == static::API_SET) {
91 2
            $elementType = $this->guessApiType(current($value));
92
        }
93 15
        $this->setApiType($attributeName, $apiType, $elementType);
94
95 15
        return static::$types[$attributeName];
96
    }
97
98
    /**
99
     * @param AttributeDefinition $definition
100
     * @return $this
101
     */
102 40
    public function setAttributeDefinition(AttributeDefinition $definition)
103
    {
104 40
        static::$types[$definition->getName()] = $definition;
105
106 40
        return $this;
107
    }
108
109
    /**
110
     * @param string $field
111
     */
112 41
    protected function initialize($field)
113
    {
114 41
        if ($field == static::PROP_VALUE) {
115 40
            $name = $this->getRaw(static::PROP_NAME);
116 40
            $value = $this->getRaw(static::PROP_VALUE);
117 40
            $this->getApiType($name, $value);
118
        }
119 41
        parent::initialize($field);
120 41
    }
121
122 36
    private function setApiType($attributeName, $valueType, $elementType = null)
123
    {
124 36
        if (!isset(static::$types[$attributeName])) {
125 36
            $definition = AttributeDefinition::of($this->getContextCallback());
126 36
            $definition->setName($attributeName);
127 36
            $definition->setType(AttributeType::fromArray(['name' => $valueType]));
128
129 36
            if ($valueType == static::API_SET && $elementType != null) {
130 13
                $definition->getType()->setElementType(AttributeType::fromArray(['name' => $elementType]));
0 ignored issues
show
Documentation Bug introduced by
The method setElementType does not exist on object<Commercetools\Cor...ductType\AttributeType>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
131
            }
132 36
            $this->setAttributeDefinition($definition);
133
        }
134 36
    }
135
136
    /**
137
     * @return bool
138
     */
139 1
    public function getValueAsBool()
140
    {
141 1
        $attributeName = $this->getName();
142 1
        $this->setApiType($attributeName, static::API_BOOL);
143 1
        return $this->getValue();
144
    }
145
146
    /**
147
     * @return int|float
148
     */
149 2
    public function getValueAsNumber()
150
    {
151 2
        $attributeName = $this->getName();
152 2
        $this->setApiType($attributeName, static::API_NUMBER);
153 2
        return $this->getValue();
154
    }
155
156
    /**
157
     * @return string
158
     */
159 1
    public function getValueAsString()
160
    {
161 1
        $attributeName = $this->getName();
162 1
        $this->setApiType($attributeName, static::API_TEXT);
163 1
        return $this->getValue();
164
    }
165
166
    /**
167
     * @return LocalizedString
168
     */
169 1
    public function getValueAsLocalizedString()
170
    {
171 1
        $attributeName = $this->getName();
172 1
        $this->setApiType($attributeName, static::API_LTEXT);
173 1
        return $this->getValue();
174
    }
175
176
    /**
177
     * @return LocalizedEnum
178
     */
179 1
    public function getValueAsLocalizedEnum()
180
    {
181 1
        $attributeName = $this->getName();
182 1
        $this->setApiType($attributeName, static::API_LENUM);
183 1
        return $this->getValue();
184
    }
185
186
    /**
187
     * @return Enum
188
     */
189 1
    public function getValueAsEnum()
190
    {
191 1
        $attributeName = $this->getName();
192 1
        $this->setApiType($attributeName, static::API_ENUM);
193 1
        return $this->getValue();
194
    }
195
196
    /**
197
     * @return Money
198
     */
199 1
    public function getValueAsMoney()
200
    {
201 1
        $attributeName = $this->getName();
202 1
        $this->setApiType($attributeName, static::API_MONEY);
203 1
        return $this->getValue();
204
    }
205
206
    /**
207
     * @return DateDecorator
208
     */
209
    public function getValueAsDate()
210
    {
211
        $attributeName = $this->getName();
212
        $this->setApiType($attributeName, static::API_DATE);
213
        return $this->getValue();
214
    }
215
216
    /**
217
     * @return TimeDecorator
218
     */
219
    public function getValueAsTime()
220
    {
221
        $attributeName = $this->getName();
222
        $this->setApiType($attributeName, static::API_TIME);
223
        return $this->getValue();
224
    }
225
226
    /**
227
     * @return DateTimeDecorator
228
     */
229
    public function getValueAsDateTime()
230
    {
231
        $attributeName = $this->getName();
232
        $this->setApiType($attributeName, static::API_DATETIME);
233
        return $this->getValue();
234
    }
235
236
    /**
237
     * @return AttributeCollection
238
     */
239 1
    public function getValueAsNested()
240
    {
241 1
        $attributeName = $this->getName();
242 1
        $this->setApiType($attributeName, static::API_NESTED);
243 1
        return $this->getValue();
244
    }
245
246
    /**
247
     * @return Reference
248
     */
249 1
    public function getValueAsReference()
250
    {
251 1
        $attributeName = $this->getName();
252 1
        $this->setApiType($attributeName, static::API_REFERENCE);
253 1
        return $this->getValue();
254
    }
255
256
    /**
257
     * @return Set
258
     */
259 1
    public function getValueAsBoolSet()
260
    {
261 1
        $attributeName = $this->getName();
262 1
        $this->setApiType($attributeName, static::API_SET, static::API_BOOL);
263 1
        return $this->getValue();
264
    }
265
266
    /**
267
     * @return Set
268
     */
269 2
    public function getValueAsNumberSet()
270
    {
271 2
        $attributeName = $this->getName();
272 2
        $this->setApiType($attributeName, static::API_SET, static::API_NUMBER);
273 2
        return $this->getValue();
274
    }
275
276
    /**
277
     * @return Set
278
     */
279 1
    public function getValueAsStringSet()
280
    {
281 1
        $attributeName = $this->getName();
282 1
        $this->setApiType($attributeName, static::API_SET, static::API_TEXT);
283 1
        return $this->getValue();
284
    }
285
286
    /**
287
     * @return Set
288
     */
289 1
    public function getValueAsLocalizedStringSet()
290
    {
291 1
        $attributeName = $this->getName();
292 1
        $this->setApiType($attributeName, static::API_SET, static::API_LTEXT);
293 1
        return $this->getValue();
294
    }
295
296
    /**
297
     * @return Set
298
     */
299 1
    public function getValueAsLocalizedEnumSet()
300
    {
301 1
        $attributeName = $this->getName();
302 1
        $this->setApiType($attributeName, static::API_SET, static::API_LENUM);
303 1
        return $this->getValue();
304
    }
305
306
    /**
307
     * @return Set
308
     */
309 2
    public function getValueAsEnumSet()
310
    {
311 2
        $attributeName = $this->getName();
312 2
        $this->setApiType($attributeName, static::API_SET, static::API_ENUM);
313 2
        return $this->getValue();
314
    }
315
316
    /**
317
     * @return Set
318
     */
319 1
    public function getValueAsMoneySet()
320
    {
321 1
        $attributeName = $this->getName();
322 1
        $this->setApiType($attributeName, static::API_SET, static::API_MONEY);
323 1
        return $this->getValue();
324
    }
325
326
    /**
327
     * @return Set
328
     */
329
    public function getValueAsDateSet()
330
    {
331
        $attributeName = $this->getName();
332
        $this->setApiType($attributeName, static::API_SET, static::API_DATE);
333
        return $this->getValue();
334
    }
335
336
    /**
337
     * @return Set
338
     */
339
    public function getValueAsTimeSet()
340
    {
341
        $attributeName = $this->getName();
342
        $this->setApiType($attributeName, static::API_SET, static::API_TIME);
343
        return $this->getValue();
344
    }
345
346
    /**
347
     * @return Set
348
     */
349
    public function getValueAsDateTimeSet()
350
    {
351
        $attributeName = $this->getName();
352
        $this->setApiType($attributeName, static::API_SET, static::API_DATETIME);
353
        return $this->getValue();
354
    }
355
356
    /**
357
     * @return Set
358
     */
359 1
    public function getValueAsNestedSet()
360
    {
361 1
        $attributeName = $this->getName();
362 1
        $this->setApiType($attributeName, static::API_SET, static::API_NESTED);
363 1
        return $this->getValue();
364
    }
365
366
    /**
367
     * @return Set
368
     */
369 1
    public function getValueAsReferenceSet()
370
    {
371 1
        $attributeName = $this->getName();
372 1
        $this->setApiType($attributeName, static::API_SET, static::API_REFERENCE);
373 1
        return $this->getValue();
374
    }
375
376
    /**
377
     * @param $value
378
     * @return string
379
     */
380 15
    protected function guessApiType($value)
381
    {
382
        $map = [
383 15
            'guessUnknown',
384
            'guessBool',
385
            'guessTextLike',
386
            'guessNumber',
387
            'guessEnum',
388
            'guessLocalizedEnum',
389
            'guessMoney',
390
            'guessReference',
391
            'guessLocalizedText',
392
            'guessNested',
393
            'guessSet',
394
        ];
395
396 15
        foreach ($map as $function) {
397 15
            if ($type = $this->$function($value)) {
398 15
                return $type;
399
            }
400
        }
401
402
        return static::T_UNKNOWN;
403
    }
404
405
    /**
406
     * @param $value
407
     * @param string[] $keys
408
     * @return bool
409
     */
410 9
    protected function hasKeys($value, $keys)
411
    {
412 9
        if (!is_array($value)) {
413 1
            return false;
414
        }
415 9
        $intersect = array_intersect_key(array_flip($keys), $value);
416 9
        return (count($intersect) == count($keys));
417
    }
418
419 15
    protected function guessUnknown($value)
420
    {
421 15
        return (!isset($value) ? static::T_UNKNOWN : null);
422
    }
423
424 13
    protected function guessTextLike($value)
425
    {
426 13
        return is_string($value) ? static::API_TEXT : null;
427
    }
428
429 14
    protected function guessBool($value)
430
    {
431 14
        return is_bool($value) ? static::API_BOOL : null;
432
    }
433
434 11
    protected function guessNumber($value)
435
    {
436 11
        return is_numeric($value) ? static::API_NUMBER : null;
437
    }
438
439 9 View Code Duplication
    protected function guessEnum($value)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
440
    {
441 9
        if ($this->hasKeys($value, [static::PROP_KEY, static::PROP_LABEL]) && is_string($value[static::PROP_LABEL])) {
442 2
            return static::API_ENUM;
443
        }
444
445 8
        return null;
446
    }
447
448 8 View Code Duplication
    protected function guessLocalizedEnum($value)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
449
    {
450 8
        if ($this->hasKeys($value, [static::PROP_KEY, static::PROP_LABEL]) && is_array($value[static::PROP_LABEL])) {
451 1
            return static::API_LENUM;
452
        }
453
454 7
        return null;
455
    }
456
457 7 View Code Duplication
    protected function guessMoney($value)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
458
    {
459 7
        if ($this->hasKeys($value, [static::PROP_CENT_AMOUNT, static::PROP_CURRENCY_CODE])) {
460 1
            return static::API_MONEY;
461
        }
462
463 6
        return null;
464
    }
465
466 6 View Code Duplication
    protected function guessReference($value)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
467
    {
468 6
        if ($this->hasKeys($value, [static::PROP_TYPE_ID, static::PROP_ID])) {
469 2
            return static::API_REFERENCE;
470
        }
471
472 4
        return null;
473
    }
474
475 4
    protected function guessLocalizedText($value)
476
    {
477 4
        if (is_array($value) && !is_numeric(key($value))) {
478 1
            return static::API_LTEXT;
479
        }
480
481 3
        return null;
482
    }
483
484 2
    protected function guessSet($value)
485
    {
486 2
        if (is_array($value)) {
487 2
            return static::API_SET;
488
        }
489
490
        return null;
491
    }
492
493 3
    protected function guessNested($value)
494
    {
495 3
        if (is_array($value)) {
496 3
            $first = reset($value);
497 3
            if ($this->hasKeys($first, [static::PROP_NAME, static::PROP_VALUE])) {
498 1
                return static::API_NESTED;
499
            }
500
        }
501
502 2
        return null;
503
    }
504
}
505