abstract class ActiveRecord
{
protected int $id;
protected static $db;
public static function setup($type, $user, $pass, $opt)
{
self::$db = new \PDO($type, $user, $pass, $opt);
}
abstract protected static function getTableName(): string;
public static function findAll(): ?array
{
$stmt = self::$db->prepare('SELECT * FROM ' . static::getTableName());
$stmt->execute();
$r = $stmt->fetchAll();
$c = sizeof($r);
for ($i = 0; $i < $c; $i++) {
$r[$i] = new static($r[$i]);
}
return $r ? $r : null;
}
public static function findById(int $id): ?object
{
$stmt = self::$db->prepare('SELECT * FROM `' . static::getTableName() . '` WHERE id = ?');
$stmt->execute([$id]);
$r = $stmt->fetch();
return $r ? new static($r) : null;
}
public static function findByAttribute(array $attributes): ?object
{
$keys = array_keys($attributes);
foreach ($keys as $key => $value) {
$keys[$key] = '`' . $value . '` = ?';
}
$stmt = self::$db->prepare('SELECT * FROM `' . static::getTableName() . '` WHERE ' . implode(' AND ', $keys));
$stmt->execute(array_values($attributes));
$r = $stmt->fetch();
return $r ? new static($r) : null;
}
public static function findCollectionByAttribute(array $attributes): ?array
{
$keys = array_keys($attributes);
foreach ($keys as $key => $value) {
$keys[$key] = '`' . $value . '` = ?';
}
$stmt = self::$db->prepare('SELECT * FROM `' . static::getTableName() . '` WHERE ' . implode(' AND ', $keys));
$stmt->execute(array_values($attributes));
$r = $stmt->fetchAll();
$c = sizeof($r);
if ($c > 0) {
for ($i = 0; $i < $c; $i++) {
$r[$i] = new static($r[$i]);
}
return $r;
}
return null;
}
public static function whereOne($query, array $attributes): ?object
{
$stmt = self::$db->prepare('SELECT * FROM `' . static::getTableName() . '` WHERE ' . $query);
$stmt->execute([$attributes]);
$r = $stmt->fetch();
return $r ? new static($r) : null;
}
public static function whereCollection($query, array $attributes): ?array
{
$stmt = self::$db->prepare('SELECT * FROM `' . static::getTableName() . '` WHERE ' . $query);
$stmt->execute([$attributes]);
$r = $stmt->fetchAll();
$c = sizeof($r);
if ($c > 0) {
for ($i = 0; $i < $c; $i++) {
$r[$i] = new static($r[$i]);
}
return $r;
}
return null;
}
public static function deleteById(int $id): void
{
self::$db->prepare('DELETE FROM `' . static::getTableName() . '` WHERE id = ?')->execute([$id]);
}
public function save(): void
{
$properties = get_object_vars($this);
if (empty($properties['id'])) {
$questionmarks = array_fill(0, sizeof($properties), '?');
$stmt = self::$db->prepare('INSERT INTO `' . static::getTableName() . '` (`' . implode('`,`', array_keys($properties)) . '`) VALUES (' . implode(',', $questionmarks) . ')');
$stmt->execute(array_values($properties));
$this->id = self::$db->lastInsertId();
} else {
$keys = array_keys($properties);
foreach ($keys as $key => $value) {
$keys[$key] = $value . ' = ?';
}
$stmt = self::$db->prepare('UPDATE `' . static::getTableName() . '` SET ' . implode(',', $keys) . ' WHERE id = ?');
$stmt->execute(array_merge(array_values($properties), [$this->id]));
}
}
public function delete(): void
{
self::$db->prepare('DELETE FROM `' . static::getTableName() . '` WHERE id = ?')->execute([$this->id]);
}
public function getId(): int
{
return $this->id;
}
}
class User extends ActiveRecord
{
protected string $login;
protected string $password;
protected string $fullname;
protected string $type;
protected int $status;
protected static function getTableName(): string
{
return 'users';
}
/**
* @return string
*/
public function getLogin(): string
{
return $this->login;
}
/**
* @param string $login
*/
public function setLogin(string $login): void
{
$this->login = $login;
}
/**
* @param string $password
*/
public function setPassword(string $password): void
{
$this->password = $password;
}
/**
* @return string
*/
public function getFullname(): string
{
return $this->fullname;
}
/**
* @param string $fullname
*/
public function setFullname(string $fullname): void
{
$this->fullname = $fullname;
}
/**
* @return string
*/
public function getType(): string
{
return $this->type;
}
/**
* @param string
*/
public function setType(string $type): void
{
$this->type = $type;
}
/**
* @return int $status
*/
public function getStatus()
{
return $this->status;
}
/**
* @param int $status
*/
public function setStatus($status): void
{
$this->status = $status;
}
public function isFree(): bool
{
if ($this->status < 2) return true;
return false;
}
public function validatePassword($password): bool
{
return password_verify($password, $this->password);
}
// высокоуровневый метод делающий ТОЛЬКО выборку по id
public function findModelById($id): Model
{
return $this->findModelByParams(
array('where' => array('`id` = ?i' => array($id)))
);
}
// УНИВЕРСАЛЬНЫЙ низкоуровневый метод, находящий объект модели по любым параметрам
public final function findModelByParams(array $params=array()): Model
{
$res = parent::createQuerySelect($params);
$object = $this->createModelFromDatabaseResult( is_object($res) && $res->getNumRows() ? $res->fetch_assoc() : array() );
return $object;
}
// построитель любого sql-запроса на SELECT, его исполнение и возвращение объекта типа РЕЗУЛЬТАТ
protected final function createQuerySelect(array $params)
{
$params = self::makeSqlFromParams($params); // это сам билдер!!!!!!!!!!!!!!
$sql = 'SELECT' . $params['what'] . 'FROM ?f' . $params['join'] . $params['where'] . $params['order'] . $params['limit'];
array_unshift($params['args'], $this->getTableName());
array_unshift($params['args'], $sql);
$result = call_user_func_array(array($this->getDb(), 'query'), $params['args']);
return $result;
}
protected final function createQueryDelete(array $params)
{
$params = self::makeSqlFromParams($params);
$sql = 'DELETE FROM ?f ' . $params['where'] . $params['limit'];
array_unshift($params['args'], $this->getTableName());
array_unshift($params['args'], $sql);
return call_user_func_array(array($this->getDb(), 'query'), $params['args']);
}
public static function findUserByIdOrNameAndSurname($id, $name, $surname)
{
$stmt = self::$db->prepare('SELECT * FROM `' . static::getTableName() . '` WHERE id = ? or name = ? and surname = ?');
$stmt->execute([$id, $name, $surname]); // или как тут правильно, не знаю..
$r = $stmt->fetch();
return $r ? new static($r) : null;
}