| @@ -1,10 +1,81 @@ | ||
| 1 | 1 | <?php |
| 2 | 2 | |
| 3 | 3 | namespace FluentBoards\App\Models; |
| 4 | 4 | |
| 5 | +use DateTimeInterface; | |
| 5 | 6 | use FluentBoards\Framework\Database\Orm\Model as BaseModel; |
| 7 | + | |
| 6 | 8 | class Model extends BaseModel |
| 7 | 9 | { |
| 8 | 10 | protected $guarded = ['id', 'ID']; |
| 9 | 11 | |
| 12 | + protected $nullableTimestampAttributes = []; | |
| 13 | + | |
| 14 | + public function setAttribute($key, $value) | |
| 15 | + { | |
| 16 | + if ($this->isNullableTimestampAttribute($key)) { | |
| 17 | + $value = $this->normalizeNullableTimestampValue($value); | |
| 18 | + } | |
| 19 | + | |
| 20 | + return parent::setAttribute($key, $value); | |
| 21 | + } | |
| 22 | + | |
| 23 | + public function getAttributeValue($key) | |
| 24 | + { | |
| 25 | + $value = parent::getAttributeValue($key); | |
| 26 | + | |
| 27 | + if ($this->isNullableTimestampAttribute($key)) { | |
| 28 | + return $this->normalizeNullableTimestampValue($value); | |
| 29 | + } | |
| 30 | + | |
| 31 | + return $value; | |
| 32 | + } | |
| 33 | + | |
| 34 | + protected function isNullableTimestampAttribute($key) | |
| 35 | + { | |
| 36 | + return is_string($key) && in_array($key, $this->nullableTimestampAttributes, true); | |
| 37 | + } | |
| 38 | + | |
| 39 | + protected function normalizeNullableTimestampValue($value) | |
| 40 | + { | |
| 41 | + if ($value instanceof DateTimeInterface) { | |
| 42 | + return (int) $value->format('Y') < 1900 ? null : $this->fromDateTime($value); | |
| 43 | + } | |
| 44 | + | |
| 45 | + if ($value === null) { | |
| 46 | + return null; | |
| 47 | + } | |
| 48 | + | |
| 49 | + if (is_bool($value)) { | |
| 50 | + return null; | |
| 51 | + } | |
| 52 | + | |
| 53 | + if (is_string($value)) { | |
| 54 | + $value = trim($value); | |
| 55 | + | |
| 56 | + if ($value === '') { | |
| 57 | + return null; | |
| 58 | + } | |
| 59 | + | |
| 60 | + $normalizedValue = strtolower($value); | |
| 61 | + | |
| 62 | + if (in_array($normalizedValue, ['none', 'null'], true)) { | |
| 63 | + return null; | |
| 64 | + } | |
| 65 | + | |
| 66 | + if (in_array($value, ['0000-00-00', '0000-00-00 00:00:00'], true)) { | |
| 67 | + return null; | |
| 68 | + } | |
| 69 | + | |
| 70 | + if (preg_match('/^(\d{4})-/', $value, $matches) && (int) $matches[1] < 1900) { | |
| 71 | + return null; | |
| 72 | + } | |
| 73 | + | |
| 74 | + if (strtotime($value) === false) { | |
| 75 | + return null; | |
| 76 | + } | |
| 77 | + } | |
| 78 | + | |
| 79 | + return $value; | |
| 80 | + } | |
| 10 | 81 | } |