48 lines
1.2 KiB
PHP
48 lines
1.2 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace App\Dashboard\Stats;
|
||
|
|
|
||
|
|
use App\Models\Article;
|
||
|
|
use App\Models\Feed;
|
||
|
|
use App\Support\DateRange;
|
||
|
|
|
||
|
|
class ArticlesPerFeed implements BreakdownStat
|
||
|
|
{
|
||
|
|
public function key(): string
|
||
|
|
{
|
||
|
|
return 'articles-per-feed';
|
||
|
|
}
|
||
|
|
|
||
|
|
public function label(): string
|
||
|
|
{
|
||
|
|
return 'Articles per Feed';
|
||
|
|
}
|
||
|
|
|
||
|
|
public function for(DateRange $range): BreakdownResult
|
||
|
|
{
|
||
|
|
/** @var array<int, int> $counts */
|
||
|
|
$counts = Article::query()
|
||
|
|
->whereBetween('created_at', [$range->from, $range->to])
|
||
|
|
->selectRaw('feed_id, COUNT(*) as aggregate')
|
||
|
|
->groupBy('feed_id')
|
||
|
|
->pluck('aggregate', 'feed_id')
|
||
|
|
->all();
|
||
|
|
|
||
|
|
// Zero-fill in PHP; assumes the feed table stays small enough to load whole.
|
||
|
|
$rows = Feed::query()
|
||
|
|
->get()
|
||
|
|
->map(fn (Feed $feed): Breakdown => new Breakdown(
|
||
|
|
$feed->name,
|
||
|
|
(int) ($counts[$feed->id] ?? 0),
|
||
|
|
))
|
||
|
|
->all();
|
||
|
|
|
||
|
|
usort(
|
||
|
|
$rows,
|
||
|
|
fn (Breakdown $a, Breakdown $b): int => [$b->count, $a->label] <=> [$a->count, $b->label],
|
||
|
|
);
|
||
|
|
|
||
|
|
return new BreakdownResult($rows);
|
||
|
|
}
|
||
|
|
}
|