Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
95.00% covered (success)
95.00%
38 / 40
75.00% covered (warning)
75.00%
3 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
DashboardStatsService
95.00% covered (success)
95.00%
38 / 40
75.00% covered (warning)
75.00%
3 / 4
13
0.00% covered (danger)
0.00%
0 / 1
 getStats
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
1 / 1
4
 getAvailablePeriods
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
 getDateRange
77.78% covered (warning)
77.78%
7 / 9
0.00% covered (danger)
0.00%
0 / 1
7.54
 getSystemStats
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace App\Services;
4
5use App\Models\Article;
6use App\Models\ArticlePublication;
7use Carbon\Carbon;
8
9class DashboardStatsService
10{
11    /**
12     * @return array
13     */
14    public function getStats(string $period = 'today'): array
15    {
16        $dateRange = $this->getDateRange($period);
17        
18        // Get articles fetched for the period
19        $articlesFetchedQuery = Article::query();
20        if ($dateRange) {
21            $articlesFetchedQuery->whereBetween('created_at', $dateRange);
22        }
23        $articlesFetched = $articlesFetchedQuery->count();
24
25        // Get articles published for the period
26        $articlesPublishedQuery = ArticlePublication::query()
27            ->whereNotNull('published_at');
28        if ($dateRange) {
29            $articlesPublishedQuery->whereBetween('published_at', $dateRange);
30        }
31        $articlesPublished = $articlesPublishedQuery->count();
32
33        // Calculate published percentage
34        $publishedPercentage = $articlesFetched > 0 ? round(($articlesPublished / $articlesFetched) * 100, 1) : 0.0;
35
36        return [
37            'articles_fetched' => $articlesFetched,
38            'articles_published' => $articlesPublished,
39            'published_percentage' => $publishedPercentage,
40        ];
41    }
42
43    /**
44     * @return array<string, string>
45     */
46    public function getAvailablePeriods(): array
47    {
48        return [
49            'today' => 'Today',
50            'week' => 'This Week',
51            'month' => 'This Month',
52            'year' => 'This Year',
53            'all' => 'All Time',
54        ];
55    }
56
57    /**
58     * @return array{0: Carbon, 1: Carbon}|null
59     */
60    private function getDateRange(string $period): ?array
61    {
62        $now = Carbon::now();
63        
64        return match ($period) {
65            'today' => [$now->copy()->startOfDay(), $now->copy()->endOfDay()],
66            'week' => [$now->copy()->startOfWeek(), $now->copy()->endOfWeek()],
67            'month' => [$now->copy()->startOfMonth(), $now->copy()->endOfMonth()],
68            'year' => [$now->copy()->startOfYear(), $now->copy()->endOfYear()],
69            'all' => null, // No date filtering for all-time stats
70            default => [$now->copy()->startOfDay(), $now->copy()->endOfDay()],
71        };
72    }
73
74    /**
75     * Get additional stats for dashboard
76     */
77    public function getSystemStats(): array
78    {
79        return [
80            'total_feeds' => \App\Models\Feed::count(),
81            'active_feeds' => \App\Models\Feed::where('is_active', true)->count(),
82            'total_channels' => \App\Models\PlatformChannel::count(),
83            'active_channels' => \App\Models\PlatformChannel::where('is_active', true)->count(),
84            'total_routes' => \App\Models\Route::count(),
85            'active_routes' => \App\Models\Route::where('is_active', true)->count(),
86        ];
87    }
88}