1
0
mirror of https://github.com/flarum/core.git synced 2025-08-04 15:37:51 +02:00

feat(statistics): support for custom date ranges (#3622)

* feat: backend support for statistics custom date ranges
* feat: use seconds-based timestamps on backend instead
* feat: add frontend date selection option
* feat: add tests for lifetime and timed stats
* fix: add error alert when end date is after start date
* fix: wrong label
* fix: no data when start and end date are same day
* fix: use utc dayjs for formatting custom date range on widget
* chore: add dayjs as project dep
* fix: make end date inclusive
* feat: add integration test for custom date period
* fix: incorrect ts expect error comment
* fix: add missing type
* fix: typing errors
* fix(tests): remove type from class attribute definition
* fix: extract default values to function body
* fix: typo
* chore: use small modal
* fix: add missing `FormControl` class
* fix: cast url params to int to enforce type
* chore: `yarn format`

Signed-off-by: Sami Mazouz <sychocouldy@gmail.com>
Co-authored-by: Sami Mazouz <sychocouldy@gmail.com>
This commit is contained in:
David Wheatley
2022-09-29 12:12:54 +01:00
committed by GitHub
parent 973ec32e13
commit 76788efaba
9 changed files with 678 additions and 37 deletions

View File

@@ -9,6 +9,7 @@
namespace Flarum\Statistics\Api\Controller;
use Carbon\Carbon;
use DateTime;
use Flarum\Discussion\Discussion;
use Flarum\Http\RequestUtil;
@@ -69,20 +70,39 @@ class ShowStatisticsData implements RequestHandlerInterface
// control panel.
$actor->assertAdmin();
$reportingPeriod = Arr::get($request->getQueryParams(), 'period');
$model = Arr::get($request->getQueryParams(), 'model');
$query = $request->getQueryParams();
return new JsonResponse($this->getResponse($model, $reportingPeriod));
$reportingPeriod = Arr::get($query, 'period');
$model = Arr::get($query, 'model');
$customDateRange = Arr::get($query, 'dateRange');
return new JsonResponse($this->getResponse($model, $reportingPeriod, $customDateRange));
}
private function getResponse(?string $model, ?string $period): array
private function getResponse(?string $model, ?string $period, ?array $customDateRange): array
{
if ($period === 'lifetime') {
return $this->getLifetimeStatistics();
}
if (! Arr::exists($this->entities, $model)) {
throw new InvalidParameterException();
throw new InvalidParameterException('A model must be specified');
}
if ($period === 'custom') {
$start = (int) $customDateRange['start'];
$end = (int) $customDateRange['end'];
if (! $customDateRange || ! $start || ! $end) {
throw new InvalidParameterException('A custom date range must be specified');
}
// Seconds-based timestamps
$startRange = Carbon::createFromTimestampUTC($start)->toDateTime();
$endRange = Carbon::createFromTimestampUTC($end)->toDateTime();
// We can't really cache this
return $this->getTimedCounts($this->entities[$model][0], $this->entities[$model][1], $startRange, $endRange);
}
return $this->getTimedStatistics($model);
@@ -104,8 +124,16 @@ class ShowStatisticsData implements RequestHandlerInterface
});
}
private function getTimedCounts(Builder $query, $column)
private function getTimedCounts(Builder $query, string $column, ?DateTime $startDate = null, ?DateTime $endDate = null)
{
if (! isset($startDate)) {
$startDate = new DateTime('-365 days');
}
if (! isset($endDate)) {
$endDate = new DateTime();
}
$results = $query
->selectRaw(
'DATE_FORMAT(
@@ -115,7 +143,8 @@ class ShowStatisticsData implements RequestHandlerInterface
[new DateTime('-25 hours')]
)
->selectRaw('COUNT(id) as count')
->where($column, '>', new DateTime('-365 days'))
->where($column, '>', $startDate)
->where($column, '<=', $endDate)
->groupBy('time_group')
->pluck('count', 'time_group');