ldc-qrcollector-back/app/Http/Controllers/Api/UrlController.php
2026-02-12 16:09:21 +01:00

151 lines
5.2 KiB
PHP

<?php
namespace App\Http\Controllers\Api;
use App\Enums\Api\ApiPeriodEnum;
use App\Http\Controllers\Controller;
use App\Http\Requests\Api\GetStatsRequest;
use App\Http\Resources\UrlCollection;
use App\Http\Resources\UrlHistoryCollection;
use App\Http\Resources\UrlResource;
use App\Models\Url;
use Carbon\Carbon;
use Carbon\CarbonPeriod;
use DateTime;
use Illuminate\Http\Request;
class UrlController extends Controller
{
/**
* Returns a listing of the urls.
*
* @return \App\Http\Resources\UrlCollection
*/
public function index()
{
return new UrlCollection(Url::paginate(25));
}
/**
* Returns the specified url.
*
* @param Url $url
* @return \App\Http\Resources\UrlResource
*/
public function show(Url $url)
{
return new UrlResource($url);
}
/**
* Returns the history for a given url.
*
* @param Url $url
* @param Request $request
* @return \Illuminate\Http\Response|\App\Http\Resources\UrlHistoryCollection
*/
public function getHistory(Url $url, Request $request)
{
// Set start date with request or now - 1 year.
if ($request->start) {
$start = $request->start;
$start = DateTime::createFromFormat('dmY', $start);
} else {
$start = now()->modify('-1 year');
}
// Set end date with request or now.
if ($request->end) {
$end = $request->end;
$end = DateTime::createFromFormat('dmY', $end)->modify('+1 day');
} else {
$end = now();
}
// Check if the difference bewteen end and start is < than 1 year.
if ($start->diff($end)->days > 366) {
return response('Date interval too long', 403);
};
$history = $url->history()
->where('start_date', '>', $start)
->where('end_date', '<', $end)
->get();
return new UrlHistoryCollection($history);
}
/**
* Returns the stats for the given url.
*
* @param \App\Http\Requests\Api\GetStatsRequest $request
* @param Url $url
* @return \Illuminate\Http\Response|\Illuminate\Http\JsonResponse
*/
public function getStats(GetStatsRequest $request, Url $url)
{
$period = ApiPeriodEnum::make($request->period, 'name');
$start = Carbon::make($request->start);
$end = Carbon::make($request->end);
// Check if the difference bewteen end and start is < than 1 year.
if ($start->diff($end)->days > 366) {
return response('Date interval too long', 403);
};
$stats = [];
switch ($period->label()) {
case \App\Enums\Api\ApiPeriodEnum::day->label():
$carbonPeriod = CarbonPeriod::create(
$start->format('Y-m-d'),
$end->format('Y-m-d')
)->toArray();
$dbStats = $url->stats()
->whereDate('date', '>', $start)
->whereDate('date', '<=', $end)
->get(['date', 'calls']);
foreach ($carbonPeriod as $day) {
$stats[] = $dbStats->where('date', $day)->isNotEmpty() ?
$dbStats->where('date', $day)->first()->calls :
0;
}
break;
case \App\Enums\Api\ApiPeriodEnum::week->label():
// Create a Carbon Period for weeks to make only one query per week.
$carbonPeriod = CarbonPeriod::create(
$start->startOfWeek()->format('Y-m-d'),
$end->endOfWeek()->format('Y-m-d')
)->weeks()->toArray();
foreach ($carbonPeriod as $week) {
$stats[] = $url->stats()
->whereIn(
'date',
CarbonPeriod::create(
$week->startOfWeek(Carbon::MONDAY)->format('Y-m-d'),
$week->endOfWeek(Carbon::SUNDAY)->format('Y-m-d')
)->toArray()
)
->sum('calls');
}
break;
case \App\Enums\Api\ApiPeriodEnum::month->label():
// Create a Carbon Period for months to make only one query per month.
$carbonPeriod = CarbonPeriod::create(
$start->startOfMonth()->format('Y-m-d'),
$end->endOfMonth()->format('Y-m-d')
)->months()->toArray();
foreach ($carbonPeriod as $month) {
$stats[] = $url->stats()
->whereIn(
'date',
CarbonPeriod::create(
$month->startOfMonth()->format('Y-m-d'),
$month->endOfMonth()->format('Y-m-d')
)->toArray()
)
->sum('calls');
}
break;
} //end switch
return \response()->json($stats);
}
}