/
itp_practice
/
itp_backend
Обзор
Документация
Войти
/
itp_practice
/
itp_backend
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
master
app/Services/UserProfileService.php
208 строк
6 KB
vivanenko
profile edit
29 май 2025, 19:57
29 май 2025, 19:57
2ec716b
Код
Авторство
О чём код?
<?php namespace App\Services; use App\Exceptions\EmailAlreadyExistsException; use App\Exceptions\TelegramDataAlreadyExistsException; use App\Models\User; use Illuminate\Support\Facades\Log; use Illuminate\Support\Str; /** * User Profile Service * * Business Logic Layer for user profile operations following SOLID principles: * - Single Responsibility: Handles only user profile update logic * - Open/Closed: Can be extended with new profile update methods * - Liskov Substitution: Can be substituted with other profile services * - Interface Segregation: Methods are focused and specific * - Dependency Inversion: Depends on abstractions (User model) */ class UserProfileService { /** * Update user email * * @param User $user * @param string $newEmail * @return User * @throws EmailAlreadyExistsException */ public function updateEmail(User $user, string $newEmail): User { // Check if email already exists if (User::where('email', $newEmail)->where('id', '!=', $user->id)->exists()) { throw new EmailAlreadyExistsException('Email already exists'); } // Update email $user->email = $newEmail; $user->email_verified_at = null; // Reset email verification $user->save(); Log::info('User email updated successfully', [ 'user_id' => $user->id, 'old_email' => $user->getOriginal('email'), 'new_email' => $newEmail ]); return $user->fresh(); } /** * Update user Telegram data * * @param User $user * @param array $telegramData * @return User * @throws TelegramDataAlreadyExistsException */ public function updateTelegram(User $user, array $telegramData): User { $this->validateTelegramDataUniqueness($user, $telegramData); // Update only provided fields if (isset($telegramData['telegram_username'])) { $user->telegram_username = $telegramData['telegram_username']; } if (isset($telegramData['telegram_id'])) { $user->telegram_id = $telegramData['telegram_id']; } // Update timestamp $user->updated_at = now(); $user->save(); Log::info('User Telegram data updated successfully', [ 'user_id' => $user->id, 'telegram_username' => $user->telegram_username, 'telegram_id' => $user->telegram_id ]); return $user->fresh(); } /** * Generate verification token for Telegram linking * * @param User $user * @return array */ public function generateTelegramVerifyToken(User $user): array { // Generate unique token $token = Str::random(32); // Store token in cache for verification (expires in 10 minutes) cache()->put("telegram_verify_{$token}", [ 'user_id' => $user->id, 'created_at' => now()->toISOString() ], now()->addMinutes(10)); Log::info('Telegram verification token generated', [ 'user_id' => $user->id, 'token' => $token ]); return [ 'token' => $token, 'botUsername' => config('telegram.bot_username', 'TakeTokenBot') ]; } /** * Validate Telegram data uniqueness * * @param User $user * @param array $telegramData * @throws TelegramDataAlreadyExistsException */ private function validateTelegramDataUniqueness(User $user, array $telegramData): void { // Check telegram_username uniqueness if (isset($telegramData['telegram_username']) && !empty($telegramData['telegram_username'])) { $existingUser = User::where('telegram_username', $telegramData['telegram_username']) ->where('id', '!=', $user->id) ->whereNotNull('telegram_username') ->first(); if ($existingUser) { throw new TelegramDataAlreadyExistsException( "Telegram username '{$telegramData['telegram_username']}' already exists" ); } } // Check telegram_id uniqueness if (isset($telegramData['telegram_id']) && !empty($telegramData['telegram_id'])) { $existingUser = User::where('telegram_id', $telegramData['telegram_id']) ->where('id', '!=', $user->id) ->whereNotNull('telegram_id') ->first(); if ($existingUser) { throw new TelegramDataAlreadyExistsException( "Telegram ID '{$telegramData['telegram_id']}' already exists" ); } } } /** * Verify Telegram linking with token * * @param string $token * @param array $telegramData * @return User|null */ public function verifyTelegramLinking(string $token, array $telegramData): ?User { // Get token data from cache $tokenData = cache()->get("telegram_verify_{$token}"); if (!$tokenData) { Log::warning('Invalid or expired Telegram verification token', [ 'token' => $token ]); return null; } // Find user $user = User::find($tokenData['user_id']); if (!$user) { Log::error('User not found for Telegram verification', [ 'user_id' => $tokenData['user_id'], 'token' => $token ]); return null; } try { // Update Telegram data $updatedUser = $this->updateTelegram($user, $telegramData); // Mark as verified $updatedUser->is_telegram_verified = true; $updatedUser->save(); // Remove token from cache cache()->forget("telegram_verify_{$token}"); Log::info('Telegram linking verified successfully', [ 'user_id' => $user->id, 'telegram_id' => $telegramData['telegram_id'] ?? null, 'telegram_username' => $telegramData['telegram_username'] ?? null ]); return $updatedUser; } catch (\Exception $e) { Log::error('Failed to verify Telegram linking', [ 'user_id' => $user->id, 'error' => $e->getMessage() ]); return null; } } }