Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

190 wiersze
4.9KB

  1. <?php
  2. namespace Framework\Database;
  3. use Exception;
  4. use Framework\Database\Connection\Connection;
  5. use Framework\Database\Connection\MysqlConnection;
  6. use Framework\Database\Connection\SqliteConnection;
  7. use Framework\Database\Exception\ConnectionException;
  8. use ReflectionClass;
  9. abstract class Model
  10. {
  11. protected Connection $connection;
  12. protected string $table;
  13. protected array $attributes = [];
  14. protected array $dirty = [];
  15. protected array $casts = [];
  16. public function setConnection(Connection $connection): static
  17. {
  18. $this->connection = $connection;
  19. return $this;
  20. }
  21. public function getConnection(): Connection
  22. {
  23. if (!isset($this->connection)) {
  24. $this->connection = app('database');
  25. }
  26. return $this->connection;
  27. }
  28. public function setTable(string $table): static
  29. {
  30. $this->table = $table;
  31. return $this;
  32. }
  33. public function getTable(): string
  34. {
  35. if (!isset($this->table)) {
  36. $reflector = new ReflectionClass(static::class);
  37. foreach ($reflector->getAttributes() as $attribute) {
  38. if ($attribute->getName() == TableName::class) {
  39. return $attribute->getArguments()[0];
  40. }
  41. }
  42. throw new Exception('$table is not set and getTable is not defined');
  43. }
  44. return $this->table;
  45. }
  46. public static function with(array $attributes = []): static
  47. {
  48. $model = new static();
  49. $model->attributes = $attributes;
  50. return $model;
  51. }
  52. public static function query(): mixed
  53. {
  54. $model = new static();
  55. $query = $model->getConnection()->query();
  56. return (new ModelCollector($query, static::class))
  57. ->from($model->getTable());
  58. }
  59. public static function __callStatic(string $method, array $parameters = []): mixed
  60. {
  61. return static::query()->$method(...$parameters);
  62. }
  63. public function __get(string $property): mixed
  64. {
  65. $getter = 'get' . ucfirst($property) . 'Attribute';
  66. $value = null;
  67. if (method_exists($this, $property)) {
  68. $relationship = $this->$property();
  69. $method = $relationship->method;
  70. $value = $relationship->$method();
  71. }
  72. if (method_exists($this, $getter)) {
  73. $value = $this->$getter($this->attributes[$property] ?? null);
  74. }
  75. if (isset($this->attributes[$property])) {
  76. $value = $this->attributes[$property];
  77. }
  78. if (isset($this->casts[$property]) && is_callable($this->casts[$property])) {
  79. $value = $this->casts[$property]($value);
  80. }
  81. return $value;
  82. }
  83. public function __set(string $property, $value)
  84. {
  85. $setter = 'set' . ucfirst($property) . 'Attribute';
  86. array_push($this->dirty, $property);
  87. if (method_exists($this, $setter)) {
  88. $this->attributes[$property] = $this->$setter($value);
  89. return;
  90. }
  91. $this->attributes[$property] = $value;
  92. }
  93. public function save(): static
  94. {
  95. $values = [];
  96. foreach ($this->dirty as $dirty) {
  97. $values[$dirty] = $this->attributes[$dirty];
  98. }
  99. $data = [array_keys($values), $values];
  100. $query = static::query();
  101. if (isset($this->attributes['id'])) {
  102. $query
  103. ->where('id', $this->attributes['id'])
  104. ->update(...$data);
  105. return $this;
  106. }
  107. $query->insert(...$data);
  108. $this->attributes['id'] = $query->getLastInsertId();
  109. $this->dirty = [];
  110. return $this;
  111. }
  112. public function delete(): static
  113. {
  114. if (isset($this->attributes['id'])) {
  115. static::query()
  116. ->where('id', $this->attributes['id'])
  117. ->delete();
  118. }
  119. return $this;
  120. }
  121. public function hasOne(string $class, string $foreignKey, string $primaryKey = 'id'): mixed
  122. {
  123. $model = new $class;
  124. $query = $class::query()->from($model->getTable())->where($foreignKey, $this->attributes['id']);
  125. return new Relationship($query, 'first');
  126. }
  127. public function hasMany(string $class, string $foreignKey, string $primaryKey = 'id'): mixed
  128. {
  129. $model = new $class;
  130. $query = $class::query()->from($model->getTable())->where($foreignKey, $this->attributes['id']);
  131. return new Relationship($query, 'all');
  132. }
  133. public function belongsTo(string $class, string $foreignKey, string $primaryKey = 'id'): mixed
  134. {
  135. $model = new $class;
  136. $query = $class::query()->from($model->getTable())->where($primaryKey, $this->attributes[$foreignKey]);
  137. return new Relationship($query, 'first');
  138. }
  139. public static function find(int $id): static
  140. {
  141. return static::where('id', $id)->first();
  142. }
  143. }

Powered by TurnKey Linux.