Files
Woles-Framework/app/Core/Database/Model.php

257 lines
5.3 KiB
PHP
Raw Normal View History

<?php
namespace App\Core\Database;
/**
* NovaCore Base Model
* Base model class for database operations
*/
abstract class Model
{
protected Connection $connection;
protected string $table;
protected string $primaryKey = 'id';
protected array $fillable = [];
protected array $guarded = [];
protected array $attributes = [];
protected bool $timestamps = true;
protected string $createdAt = 'created_at';
protected string $updatedAt = 'updated_at';
public function __construct(array $attributes = [])
{
$this->attributes = $attributes;
$this->connection = $this->getConnection();
}
/**
* Get database connection
*/
protected function getConnection(): Connection
{
$config = include __DIR__ . '/../../Config/database.php';
$connectionConfig = $config['connections'][$config['default']];
return new Connection($connectionConfig);
}
/**
* Get query builder instance
*/
protected function newQuery(): QueryBuilder
{
return new QueryBuilder($this->connection, $this->table);
}
/**
* Find record by ID
*/
public static function find(int $id): ?self
{
$instance = new static();
$result = $instance->newQuery()->where($instance->primaryKey, $id)->first();
if (!$result) {
return null;
}
return new static($result);
}
/**
* Find all records
*/
public static function all(): array
{
$instance = new static();
$results = $instance->newQuery()->get();
return array_map(function ($attributes) {
return new static($attributes);
}, $results);
}
/**
* Create new record
*/
public static function create(array $attributes): self
{
$instance = new static();
$instance->fill($attributes);
$instance->save();
return $instance;
}
/**
* Fill model attributes
*/
public function fill(array $attributes): self
{
foreach ($attributes as $key => $value) {
if ($this->isFillable($key)) {
$this->attributes[$key] = $value;
}
}
return $this;
}
/**
* Check if attribute is fillable
*/
protected function isFillable(string $key): bool
{
if (in_array($key, $this->guarded)) {
return false;
}
if (empty($this->fillable)) {
return true;
}
return in_array($key, $this->fillable);
}
/**
* Save model to database
*/
public function save(): bool
{
if ($this->exists()) {
return $this->update();
} else {
return $this->insert();
}
}
/**
* Check if model exists in database
*/
public function exists(): bool
{
return isset($this->attributes[$this->primaryKey]) && $this->attributes[$this->primaryKey] !== null;
}
/**
* Insert new record
*/
protected function insert(): bool
{
$attributes = $this->attributes;
if ($this->timestamps) {
$now = date('Y-m-d H:i:s');
$attributes[$this->createdAt] = $now;
$attributes[$this->updatedAt] = $now;
}
$result = $this->newQuery()->insert($attributes);
if ($result) {
$this->attributes[$this->primaryKey] = $this->connection->lastInsertId();
}
return $result > 0;
}
/**
* Update existing record
*/
protected function update(): bool
{
$attributes = $this->attributes;
unset($attributes[$this->primaryKey]);
if ($this->timestamps) {
$attributes[$this->updatedAt] = date('Y-m-d H:i:s');
}
$result = $this->newQuery()
->where($this->primaryKey, $this->attributes[$this->primaryKey])
->update($attributes);
return $result > 0;
}
/**
* Delete record
*/
public function delete(): bool
{
if (!$this->exists()) {
return false;
}
$result = $this->newQuery()
->where($this->primaryKey, $this->attributes[$this->primaryKey])
->delete();
return $result > 0;
}
/**
* Get attribute value
*/
public function __get(string $key)
{
return $this->attributes[$key] ?? null;
}
/**
* Set attribute value
*/
public function __set(string $key, $value): void
{
$this->attributes[$key] = $value;
}
/**
* Check if attribute exists
*/
public function __isset(string $key): bool
{
return isset($this->attributes[$key]);
}
/**
* Convert model to array
*/
public function toArray(): array
{
return $this->attributes;
}
/**
* Convert model to JSON
*/
public function toJson(): string
{
return json_encode($this->attributes);
}
/**
* Get table name
*/
public function getTable(): string
{
return $this->table;
}
/**
* Get primary key
*/
public function getKeyName(): string
{
return $this->primaryKey;
}
/**
* Get primary key value
*/
public function getKey()
{
return $this->attributes[$this->primaryKey] ?? null;
}
}