Passed
Push — master ( 633df7...87ee59 )
by Fran
03:08
created

Dto::jsonSerialize()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
namespace PSFS\base\dto;
3
4
use PSFS\base\Logger;
5
use PSFS\base\Request;
6
use PSFS\base\Singleton;
7
use PSFS\base\types\helpers\InjectorHelper;
8
9
/**
10
 * Class Dto
11
 * @package PSFS\base\dto
12
 */
13
class Dto extends Singleton implements \JsonSerializable
14
{
15
    public function __construct($hydrate = true)
16
    {
17
        parent::__construct();
18
        if($hydrate) {
19
            $this->fromArray(Request::getInstance()->getData());
20
        }
21
    }
22
23
    /**
24
     * ToArray wrapper
25
     * @return array
26
     */
27
    public function toArray()
28
    {
29
        return $this->__toArray();
30
    }
31
32
    /**
33
     * Convert dto to array representation
34
     * @return array
35
     */
36
    public function __toArray()
37
    {
38
        $dto = array();
39
        try {
40
            $reflectionClass = new \ReflectionClass($this);
41
            $properties = $reflectionClass->getProperties(\ReflectionProperty::IS_PUBLIC);
42
            if (count($properties) > 0) {
43
                /** @var \ReflectionProperty $property */
44
                foreach ($properties as $property) {
45
                    $value = $property->getValue($this);
46
                    if(is_object($value) && method_exists($value, 'toArray')) {
47
                        $dto[$property->getName()] = $value->toArray();
48
                    } else {
49
                        $dto[$property->getName()] = $property->getValue($this);
50
                    }
51
                }
52
            }
53
        } catch (\Exception $e) {
54
            Logger::log(get_class($this) . ': ' . $e->getMessage(), LOG_ERR);
55
        }
56
        return $dto;
57
    }
58
59
    /**
60
     * Convert to string representation
61
     * @return string
62
     */
63
    public function __toString()
64
    {
65
        return get_class($this);
66
    }
67
68
    /**
69
     * @param array $properties
70
     * @param string $key
71
     * @param mixed $value
72
     */
73
    protected function parseDtoField(array $properties, $key, $value = null) {
74
        $type = 'string';
75
        $is_array = false;
76
        if(array_key_exists($key, $properties)) {
77
            $type = $properties[$key];
78
            if(preg_match('/(\[\]|Array)/i', $type)) {
79
                $type = preg_replace('/(\[\]|Array)/i', '', $type);
80
                $is_array = true;
81
            }
82
        }
83
        $reflector = (class_exists($type)) ? new \ReflectionClass($type) : null;
84
        if(null !== $reflector && $reflector->isSubclassOf(Dto::class)) {
85
            if(null !== $value && is_array($value)) {
86
                if($is_array) {
87
                    $this->$key = [];
88
                    foreach($value as $data) {
89
                        if(null !== $data && is_array($data)) {
90
                            $dto = new $type(false);
91
                            $dto->fromArray($data);
92
                            array_push($this->$key, $dto);
93
                        }
94
                    }
95
                } else {
96
                    $this->$key = new $type(false);
97
                    $this->$key->fromArray($value);
98
                }
99
            }
100
        } else {
101
            switch($type) {
102
                default:
103
                case 'string':
104
                    $this->$key = $value;
105
                    break;
106
                case 'integer':
107
                    $this->$key = (integer)$value;
108
                    break;
109
                case 'float':
110
                    $this->$key = (float)$value;
111
                    break;
112
                case 'boolean':
113
                case 'bool':
114
                    $this->$key = (bool)$value;
115
                    break;
116
            }
117
        }
118
    }
119
120
    /**
121
     * Hydrate object from array
122
     * @param array $object
123
     */
124
    public function fromArray(array $object = array())
125
    {
126
        if (count($object) > 0) {
127
            $reflector = new \ReflectionClass($this);
128
            $properties = InjectorHelper::extractProperties($reflector, \ReflectionProperty::IS_PUBLIC, InjectorHelper::VAR_PATTERN);
129
            unset($reflector);
130
            foreach ($object as $key => $value) {
131
                if (property_exists($this, $key) && null !== $value) {
132
                    $this->parseDtoField($properties, $key, $value);
133
                }
134
            }
135
        }
136
    }
137
138
    /**
139
     * @return array|mixed
140
     */
141
    public function jsonSerialize()
142
    {
143
        return $this->toArray();
144
    }
145
}