Passed
Push — main ( b62f34...105729 )
by Pranjal
02:33
created

Model::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

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