Files
animexe/app/Http/Controllers/Frontend/ProfileController.php
T
2026-07-14 00:01:48 +03:00

236 lines
8.6 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace App\Http\Controllers\Frontend;
use App\Http\Controllers\Controller;
use App\Models\AnimeSwipe;
use App\Models\Comment;
use App\Models\Watchlist;
use App\Models\ContinueWatching;
use App\Models\UserAchievement;
use App\Models\EpisodeNote;
use App\Services\AchievementService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Storage;
use Illuminate\Validation\Rules\Password;
class ProfileController extends Controller
{
public function show()
{
$user = Auth::user();
$recentComments = Comment::where('user_id', $user->id)
->where('status', 'approved')
->orderByDesc('created_at')
->limit(10)
->get();
$commentCount = Comment::where('user_id', $user->id)
->where('status', 'approved')
->count();
// İzleme listesi (status gruplu)
$watchlistItems = Watchlist::where('user_id', $user->id)
->with('anime:id,title,slug,cover_image,type,rating')
->orderByDesc('created_at')
->get()
->filter(fn($wl) => $wl->anime !== null)
->groupBy('status');
// Devam et listesi
$continueItems = ContinueWatching::where('user_id', $user->id)
->with('anime:id,title,slug,cover_image')
->where('percent_complete', '<', 95)
->orderByDesc('updated_at')
->limit(12)
->get();
// İzleme istatistikleri
$watchStats = [
'episodes' => ContinueWatching::where('user_id', $user->id)->where('percent_complete', '>=', 70)->count(),
'hours' => round(ContinueWatching::where('user_id', $user->id)->sum('seconds_watched') / 3600, 1),
'watchlist'=> Watchlist::where('user_id', $user->id)->count(),
'ratings' => DB::table('anime_ratings')->where('user_id', $user->id)->count(),
];
// Başarımlar
AchievementService::check($user); // yeni kazanılanları kontrol et
$achievements = UserAchievement::where('user_id', $user->id)
->with('achievement')
->orderByDesc('earned_at')
->get();
$allAchievements = \App\Models\Achievement::all();
// İzleme Heatmap (son 365 gün)
$heatmapRaw = DB::table('analytics_watch_events')
->where('user_id', $user->id)
->where('created_at', '>=', now()->subDays(365))
->selectRaw('DATE(created_at) as d, COUNT(DISTINCT episode_id) as cnt')
->groupBy('d')
->pluck('cnt', 'd')
->toArray();
// Bölüm notları (son 20)
$episodeNotes = EpisodeNote::where('user_id', $user->id)
->with('episode:id,title,episode_number,anime_id', 'anime:id,title,slug')
->orderByDesc('created_at')
->limit(20)
->get();
// Keşfet geçmişi (beğenilenler + geçilenler)
$swipeHistory = AnimeSwipe::where('user_id', $user->id)
->with('anime:id,title,slug,cover_image,rating,release_year,type')
->orderByDesc('created_at')
->limit(60)
->get()
->filter(fn($s) => $s->anime !== null);
return view('frontend.profile', compact(
'user', 'recentComments', 'commentCount',
'watchlistItems', 'continueItems', 'watchStats',
'achievements', 'allAchievements',
'heatmapRaw', 'episodeNotes', 'swipeHistory'
));
}
public function publicProfile(\App\Models\User $user)
{
$commentCount = Comment::where('user_id', $user->id)->where('status', 'approved')->count();
$watchlistItems = Watchlist::where('user_id', $user->id)
->with('anime:id,title,slug,cover_image,type,rating')
->orderByDesc('created_at')
->get()
->filter(fn($wl) => $wl->anime !== null)
->groupBy('status');
$watchStats = [
'episodes' => ContinueWatching::where('user_id', $user->id)->where('percent_complete', '>=', 70)->count(),
'hours' => round(ContinueWatching::where('user_id', $user->id)->sum('seconds_watched') / 3600, 1),
'watchlist'=> Watchlist::where('user_id', $user->id)->count(),
'ratings' => DB::table('anime_ratings')->where('user_id', $user->id)->count(),
];
$achievements = UserAchievement::where('user_id', $user->id)
->with('achievement')
->where('earned_at', '!=', null)
->orderByDesc('earned_at')
->get();
$recentComments = Comment::where('user_id', $user->id)
->where('status', 'approved')
->orderByDesc('created_at')
->limit(6)
->get();
$isOwnProfile = Auth::id() === $user->id;
$isFollowing = Auth::check() && !$isOwnProfile ? Auth::user()->isFollowing($user->id) : false;
$followerCount = \App\Models\UserFollow::where('following_id', $user->id)->count();
$followingCount= \App\Models\UserFollow::where('follower_id', $user->id)->count();
$compatibility = (Auth::check() && !$isOwnProfile)
? Auth::user()->compatibilityWith($user)
: null;
return view('frontend.public-profile', compact(
'user', 'commentCount', 'watchlistItems',
'watchStats', 'achievements', 'recentComments', 'isOwnProfile',
'isFollowing', 'followerCount', 'followingCount', 'compatibility'
));
}
public function settings()
{
return view('frontend.profile-settings', ['user' => Auth::user()]);
}
public function update(Request $request)
{
$user = Auth::user();
$data = $request->validate([
'name' => 'required|string|max:60',
'username' => 'nullable|string|max:30|alpha_dash|unique:users,username,' . $user->id,
'bio' => 'nullable|string|max:300',
'website' => 'nullable|url|max:200',
'twitter' => 'nullable|string|max:50',
'instagram' => 'nullable|string|max:50',
'discord' => 'nullable|string|max:80',
'profile_color' => 'nullable|regex:/^#[0-9a-fA-F]{6}$/',
'show_watchlist' => 'boolean',
'show_activity' => 'boolean',
]);
// Checkboxlar false gelince request'te bulunmaz
$data['show_watchlist'] = $request->boolean('show_watchlist');
$data['show_activity'] = $request->boolean('show_activity');
// @ işaretlerini temizle
if (isset($data['twitter'])) $data['twitter'] = ltrim($data['twitter'], '@');
if (isset($data['instagram'])) $data['instagram'] = ltrim($data['instagram'], '@');
$user->update($data);
return back()->with('success', 'Profil güncellendi.');
}
public function updateAvatar(Request $request)
{
$request->validate([
'avatar' => 'required|image|mimes:jpg,jpeg,png,webp,gif|max:2048',
]);
$user = Auth::user();
// Eski avatarı sil
if ($user->avatar && Storage::disk('public')->exists($user->avatar)) {
Storage::disk('public')->delete($user->avatar);
}
$path = $request->file('avatar')->store('avatars', 'public');
$user->update(['avatar' => $path]);
return back()->with('success', 'Profil fotoğrafı güncellendi.');
}
public function updateBanner(Request $request)
{
$request->validate([
'banner' => 'required|image|mimes:jpg,jpeg,png,webp|max:5120',
]);
$user = Auth::user();
if ($user->banner_image && Storage::disk('public')->exists($user->banner_image)) {
Storage::disk('public')->delete($user->banner_image);
}
$path = $request->file('banner')->store('banners', 'public');
$user->update(['banner_image' => $path]);
return back()->with('success', 'Profil kapak fotoğrafı güncellendi.');
}
public function updatePassword(Request $request)
{
$request->validate([
'current_password' => 'required',
'password' => ['required', 'confirmed', Password::min(8)],
]);
$user = Auth::user();
if (!Hash::check($request->current_password, $user->password)) {
return back()->withErrors(['current_password' => 'Mevcut şifre yanlış.']);
}
$user->update(['password' => $request->password]);
return back()->with('success', 'Şifre güncellendi.');
}
}