Passed
Push — master ( 0756fe...706dc7 )
by Arthur
14:47
created

TypeCaster::castCollection()   A

Complexity

Conditions 5
Paths 9

Size

Total Lines 25
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 12
dl 0
loc 25
rs 9.5555
c 0
b 0
f 0
cc 5
nc 9
nop 1
1
<?php
2
3
4
namespace Larapie\DataTransferObject\Casters;
5
6
7
use Larapie\DataTransferObject\Contracts\DtoContract;
8
use Larapie\DataTransferObject\PropertyType;
9
10
class TypeCaster
11
{
12
    /**
13
     * @var PropertyType $type
14
     */
15
    protected $type;
16
17
    /**
18
     * TypeCaster constructor.
19
     * @param PropertyType $type
20
     */
21
    public function __construct(PropertyType $type)
22
    {
23
        $this->type = $type;
24
    }
25
26
    public function cast($value)
27
    {
28
        $value = $this->castDto($value);
29
30
        if (is_array($value)) {
31
            $value = $this->shouldBeCastToCollection($value) ? $this->castCollection($value) : $this->castDto($value);
32
        }
33
        return $value;
34
    }
35
36
37
    protected function castDto($value)
38
    {
39
        foreach ($this->type->getTypes() as $type) {
40
            if (is_subclass_of($type, DtoContract::class)) {
41
                if (is_array($value))
42
                    return new $type($value);
43
            }
44
        }
45
        return $value;
46
    }
47
48
    protected function castCollection(array $values)
49
    {
50
        $castTo = null;
51
52
        foreach ($this->type->getArrayTypes() as $type) {
53
            if (!is_subclass_of($type, DtoContract::class)) {
54
                continue;
55
            }
56
57
            $castTo = $type;
58
59
            break;
60
        }
61
62
        if (!$castTo) {
63
            return $values;
64
        }
65
66
        $casts = [];
67
68
        foreach ($values as $value) {
69
            $casts[] = new $castTo($value);
70
        }
71
72
        return $casts;
73
    }
74
75
    protected function shouldBeCastToCollection(array $values): bool
76
    {
77
        if (empty($values)) {
78
            return false;
79
        }
80
81
        foreach ($values as $key => $value) {
82
            if (is_string($key)) {
83
                return false;
84
            }
85
86
            if (!is_array($value)) {
87
                return false;
88
            }
89
        }
90
91
        return true;
92
    }
93
}