52 lines
1.4 KiB
PHP
52 lines
1.4 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace App\Dashboard\Stats;
|
||
|
|
|
||
|
|
use App\Models\Article;
|
||
|
|
use App\Models\ArticlePublication;
|
||
|
|
use App\Support\DateRange;
|
||
|
|
use Illuminate\Database\Eloquent\Builder;
|
||
|
|
use Illuminate\Database\Eloquent\Model;
|
||
|
|
|
||
|
|
class ArticlesTrend extends DailySeriesStat
|
||
|
|
{
|
||
|
|
public function key(): string
|
||
|
|
{
|
||
|
|
return 'articles-trend';
|
||
|
|
}
|
||
|
|
|
||
|
|
public function label(): string
|
||
|
|
{
|
||
|
|
return 'Articles Fetched vs Published';
|
||
|
|
}
|
||
|
|
|
||
|
|
protected function series(DateRange $range, array $days): SeriesResult
|
||
|
|
{
|
||
|
|
return new SeriesResult($days, [
|
||
|
|
new Series('Fetched', $this->countByDay(Article::query(), 'created_at', $range, $days)),
|
||
|
|
new Series('Published', $this->countByDay(ArticlePublication::query(), 'published_at', $range, $days)),
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @param Builder<covariant Model> $query
|
||
|
|
* @param array<int, string> $days
|
||
|
|
* @return array<int, int>
|
||
|
|
*/
|
||
|
|
private function countByDay(Builder $query, string $column, DateRange $range, array $days): array
|
||
|
|
{
|
||
|
|
/** @var array<string, int> $counts */
|
||
|
|
$counts = $query
|
||
|
|
->whereBetween($column, [$range->from, $range->to])
|
||
|
|
->selectRaw("DATE({$column}) as bucket, COUNT(*) as aggregate")
|
||
|
|
->groupBy('bucket')
|
||
|
|
->pluck('aggregate', 'bucket')
|
||
|
|
->all();
|
||
|
|
|
||
|
|
return array_map(
|
||
|
|
fn (string $day): int => (int) ($counts[$day] ?? 0),
|
||
|
|
$days,
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|