1: | <?php |
2: | |
3: | |
4: | |
5: | |
6: | |
7: | |
8: | namespace Aurora\System\Classes; |
9: | |
10: | use Aurora\System\EventEmitter; |
11: | use Aurora\System\Validator; |
12: | use Illuminate\Database\Eloquent\Model as Eloquent; |
13: | use Illuminate\Database\Eloquent\Relations\BelongsTo; |
14: | |
15: | class Model extends Eloquent |
16: | { |
17: | use DisabledModulesTrait; |
18: | |
19: | |
20: | |
21: | |
22: | |
23: | |
24: | protected $moduleName = ''; |
25: | |
26: | |
27: | |
28: | |
29: | |
30: | |
31: | protected $primaryKey = 'Id'; |
32: | |
33: | |
34: | |
35: | |
36: | |
37: | |
38: | protected $parentType = null; |
39: | |
40: | |
41: | |
42: | |
43: | |
44: | |
45: | protected $parentKey = null; |
46: | |
47: | |
48: | |
49: | |
50: | |
51: | protected $foreignModel = ''; |
52: | |
53: | |
54: | |
55: | |
56: | |
57: | protected $foreignModelIdColumn = ''; |
58: | |
59: | |
60: | |
61: | |
62: | |
63: | |
64: | protected $parentInheritedAttributes = []; |
65: | |
66: | |
67: | |
68: | |
69: | protected $validationRules = []; |
70: | |
71: | |
72: | |
73: | |
74: | |
75: | |
76: | public const CREATED_AT = 'CreatedAt'; |
77: | |
78: | |
79: | |
80: | |
81: | |
82: | |
83: | public const UPDATED_AT = 'UpdatedAt'; |
84: | |
85: | protected function castAttribute($key, $value) |
86: | { |
87: | if (is_null($value)) { |
88: | switch ($this->getCastType($key)) { |
89: | case 'array': |
90: | $value = []; |
91: | break; |
92: | |
93: | case 'string': |
94: | $value = ''; |
95: | break; |
96: | |
97: | case 'boolean': |
98: | $value = false; |
99: | break; |
100: | } |
101: | |
102: | return $value; |
103: | } |
104: | |
105: | return parent::castAttribute($key, $value); |
106: | } |
107: | |
108: | public function getInheritedAttributes() |
109: | { |
110: | $aArgs = ['ClassName' => get_class($this)]; |
111: | $aResult = []; |
112: | |
113: | \Aurora\System\EventEmitter::getInstance()->emit($this->moduleName, 'getInheritedAttributes', $aArgs, $aResult); |
114: | return $aResult; |
115: | } |
116: | |
117: | |
118: | |
119: | |
120: | |
121: | public function isInheritedAttribute($key) |
122: | { |
123: | $aInheritedAttributes = $this->getInheritedAttributes(); |
124: | return in_array($key, $aInheritedAttributes); |
125: | } |
126: | |
127: | |
128: | |
129: | |
130: | |
131: | public function getInheritedValue($key) |
132: | { |
133: | $value = null; |
134: | $parent = $this->parent(); |
135: | if ($parent instanceof BelongsTo && isset($this->parent)) { |
136: | $value = $this->parent->$key; |
137: | } |
138: | if ($value === null && is_subclass_of($this->parentType, \Aurora\System\AbstractSettings::class)) { |
139: | if ($this->parentType === \Aurora\System\Settings::class) { |
140: | $value = \Aurora\System\Api::GetSettings()->GetValue($key); |
141: | } |
142: | if ($this->parentType === \Aurora\System\Module\Settings::class) { |
143: | if (strpos($key, '::') !== false) { |
144: | list($moduleName, $key) = \explode('::', $key); |
145: | } else { |
146: | $moduleName = $this->moduleName; |
147: | } |
148: | $oModule = \Aurora\System\Api::GetModule($moduleName); |
149: | if ($oModule instanceof \Aurora\System\Module\AbstractModule) { |
150: | $value = $oModule->getConfig($key, $value); |
151: | } |
152: | } |
153: | } |
154: | |
155: | return $value; |
156: | } |
157: | |
158: | public function getOrphanIds() |
159: | { |
160: | if (!$this->foreignModel || !$this->foreignModelIdColumn) { |
161: | return ['status' => -1, 'message' => 'Foreign field doesn\'t exist']; |
162: | } |
163: | $tableName = $this->getTable(); |
164: | $foreignObject = new $this->foreignModel(); |
165: | $foreignTable = $foreignObject->getTable(); |
166: | $foreignPK = $foreignObject->primaryKey; |
167: | |
168: | $orphanIds = self::pluck($this->primaryKey)->diff( |
169: | self::leftJoin($foreignTable, "$tableName.$this->foreignModelIdColumn", '=', "$foreignTable.$foreignPK")->whereNotNull("$foreignTable.$foreignPK")->pluck("$tableName.$this->primaryKey") |
170: | )->all(); |
171: | |
172: | $message = $orphanIds ? "$tableName table has orphans: " . count($orphanIds) . "." : "Orphans were not found."; |
173: | $oResult = ['status' => $orphanIds ? 1 : 0, 'message' => $message, 'orphansIds' => $orphanIds]; |
174: | |
175: | return $oResult; |
176: | } |
177: | |
178: | |
179: | |
180: | |
181: | |
182: | |
183: | |
184: | |
185: | public function __set($key, $value) |
186: | { |
187: | if (strpos($key, '::') !== false) { |
188: | $this->setExtendedProp($key, $value); |
189: | } else { |
190: | parent::__set($key, $value); |
191: | } |
192: | } |
193: | |
194: | public function getEntityIdAttribute() |
195: | { |
196: | return $this->Id; |
197: | } |
198: | |
199: | |
200: | |
201: | |
202: | |
203: | |
204: | |
205: | public function __get($key) |
206: | { |
207: | $value = parent::__get($key); |
208: | if ($key !== 'Properties') { |
209: | if (isset($this->Properties[$key])) { |
210: | $value = $this->Properties[$key]; |
211: | } |
212: | if ($value === null && $this->isInheritedAttribute($key)) { |
213: | $value = $this->getInheritedValue($key); |
214: | } |
215: | } |
216: | return $value; |
217: | } |
218: | |
219: | |
220: | |
221: | |
222: | |
223: | |
224: | |
225: | public function __isset($key) |
226: | { |
227: | $value = parent::__isset($key); |
228: | if (!$value) { |
229: | $value = isset($this->Properties[$key]); |
230: | } |
231: | |
232: | return $value; |
233: | } |
234: | |
235: | |
236: | |
237: | |
238: | |
239: | |
240: | |
241: | public function __unset($key) |
242: | { |
243: | parent::__unset($key); |
244: | if (isset($this->Properties[$key])) { |
245: | unset($this->Properties[$key]); |
246: | } |
247: | } |
248: | |
249: | public function getExtendedProp($key, $default = null) |
250: | { |
251: | $mResult = null; |
252: | if (isset($this->Properties[$key])) { |
253: | $mResult = $this->Properties[$key]; |
254: | } else { |
255: | $mResult = $default; |
256: | } |
257: | |
258: | return $mResult; |
259: | } |
260: | |
261: | public function setExtendedProp($key, $value) |
262: | { |
263: | $properties = $this->Properties; |
264: | $properties[$key] = $value; |
265: | $this->Properties = $properties; |
266: | } |
267: | |
268: | public function unsetExtendedProp($key) |
269: | { |
270: | $properties = $this->Properties; |
271: | if (isset($properties[$key])) { |
272: | unset($properties[$key]); |
273: | } |
274: | $this->Properties = $properties; |
275: | } |
276: | |
277: | public function setExtendedProps($props) |
278: | { |
279: | $properties = is_array($this->Properties) ? $this->Properties : []; |
280: | $this->Properties = array_merge($properties, $props); |
281: | } |
282: | |
283: | |
284: | |
285: | |
286: | public function parent() |
287: | { |
288: | $result = null; |
289: | if (isset($this->parentType) && is_subclass_of($this->parentType, \Aurora\System\Classes\Model::class)) { |
290: | $result = $this->belongsTo($this->parentType, $this->parentKey, $this->primaryKey); |
291: | } |
292: | |
293: | return $result; |
294: | } |
295: | |
296: | protected function isEncryptAttribute($attributeName) |
297: | { |
298: | $result = false; |
299: | $casts = $this->getCasts(); |
300: | if (isset($casts[$attributeName]) && $casts[$attributeName] === \Aurora\System\Casts\Encrypt::class) { |
301: | $result = true; |
302: | } |
303: | |
304: | return $result; |
305: | } |
306: | |
307: | |
308: | |
309: | |
310: | public function toResponseArray() |
311: | { |
312: | $array = $this->toArray(); |
313: | |
314: | if (!isset($array['UUID'])) { |
315: | $array['UUID'] = ''; |
316: | } |
317: | $array['ParentUUID'] = ''; |
318: | $array['ModuleName'] = $this->moduleName; |
319: | |
320: | $parentInheritedAttributes = $this->getInheritedAttributes(); |
321: | if (count($parentInheritedAttributes) > 0) { |
322: | foreach ($parentInheritedAttributes as $attribute) { |
323: | $value = null; |
324: | if (isset($array[$attribute])) { |
325: | $value = $array[$attribute]; |
326: | } |
327: | if ($value === null) { |
328: | $array[$attribute] = $this->getInheritedValue($attribute); |
329: | } |
330: | } |
331: | } |
332: | if (isset($array['Properties'])) { |
333: | foreach ($array['Properties'] as $key => $value) { |
334: | if ($value !== null) { |
335: | $aArgs = ['Model' => $this, 'PropertyName' => $key]; |
336: | EventEmitter::getInstance()->emit('System', 'CastExtendedProp', $aArgs, $value); |
337: | $array[$key] = $value; |
338: | } |
339: | } |
340: | unset($array['Properties']); |
341: | } |
342: | |
343: | foreach ($array as $key => $value) { |
344: | if ($this->isEncryptAttribute($key)) { |
345: | $array[$key] = '*****'; |
346: | } |
347: | } |
348: | |
349: | return $array; |
350: | } |
351: | |
352: | public function validate() |
353: | { |
354: | Validator::validate($this->getAttributes(), $this->validationRules); |
355: | |
356: | return true; |
357: | } |
358: | |
359: | |
360: | |
361: | |
362: | |
363: | |
364: | |
365: | |
366: | |
367: | public function generateUUID() |
368: | { |
369: | return sprintf( |
370: | '%04x%04x-%04x-%04x-%04x-%04x%04x%04x', |
371: | |
372: | |
373: | mt_rand(0, 0xffff), |
374: | mt_rand(0, 0xffff), |
375: | |
376: | |
377: | mt_rand(0, 0xffff), |
378: | |
379: | |
380: | |
381: | mt_rand(0, 0x0fff) | 0x4000, |
382: | |
383: | |
384: | |
385: | |
386: | mt_rand(0, 0x3fff) | 0x8000, |
387: | |
388: | |
389: | mt_rand(0, 0xffff), |
390: | mt_rand(0, 0xffff), |
391: | mt_rand(0, 0xffff) |
392: | ); |
393: | } |
394: | |
395: | |
396: | |
397: | |
398: | |
399: | |
400: | |
401: | public function validateUUID($uuid) |
402: | { |
403: | return preg_match( |
404: | '/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/i', |
405: | $uuid |
406: | ) == true; |
407: | } |
408: | |
409: | |
410: | |
411: | |
412: | |
413: | public function populate($aProperties) |
414: | { |
415: | foreach ($aProperties as $key => $value) { |
416: | if (in_array($key, $this->fillable) || strpos($key, '::') !== false) { |
417: | $this->$key = $value; |
418: | } |
419: | } |
420: | } |
421: | |
422: | |
423: | |
424: | |
425: | |
426: | public function getName() |
427: | { |
428: | return \get_class($this); |
429: | } |
430: | |
431: | |
432: | |
433: | |
434: | |
435: | |
436: | |
437: | public function save(array $options = []) |
438: | { |
439: | if ($this->validate()) { |
440: | return parent::save($options); |
441: | } |
442: | |
443: | return false; |
444: | } |
445: | } |
446: | |