Completed
Push — feature/controller ( 08e254...534c3a )
by René
09:48
created

Entity::toArray()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 19
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 4

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 19
ccs 10
cts 10
cp 1
rs 9.2
cc 4
eloc 10
nc 3
nop 1
crap 4
1
<?php
2
3
namespace Zortje\MVC\Model\Table\Entity;
4
5
use Zortje\MVC\Model\Table\Entity\Exception\InvalidEntityPropertyException;
6
use Zortje\MVC\Model\Table\Entity\Exception\InvalidValueTypeForEntityPropertyException;
7
8
/**
9
 * Class Entity
10
 *
11
 * @package Zortje\MVC\Model\Table\Entity
12
 */
13
abstract class Entity
14
{
15
16
    /**
17
     * @var array Columns
18
     */
19
    protected static $columns = [];
20
21
    /**
22
     * @var array Internal entity properties
23
     */
24
    protected $properties = [];
25
26
    /**
27
     * Get entity columns
28
     *
29
     * @return array Entity columns
30
     */
31 1
    public static function getColumns()
32
    {
33 1
        $columns = array_merge([
34
            'id' => 'integer'
35 1
        ], static::$columns);
36
37 1
        $columns = array_merge($columns, [
38 1
            'modified' => 'DateTime',
39
            'created'  => 'DateTime'
40
        ]);
41
42 1
        return $columns;
43
    }
44
45
    /**
46
     * Set entity property
47
     *
48
     * @param string                                          $key   Entity property name
49
     * @param object|integer|double|string|array|boolean|null $value Entity property value
50
     *
51
     * @throws InvalidEntityPropertyException If entity does not have that property
52
     * @throws InvalidValueTypeForEntityPropertyException If value is of the wrong type
53
     */
54 2 View Code Duplication
    public function set($key, $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...
55
    {
56 2
        if (!isset(self::getColumns()[$key])) {
57 1
            throw new InvalidEntityPropertyException([get_class($this), $key]);
58
        }
59
60 2
        $this->properties[$key] = $this->validatePropertyForValue($key, $value);
61 2
    }
62
63
    /**
64
     * Get entity property
65
     *
66
     * @param string $key Entity property
67
     *
68
     * @return object|integer|double|string|array|boolean|null Entity property value for given key
69
     *
70
     * @throws InvalidEntityPropertyException If entity does not have that property
71
     */
72 2 View Code Duplication
    public function get($key)
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...
73
    {
74 2
        if (!isset(self::getColumns()[$key])) {
75 1
            throw new InvalidEntityPropertyException([get_class($this), $key]);
76
        }
77
78 1
        return $this->properties[$key];
79
    }
80
81
    /**
82
     * Return table structur for saving
83
     * Example: `['table_field_name' => $this->fieldName]`
84
     *
85
     * @param bool $includeId Should the ID column be included
86
     *
87
     * @return array
88
     */
89 2
    public function toArray($includeId)
90
    {
91 2
        $array = [];
92
93 2
        foreach (self::getColumns() as $column => $type) {
94 2
            if ($column === 'id' && !$includeId) {
95 1
                continue;
96
            }
97
98 2
            $property = new EntityProperty($type);
99
100 2
            $value = $this->get($column);
101 2
            $value = $property->formatValueForDatabase($value);
102
103 2
            $array[":$column"] = $value;
104
        }
105
106 2
        return $array;
107
    }
108
109
    /**
110
     * Validate property for given value
111
     *
112
     * @param string $key   Entity property name
113
     * @param mixed  $value Entity property value
114
     *
115
     * @return object|integer|double|string|array|boolean|null Value
116
     *
117
     * @throws InvalidEntityPropertyException If entity does not have that property
118
     * @throws InvalidValueTypeForEntityPropertyException If value is of the wrong type
119
     */
120 3
    protected function validatePropertyForValue($key, $value)
121
    {
122 3
        if (!isset(self::getColumns()[$key])) {
123 1
            throw new InvalidEntityPropertyException([get_class($this), $key]);
124
        }
125
126
        /**
127
         * Allow NULL
128
         */
129 3
        if ($value !== null) {
130 3
            $valueType = gettype($value);
131
132
            /**
133
             * Get class if object
134
             */
135 3
            if ($valueType === 'object') {
136 3
                $valueType = get_class($value);
137
            }
138
139
            /**
140
             * Handle alias types
141
             */
142 3
            $columnType = self::getColumns()[$key];
143
144
            switch ($columnType) {
145 3
                case 'Date':
146 3
                    $columnType = 'DateTime';
147 3
                    break;
148
            }
149
150
            /**
151
             * Validate type
152
             */
153 3
            if ($valueType !== $columnType) {
154 1
                throw new InvalidValueTypeForEntityPropertyException([
155 1
                    get_class($this),
156 1
                    $key,
157 1
                    $valueType,
158 1
                    $columnType
159
                ]);
160
            }
161
        }
162
163 3
        return $value;
164
    }
165
166
    /**
167
     * @param int       $id
168
     * @param \DateTime $modified
169
     * @param \DateTime $created
170
     */
171
    public function __construct($id, \DateTime $modified, \DateTime $created)
172
    {
173
        $this->set('id', $id);
174
        $this->set('modified', $modified);
175
        $this->set('created', $created);
176
    }
177
}
178