[MVC] Полная миграция на MVC архитектуру

- Создано ядро MVC: App, Router, Controller, Model, View, Database
- Созданы модели: User, Product, Category, Cart, Order
- Созданы контроллеры: Home, Auth, Product, Cart, Order, Page, Admin
- Созданы layouts и partials для представлений
- Добавлены все views для страниц
- Настроена маршрутизация с чистыми URL
- Обновлена конфигурация Docker и Apache для mod_rewrite
- Добавлена единая точка входа public/index.php
This commit is contained in:
kirill.khorkov
2026-01-03 11:48:14 +03:00
parent 3f257120fa
commit d2c15ec37f
53 changed files with 8650 additions and 30 deletions

153
app/Models/User.php Normal file
View File

@@ -0,0 +1,153 @@
<?php
namespace App\Models;
use App\Core\Model;
/**
* User - модель пользователя
*/
class User extends Model
{
protected string $table = 'users';
protected string $primaryKey = 'user_id';
/**
* Найти пользователя по email
*/
public function findByEmail(string $email): ?array
{
return $this->findWhere(['email' => $email]);
}
/**
* Проверить пароль пользователя
*/
public function verifyPassword(string $password, string $hash): bool
{
return password_verify($password, $hash);
}
/**
* Хешировать пароль
*/
public function hashPassword(string $password): string
{
return password_hash($password, PASSWORD_DEFAULT);
}
/**
* Создать нового пользователя
*/
public function register(array $data): ?int
{
$config = require dirname(__DIR__, 2) . '/config/app.php';
// Проверяем, является ли email администраторским
$isAdmin = in_array(strtolower($data['email']), $config['admin_emails'] ?? []);
return $this->create([
'email' => $data['email'],
'password_hash' => $this->hashPassword($data['password']),
'full_name' => $data['full_name'],
'phone' => $data['phone'] ?? null,
'city' => $data['city'] ?? null,
'is_admin' => $isAdmin,
'is_active' => true
]);
}
/**
* Авторизация пользователя
*/
public function authenticate(string $email, string $password): ?array
{
$user = $this->findByEmail($email);
if (!$user) {
return null;
}
if (!$user['is_active']) {
return null;
}
if (!$this->verifyPassword($password, $user['password_hash'])) {
return null;
}
// Обновляем время последнего входа
$this->update($user['user_id'], [
'last_login' => date('Y-m-d H:i:s')
]);
return $user;
}
/**
* Получить активных пользователей
*/
public function getActive(int $limit = 50): array
{
$sql = "SELECT * FROM {$this->table}
WHERE is_active = TRUE
ORDER BY created_at DESC
LIMIT ?";
return $this->query($sql, [$limit]);
}
/**
* Получить всех пользователей с пагинацией
*/
public function getAllPaginated(int $limit = 50, int $offset = 0): array
{
$sql = "SELECT * FROM {$this->table}
ORDER BY created_at DESC
LIMIT ? OFFSET ?";
return $this->query($sql, [$limit, $offset]);
}
/**
* Проверить существование email
*/
public function emailExists(string $email): bool
{
$user = $this->findByEmail($email);
return $user !== null;
}
/**
* Обновить профиль пользователя
*/
public function updateProfile(int $userId, array $data): bool
{
$allowedFields = ['full_name', 'phone', 'city'];
$updateData = array_intersect_key($data, array_flip($allowedFields));
$updateData['updated_at'] = date('Y-m-d H:i:s');
return $this->update($userId, $updateData);
}
/**
* Изменить пароль
*/
public function changePassword(int $userId, string $newPassword): bool
{
return $this->update($userId, [
'password_hash' => $this->hashPassword($newPassword),
'updated_at' => date('Y-m-d H:i:s')
]);
}
/**
* Заблокировать/разблокировать пользователя
*/
public function setActive(int $userId, bool $active): bool
{
return $this->update($userId, [
'is_active' => $active,
'updated_at' => date('Y-m-d H:i:s')
]);
}
}