137 lines
6.5 KiB
PHP
137 lines
6.5 KiB
PHP
<?php
|
||
|
||
namespace App\Http\Controllers\Admin;
|
||
|
||
use App\Http\Controllers\Controller;
|
||
use App\Models\Anime;
|
||
use App\Models\Episode;
|
||
use App\Models\Season;
|
||
use Illuminate\Support\Facades\DB;
|
||
|
||
class ContentStatsController extends Controller
|
||
{
|
||
public function index()
|
||
{
|
||
// ── Özet sayılar ──────────────────────────────────────────────────────
|
||
$totalAnimes = Anime::count();
|
||
$publishedAnimes= Anime::where('is_published', true)->count();
|
||
$totalEpisodes = Episode::count();
|
||
$publishedEps = Episode::where('is_published', true)->count();
|
||
$totalSeasons = Season::count();
|
||
|
||
// ── Son 365 gün — günlük bölüm yükleme (ısı haritası için) ───────────
|
||
$epsByDay = Episode::selectRaw('DATE(created_at) as day, COUNT(*) as cnt')
|
||
->where('created_at', '>=', now()->subYear())
|
||
->groupBy('day')
|
||
->orderBy('day')
|
||
->pluck('cnt', 'day');
|
||
|
||
// ── Son 365 gün — günlük anime yükleme ───────────────────────────────
|
||
$animesByDay = Anime::selectRaw('DATE(created_at) as day, COUNT(*) as cnt')
|
||
->where('created_at', '>=', now()->subYear())
|
||
->groupBy('day')
|
||
->orderBy('day')
|
||
->pluck('cnt', 'day');
|
||
|
||
// ── Son 90 gün trend (chart için) ─────────────────────────────────────
|
||
$from90 = now()->subDays(89)->startOfDay();
|
||
$trendLabels = [];
|
||
$epTrendData = [];
|
||
$animeTrendData = [];
|
||
$cur = clone $from90;
|
||
while ($cur->lte(now())) {
|
||
$key = $cur->format('Y-m-d');
|
||
$trendLabels[] = $cur->format('d M');
|
||
$epTrendData[] = (int)($epsByDay[$key] ?? 0);
|
||
$animeTrendData[] = (int)($animesByDay[$key] ?? 0);
|
||
$cur->addDay();
|
||
}
|
||
|
||
// ── Saatlik yükleme dağılımı (tüm zamanlar) ──────────────────────────
|
||
$hourlyEps = Episode::selectRaw('HOUR(created_at) as hour, COUNT(*) as cnt')
|
||
->groupBy('hour')
|
||
->pluck('cnt', 'hour');
|
||
$hourlyEpsData = array_map(fn($h) => (int)($hourlyEps[$h] ?? 0), range(0, 23));
|
||
|
||
// ── Haftanın günlerine göre dağılım ───────────────────────────────────
|
||
$weekdayEps = Episode::selectRaw('DAYOFWEEK(created_at) as dow, COUNT(*) as cnt')
|
||
->groupBy('dow')
|
||
->pluck('cnt', 'dow');
|
||
// MySQL DAYOFWEEK: 1=Pazar, 2=Pazartesi, ..., 7=Cumartesi
|
||
$weekdayLabels = ['Paz', 'Pzt', 'Sal', 'Çar', 'Per', 'Cum', 'Cmt'];
|
||
$weekdayData = array_map(fn($d) => (int)($weekdayEps[$d] ?? 0), range(1, 7));
|
||
|
||
// ── Aylık dağılım (son 24 ay) ─────────────────────────────────────────
|
||
$monthlyEps = Episode::selectRaw('DATE_FORMAT(created_at, "%Y-%m") as mon, COUNT(*) as cnt')
|
||
->where('created_at', '>=', now()->subMonths(24))
|
||
->groupBy('mon')
|
||
->orderBy('mon')
|
||
->pluck('cnt', 'mon');
|
||
|
||
$monthLabels = [];
|
||
$monthData = [];
|
||
$mCur = now()->subMonths(23)->startOfMonth();
|
||
while ($mCur->lte(now())) {
|
||
$key = $mCur->format('Y-m');
|
||
$monthLabels[] = $mCur->format('M y');
|
||
$monthData[] = (int)($monthlyEps[$key] ?? 0);
|
||
$mCur->addMonth();
|
||
}
|
||
|
||
// ── Top 10 en fazla bölüm olan anime ──────────────────────────────────
|
||
$topByEpisodes = Anime::withCount('episodes')
|
||
->orderByDesc('episodes_count')
|
||
->limit(10)
|
||
->get(['id', 'title', 'slug', 'cover_image', 'status', 'type']);
|
||
|
||
// ── Son eklenen 20 bölüm ───────────────────────────────────────────────
|
||
$recentEpisodes = Episode::with(['anime:id,title,slug', 'season:id,season_number'])
|
||
->orderByDesc('created_at')
|
||
->limit(20)
|
||
->get();
|
||
|
||
// ── Son eklenen 10 anime ───────────────────────────────────────────────
|
||
$recentAnimes = Anime::orderByDesc('created_at')
|
||
->limit(10)
|
||
->get(['id', 'title', 'slug', 'cover_image', 'type', 'status', 'is_published', 'created_at']);
|
||
|
||
// ── Isı haritası verisi (52 hafta × 7 gün) ────────────────────────────
|
||
$heatStart = now()->subWeeks(51)->startOfWeek(\Carbon\Carbon::MONDAY);
|
||
$heatData = [];
|
||
for ($w = 0; $w < 52; $w++) {
|
||
$week = [];
|
||
for ($d = 0; $d < 7; $d++) {
|
||
$day = $heatStart->copy()->addDays($w * 7 + $d);
|
||
$key = $day->format('Y-m-d');
|
||
$week[] = [
|
||
'date' => $key,
|
||
'cnt' => (int)($epsByDay[$key] ?? 0),
|
||
];
|
||
}
|
||
$heatData[] = $week;
|
||
}
|
||
|
||
// ── Tür bazlı bölüm sayısı ────────────────────────────────────────────
|
||
$genreEpStats = DB::table('anime_genre')
|
||
->join('genres', 'genres.id', '=', 'anime_genre.genre_id')
|
||
->join('episodes', 'episodes.anime_id', '=', 'anime_genre.anime_id')
|
||
->select('genres.name', DB::raw('COUNT(episodes.id) as ep_count'))
|
||
->groupBy('genres.id', 'genres.name')
|
||
->orderByDesc('ep_count')
|
||
->limit(12)
|
||
->get();
|
||
|
||
return view('admin.stats.index', compact(
|
||
'totalAnimes', 'publishedAnimes', 'totalEpisodes', 'publishedEps', 'totalSeasons',
|
||
'trendLabels', 'epTrendData', 'animeTrendData',
|
||
'hourlyEpsData',
|
||
'weekdayLabels', 'weekdayData',
|
||
'monthLabels', 'monthData',
|
||
'topByEpisodes',
|
||
'recentEpisodes', 'recentAnimes',
|
||
'heatData',
|
||
'genreEpStats',
|
||
));
|
||
}
|
||
}
|