Passed
Push — main ( 632f8e...e54bd0 )
by Pranjal
07:07
created

Model::__set()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 3
rs 10
1
<?php
2
declare(strict_types=1);
3
namespace Scrawler\Arca;
4
5
class Model
6
{
7
    private array $properties = array();
8
    private String $table;
9
    private $_id = 0;
10
    private array $__meta = [];
11
    private \Scrawler\Arca\Database $db;
12
    
13
14
    public function __construct(String $name, Database $db)
15
    {
16
        $this->db = $db;
17
        $this->table = $name;
18
        $this->__meta['has_foreign']['oto'] = false;
19
        $this->__meta['has_foreign']['otm'] = false;
20
        $this->__meta['has_foreign']['mtm'] = false;
21
        $this->__meta['is_loaded'] = false;
22
        $this->__meta['foreign_models']['otm'] = [];
23
        $this->__meta['foreign_models']['oto'] = [];
24
        $this->__meta['foreign_models']['mtm'] = [];
25
    }
26
27
    /**
28
     * adds the key to properties
29
     *
30
     * @param String $key
31
     * @param Mixed $val
32
     */
33
    public function __set(string $key, mixed $val): void
34
    {
35
       $this->set($key,$val);
36
    }
37
38
    public function set(string $key,mixed $val): void
39
    {
40
                //bug: fix issue with bool storage
41
                if (gettype($val) == 'boolean') {
42
                    ($val) ? $val = 1 : $val = 0;
43
                }
44
        
45
                if (preg_match('/[A-Z]/', $key)) {
46
                    $parts = preg_split('/(?=[A-Z])/', $key, -1, PREG_SPLIT_NO_EMPTY);
47
                    if (strtolower($parts[0]) == 'own') {
48
                        if (gettype($val) == 'array') {
49
                            array_push($this->__meta['foreign_models']['otm'], $val);
50
                            $this->__meta['has_foreign']['otm'] = true;
51
                        }
52
                        return;
53
                    }
54
                    if (strtolower($parts[0]) == 'shared') {
55
                        if (gettype($val) == 'array') {
56
                            array_push($this->__meta['foreign_models']['mtm'], $val);
57
                            $this->__meta['has_foreign']['mtm'] = true;
58
                        }
59
                        return;
60
                    }
61
                }
62
                if ($val instanceof Model) {
63
                    $this->__meta['has_foreign']['oto'] = true;
64
                    array_push($this->__meta['foreign_models']['oto'], $val);
65
                    return;
66
                }
67
        
68
                $this->properties[$key] = $val;
69
    }
70
71
    public function __get(string $key): mixed
72
    {
73
         return $this->get($key);  
74
    }
75
76
    public function get(string $key){
77
78
        if (preg_match('/[A-Z]/', $key)) {
79
            $parts = preg_split('/(?=[A-Z])/', $key, -1, PREG_SPLIT_NO_EMPTY);
80
            if (strtolower($parts[0]) == 'own') {
81
                if (strtolower($parts[2])  == 'list') {
82
                    return $this->db->find(strtolower($parts[1]))->where($this->getName() . '_id = "' . $this->_id.'"')->get();
83
                }
84
            }
85
            if (strtolower($parts[0]) == 'shared') {
86
                if (strtolower($parts[2])  == 'list') {
87
                    $rel_table = $this->db->getTableManager()->tableExists($this->table.'_'.strtolower($parts[1])) ? $this->table.'_'.strtolower($parts[1]) : strtolower($parts[1]).'_'.$this->table;
88
                    $relations = $this->db->find($rel_table)->where($this->getName() . '_id = "' . $this->_id.'"')->get();
89
                    $rel_ids = '';
90
                    foreach ($relations as $relation) {
91
                        $key = strtolower($parts[1]) . '_id';
92
                        $rel_ids .= "'".$relation->$key . "',";
93
                    }
94
                    $rel_ids = substr($rel_ids, 0, -1);
95
                    return $this->db->find(strtolower($parts[1]))->where('id IN ('.$rel_ids.')')->get();
96
                }
97
            }
98
        }
99
100
        if (array_key_exists($key, $this->properties)) {
101
            return $this->properties[$key];
102
        }
103
        
104
        if (array_key_exists($key.'_id', $this->properties)) {
105
            return $this->db->get($key, $this->properties[$key.'_id']);
106
        }
107
        
108
        throw new Exception\KeyNotFoundException();
109
    }
110
111
    /**
112
     * Unset a property from model
113
     *
114
     * @param string $key
115
     */
116
    public function __unset(string $key): void
117
    {
118
        unset($this->properties[$key]);
119
    }
120
121
    /**
122
     * Check if property exists
123
     *
124
     * @param string $key
125
     * @return boolean
126
     */
127
    public function __isset(string $key): bool
128
    {
129
       return $this->isset($key);
130
    }
131
132
    /**
133
     * Check if property exists
134
     *
135
     * @param string $key
136
     * @return boolean
137
     */
138
    public function isset(string $key): bool
139
    {
140
        return array_key_exists($key, $this->properties);
141
    }
142
    
143
    /**
144
     * Set all properties of model via array
145
     *
146
     * @param array $properties
147
     * @return Model
148
     */
149
    public function setProperties(array $properties) : Model
150
    {
151
        $this->properties = array_merge($this->properties, $properties);
152
        if (isset($properties['id'])) {
153
            $this->_id = $properties['id'];
154
        }
155
        return $this;
156
    }
157
158
    /**
159
     * Get all properties in array form
160
     *
161
     * @return array
162
     */
163
    public function getProperties() : array
164
    {
165
        return $this->properties;
166
    }
167
168
    /**
169
     * Get all properties in array form
170
     *
171
     * @return array
172
     */
173
    public function toArray() : array
174
    {
175
        return $this->getProperties();
176
    }
177
178
    /**
179
     *  check if model loaded from db
180
     * @return array
181
     */
182
    public function isLoaded() : bool
183
    {
184
        return  $this->__meta['is_loaded'];
185
    }
186
187
    /**
188
     * call when model is loaded from database
189
     *
190
     * @return Model
191
     */
192
    public function setLoaded() : Model
193
    {
194
        $this->__meta['is_loaded'] = true;
195
        return $this;
196
    }
197
    
198
    /**
199
     * Get current table name of model
200
     *
201
     * @return String
202
     */
203
    public function getName() : String
204
    {
205
        return $this->table;
206
    }
207
208
    /**
209
     * Get current model Id or UUID
210
     *
211
     * @return mixed
212
     */
213
    public function getId() : mixed
214
    {
215
        return $this->_id;
216
    }
217
218
219
    /**
220
     * Save model to database
221
     *
222
     * @return mixed returns int when id is used else returns string for uuid
223
     */
224
    public function save() : mixed
225
    {
226
        $id = $this->db->save($this);
227
        $this->id = $id;
0 ignored issues
show
Bug Best Practice introduced by
The property id does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
228
        $this->_id = $id;
229
        return $id;
230
    }
231
232
    /**
233
     * Delete model data
234
     */
235
    public function delete() : void
236
    {
237
        $this->db->delete($this);
238
    }
239
240
    /**
241
     * converts model into json object
242
     * @return string
243
     */
244
    public function toString() : string
245
    {
246
        return \json_encode($this->properties);
247
    }
248
249
    /**
250
     *
251
     * @return string
252
     */
253
    public function __toString() : string
254
    {
255
        return $this->toString();
256
    }
257
258
259
    /**
260
     * Function used to compare to models
261
     *
262
     * @param self $other
263
     * @return boolean
264
     */
265
    public function equals(self $other): bool
266
    {
267
        return ($this->getId() === $other->getId() && $this->toString() === $other->toString());
268
    }
269
270
    /**
271
     * Check if model has any relations
272
     *
273
     * @return boolean
274
     */
275
    public function hasForeign($type) : bool
276
    {
277
        return $this->__meta['has_foreign'][$type];
278
    }
279
280
    /**
281
     * returns all relational models
282
     *
283
     * @return array
284
     */
285
    public function getForeignModels($type): array
286
    {
287
        return $this->__meta['foreign_models'][$type];
288
    }
289
}
290