feat: Complete Woles Framework v1.0 with enterprise-grade UI
- Add comprehensive error handling system with custom error pages - Implement professional enterprise-style design with Tailwind CSS - Create modular HMVC architecture with clean separation of concerns - Add security features: CSRF protection, XSS filtering, Argon2ID hashing - Include CLI tools for development workflow - Add error reporting dashboard with system monitoring - Implement responsive design with consistent slate color scheme - Replace all emoji icons with professional SVG icons - Add comprehensive test suite with PHPUnit - Include database migrations and seeders - Add proper exception handling with fallback pages - Implement template engine with custom syntax support - Add helper functions and facades for clean code - Include proper logging and debugging capabilities
This commit is contained in:
256
app/Core/Database/Model.php
Normal file
256
app/Core/Database/Model.php
Normal file
@@ -0,0 +1,256 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user