scaffold/src/Database/Model.php

112 lines
2.6 KiB
PHP

<?php
/**
* Read the documentation at:
* https://codeberg.org/vlw/scaffold/docs/Database/Model.md
*/
namespace vlw\Scaffold\Database;
use vlw\Scaffold\Database\Database;
require_once "Database.php";
abstract class Model {
const DATE_FORMAT = Database::DATE_FORMAT;
abstract public string $id { get; }
protected readonly Database $db;
private bool $_resolved = false;
private bool $_isset;
private ?array $_row;
/**
* Insert values into a database table
*
* @param string $table The target database table
*/
protected static function create(string $table, array $values): bool {
return new Database()->from($table)->insert($values);
}
/**
* Create a new Model to retrieve a specific entity
*
* @param string $table Target table where the entity is stored
* @param array<string> $columns An array of strings for each target database column
* @param array<array> $where vlw/MySQL->where() to locate the target entity
*/
public function __construct(
private readonly string $table,
private readonly array $columns,
private readonly array $where
) {
$this->db = new Database();
}
/**
* Fetch and store column values for instanced row
*
* @return ?array<array> The column and value of each target database column
*/
private ?array $row {
get {
// Return existing row data
if ($this->_resolved) { return $this->_row; }
$this->_resolved = true;
$this->_row = $this->db
->for($this->table)
->where($this->where)
->limit(1)
->select($this->columns)
->fetch_assoc() ?? null;
// Set isset property if property null
$this->_isset ??= $this->_row !== null;
return $this->_row;
}
}
/**
* Returns true if instanced target ebity exists
*
* @return bool Entity exists
*/
public bool $isset {
// Returns bool if row is set or attempts to resolve and set if null
get => $this->_isset ??= new Database()
->for($this->table)
->where($this->where)
->limit(1)
->select()
->num_rows === 1;
}
/**
* Get current row column value
*
* @param string $key Target column
* @return mixed Value of target column
*/
public function get(string $key): mixed {
return $this->row[$key] ?? null;
}
/**
* Update current row column with value
*
* @param string $key Target column to update
* @param mixed $value New value of target column
* @return bool Update was successful
*/
public function set(string $key, mixed $value): bool {
$this->_row[$key] = $value;
return $this->db
->for($this->table)
->where($this->where)
->update([$key => $value]);
}
}