/
delphin
/
CatRW
Обзор
Документация
Войти
/
delphin
/
CatRW
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
api/UserService.php
346 строк
13 KB
delphin
start project
02 мар 2026, 09:14
Верифицирован
02 мар 2026, 09:14
4b0ee03
Код
Авторство
О чём код?
<?php // /api/UserService.php - ИСПРАВЛЕННЫЙ КОД (без ошибок синтаксиса) class UserService { const STATUS_ACTIVE = 'active'; const STATUS_PENDING = 'pending'; // ожидает верификации const STATUS_BANNED = 'banned'; const STATUS_INACTIVE = 'inactive'; // деактивирован // 1. Метод для определения статуса public static function getUserStatus($user) { if (!$user) return 'unknown'; // Заблокирован (бан) if ($user['is_active'] == 0 && !empty($user['ban_reason']) && !empty($user['banned_at'])) { return self::STATUS_BANNED; } // Деактивирован if ($user['is_active'] == 0) { return self::STATUS_INACTIVE; } // Ожидает верификации email if ($user['is_active'] == 1 && (!isset($user['email_verified']) || $user['email_verified'] == 0)) { return self::STATUS_PENDING; } // Активен return self::STATUS_ACTIVE; } // 2. Исправленный getAll() public static function getAll($limit = 1000) { try { $sql = "SELECT id, username, email, role, full_name, language, is_active, email_verified, ban_reason, banned_at, created_at, last_login FROM users ORDER BY username LIMIT :limit"; $stmt = Database::connect()->prepare($sql); $stmt->bindParam(':limit', $limit, PDO::PARAM_INT); $stmt->execute(); $users = $stmt->fetchAll(); // Добавляем статус каждому пользователю foreach ($users as &$user) { $user['status'] = self::getUserStatus($user); } return $users; } catch (Exception $e) { error_log("UserService::getAll error: " . $e->getMessage()); return []; } } // 3. Исправленный get() public static function get($id) { try { $user = Database::selectOne(" SELECT id, username, email, role, full_name, language, is_active, email_verified, ban_reason, banned_at, created_at, last_login FROM users WHERE id = :id", [':id' => $id] ); if ($user) { $user['status'] = self::getUserStatus($user); } return $user; } catch (Exception $e) { error_log("UserService::get error for id $id: " . $e->getMessage()); return null; } } // 4. Исправленный search() public static function search($query) { try { if (empty($query)) { return self::getAll(); } // Используем анонимные параметры как в ManufacturerService $searchPattern = "%" . $query . "%"; return Database::select(" SELECT id, username, email, role, full_name, language, is_active, email_verified, ban_reason, banned_at, created_at, last_login FROM users WHERE username LIKE ? OR email LIKE ? OR full_name LIKE ? ORDER BY username ", [$searchPattern, $searchPattern, $searchPattern]); // Три параметра } catch (Exception $e) { error_log("UserService::search error: " . $e->getMessage()); return []; } } // 5. Создать пользователя public static function create($data) { try { // Валидация if (empty($data['username'])) { throw new Exception("Имя пользователя обязательно"); } if (empty($data['email'])) { throw new Exception("Email обязателен"); } if (empty($data['password'])) { throw new Exception("Пароль обязателен"); } // Проверка уникальности с более информативным сообщением $existingByUsername = Database::selectOne( "SELECT id, username FROM users WHERE username = ?", [$data['username']] ); $existingByEmail = Database::selectOne( "SELECT id, email FROM users WHERE email = ?", [$data['email']] ); if ($existingByUsername) { throw new Exception("Имя пользователя '{$data['username']}' уже занято (ID: {$existingByUsername['id']})"); } if ($existingByEmail) { throw new Exception("Email '{$data['email']}' уже используется (ID: {$existingByEmail['id']})"); } // Подготовка данных $userData = [ 'username' => trim($data['username']), 'email' => trim($data['email']), 'password_hash' => password_hash($data['password'], PASSWORD_DEFAULT), 'role' => $data['role'] ?? 'editor', 'full_name' => !empty($data['full_name']) ? trim($data['full_name']) : null, 'language' => $data['language'] ?? 'ru', 'is_active' => 1, 'email_verified' => 1 // Для админ-панели сразу верифицируем ]; return Database::insert('users', $userData); } catch (Exception $e) { error_log("UserService::create error: " . $e->getMessage()); throw $e; } } // 6. Исправленный update() - используем только именованные параметры public static function update($id, $data) { try { error_log("🔄 UserService::update called for ID: " . $id); error_log("📦 Update data: " . print_r($data, true)); // Проверяем существование пользователя $user = self::get($id); if (!$user) { throw new Exception("Пользователь #$id не найден"); } // Убираем поля, которые не должны обновляться unset($data['id'], $data['created_at'], $data['last_login']); // Если есть пароль - хэшируем if (!empty($data['password'])) { error_log("🔐 Password provided, hashing..."); $data['password_hash'] = password_hash($data['password'], PASSWORD_DEFAULT); unset($data['password']); } // Если запрос на бан if (isset($data['ban_action'])) { if ($data['ban_action'] === 'ban') { // Блокируем $data['is_active'] = 0; $data['banned_at'] = date('Y-m-d H:i:s'); if (!empty($data['ban_reason'])) { $data['ban_reason'] = trim($data['ban_reason']); } } elseif ($data['ban_action'] === 'unban') { // Разблокируем $data['is_active'] = 1; $data['ban_reason'] = null; $data['banned_at'] = null; } unset($data['ban_action']); } // Если меняем email_verified if (isset($data['email_verified'])) { $data['email_verified'] = $data['email_verified'] ? 1 : 0; } // Если меняем is_active if (isset($data['is_active'])) { $data['is_active'] = $data['is_active'] ? 1 : 0; // Если активируем и нет верификации email - верифицируем if ($data['is_active'] == 1 && !isset($data['email_verified'])) { $data['email_verified'] = 1; } } error_log("📋 Final update data: " . print_r($data, true)); // Используем именованные параметры вместо позиционных $result = Database::update( 'users', $data, 'id = :id', [':id' => $id] ); error_log("✅ Database::update affected rows: " . $result); return $result; } catch (Exception $e) { error_log("❌ UserService::update error for id $id: " . $e->getMessage()); throw $e; } } // 7. Удаление пользователя (деактивация) public static function delete($id) { try { error_log("UserService::delete called for ID: " . $id); // Проверяем существование пользователя $user = self::get($id); if (!$user) { throw new Exception("Пользователь #$id не найден"); } // Мягкое удаление - деактивация $result = Database::update('users', ['is_active' => 0], 'id = :id', [':id' => $id] ); return [ 'type' => 'deactivated', 'message' => 'Пользователь деактивирован' ]; } catch (Exception $e) { error_log("UserService::delete ERROR for id $id: " . $e->getMessage()); throw $e; } } // 8. Бан пользователя (отдельный метод для простоты) public static function ban($id, $reason = '') { try { $data = [ 'is_active' => 0, 'ban_reason' => trim($reason), 'banned_at' => date('Y-m-d H:i:s') ]; $result = Database::update('users', $data, 'id = :id', [':id' => $id]); return [ 'type' => 'banned', 'message' => 'Пользователь заблокирован', 'rows' => $result ]; } catch (Exception $e) { error_log("UserService::ban error for id $id: " . $e->getMessage()); throw $e; } } // 9. Разбан пользователя (отдельный метод для простоты) public static function unban($id) { try { $data = [ 'is_active' => 1, 'ban_reason' => null, 'banned_at' => null ]; $result = Database::update('users', $data, 'id = :id', [':id' => $id]); return [ 'type' => 'unbanned', 'message' => 'Пользователь разблокирован', 'rows' => $result ]; } catch (Exception $e) { error_log("UserService::unban error for id $id: " . $e->getMessage()); throw $e; } } // 10. Статистика public static function getStats() { try { return Database::selectOne(" SELECT COUNT(*) as total, SUM(is_active = 1 AND email_verified = 1) as active, SUM(is_active = 1 AND email_verified = 0) as pending, SUM(is_active = 0 AND ban_reason IS NOT NULL) as banned, SUM(is_active = 0 AND ban_reason IS NULL) as inactive FROM users "); } catch (Exception $e) { error_log("UserService::getStats error: " . $e->getMessage()); return ['total' => 0, 'active' => 0, 'pending' => 0, 'banned' => 0, 'inactive' => 0]; } } // 11. Верификация email public static function verifyEmail($id) { try { $data = [ 'email_verified' => 1 ]; $result = Database::update('users', $data, 'id = ?', [$id]); return $result; } catch (Exception $e) { error_log("UserService::verifyEmail error for id $id: " . $e->getMessage()); throw $e; } } } ?>