Passed
Push — master ( 80bad9...83e37e )
by Vitalijs
01:52
created

DTOBaseBuilder::validateFieldNames()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 4

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 8
ccs 6
cts 6
cp 1
rs 9.2
cc 4
eloc 5
nc 3
nop 1
crap 4
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: vlitvinovs
5
 * Date: 2/8/17
6
 * Time: 4:28 PM
7
 */
8
9
namespace CodinPro\DataTransferObject;
10
11
class DTOBaseBuilder
12
{
13
    /** @property DTOBase $dto */
14
    private $dto;
15
16 42
    public function __construct(DTOBase $dtoBase)
17
    {
18 42
        $this->dto = $dtoBase;
19 42
    }
20
21
    /**
22
     * Build DTO from given type of data
23
     * @param $data
24
     * @throws \InvalidArgumentException
25
     */
26 42
    public function build($data)
27
    {
28 42
        switch (gettype($data)) {
29 42
            case 'array':
30 33
                $this->buildFromArray($data);
31 31
                break;
32 10
            case 'object':
33 3
                $this->buildFromObject($data);
34 3
                break;
35 8
            case 'string':
36 6
                $this->buildFromJson($data);
37 4
                break;
38
            default:
39 2
                throw new \InvalidArgumentException('DTO can be built from array|object|json, "'.gettype($data).'" given.');
40
        }
41 36
    }
42
    
43
    /**
44
     * Check if given array has given key
45
     * @param $array
46
     * @param $field
47
     */
48 38
    private function arrayHasField($array, $field) {
49 38
        return is_array($array) && isset($array[$field]);
50
    }
51
    
52
    /**
53
     * Check if given object has given property
54
     * @param $object
55
     * @param $field
56
     */
57 37
    private function objectHasField($object, $field) {
58 37
        return is_object($object) && isset($object->{$field});
59
    }
60
    
61
    /**
62
     * Restrict internalDTO* fields in data
63
     * @param $data
64
     */
65 38
    private function validateFieldNames($data) {
66 38
        $restrictedFields = ['internalDTOData', 'internalDTODefault'];
67 38
        foreach ($restrictedFields as $field) {
68 38
            if ($this->arrayHasField($data, $field) || $this->objectHasField($data, $field)) {
69 2
                throw new \InvalidArgumentException('internalDTO* fields are restricted');
70
            }
71
        }
72 36
    }
73
74
    /**
75
     * Build DTO from provided data
76
     * @param $array
77
     */
78 33
    private function buildFromArray($array)
79
    {
80 33
        $this->validateFieldNames($array);
81
        
82 31
        foreach ($this->dto->getDefault() as $key => $value) {            
83 29
            if (isset($array[$key])) {
84 13
                $this->dto[$key] = $array[$key];
85
            } else {
86 29
                $this->dto[$key] = $value;
87
            }
88
        }
89 31
    }
90
91
    /**
92
     * Build DTO from provided data
93
     * @param $object
94
     */
95 6
    private function buildFromObject($object)
96
    {
97 6
        $this->validateFieldNames($object);
98
        
99 6
        foreach ($this->dto->getDefault() as $key => $value) {
100
            
101 6
            if (isset($object->{$key})) {
102 6
                $this->dto[$key] = $object->{$key};
103
            } else {
104 5
                $this->dto[$key] = $value;
105
            }
106
        }
107 6
    }
108
109
    /**
110
     * Try to build from provided string as JSON
111
     * @param string $data
112
     * @throws \InvalidArgumentException
113
     */
114 6
    private function buildFromJson($data)
115
    {
116 6
        $triedToDecodeData = json_decode($data);
117
118 6
        if ($triedToDecodeData !== null) {
119 4
            $this->buildFromObject($triedToDecodeData);
120
        } else {
121 2
            throw new \InvalidArgumentException(
122 2
                'DTO can be built from array|object|json, "'.gettype($data).'" given. Probably tried to pass invalid JSON.'
123
            );
124
        }
125 4
    }
126
}
127