47 lines
1.3 KiB
PHP
47 lines
1.3 KiB
PHP
<?php
|
|
|
|
namespace App\Dashboard\Stats;
|
|
|
|
use App\Models\ArticlePublication;
|
|
use App\Models\PlatformChannel;
|
|
use App\Support\DateRange;
|
|
|
|
class PublicationsPerChannel implements BreakdownStat
|
|
{
|
|
public function key(): string
|
|
{
|
|
return 'publications-per-channel';
|
|
}
|
|
|
|
public function label(): string
|
|
{
|
|
return 'Publications per Channel';
|
|
}
|
|
|
|
public function for(DateRange $range): BreakdownResult
|
|
{
|
|
/** @var array<int, int> $counts */
|
|
$counts = ArticlePublication::query()
|
|
->whereBetween('published_at', [$range->from, $range->to])
|
|
->selectRaw('platform_channel_id, COUNT(*) as aggregate')
|
|
->groupBy('platform_channel_id')
|
|
->pluck('aggregate', 'platform_channel_id')
|
|
->all();
|
|
|
|
// Zero-fill in PHP; assumes the channel table stays small enough to load whole.
|
|
$rows = PlatformChannel::query()
|
|
->get()
|
|
->map(fn (PlatformChannel $channel): Breakdown => new Breakdown(
|
|
$channel->display_name,
|
|
(int) ($counts[$channel->id] ?? 0),
|
|
))
|
|
->all();
|
|
|
|
usort(
|
|
$rows,
|
|
fn (Breakdown $a, Breakdown $b): int => [$b->count, $a->label] <=> [$a->count, $b->label],
|
|
);
|
|
|
|
return new BreakdownResult($rows);
|
|
}
|
|
}
|