phase 8 and 9
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\V1;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Resources\V1\EventResource;
|
||||
use App\Http\Resources\V1\PageResource;
|
||||
use App\Http\Resources\V1\ReferrerResource;
|
||||
use App\Http\Resources\V1\StatsResource;
|
||||
use App\Http\Resources\V1\VisitorBreakdownResource;
|
||||
use App\Http\Resources\V1\WebsiteResource;
|
||||
use App\Models\Website;
|
||||
use App\Services\AnalyticsQueryService;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
class WebsiteController extends Controller
|
||||
{
|
||||
public function index(Request $request): AnonymousResourceCollection
|
||||
{
|
||||
$websites = $request->user()->websites()->orderBy('name')->get();
|
||||
|
||||
return WebsiteResource::collection($websites);
|
||||
}
|
||||
|
||||
public function stats(Request $request, Website $website): StatsResource
|
||||
{
|
||||
$this->authorizeWebsite($request, $website);
|
||||
[$from, $to] = $this->parseDateRange($request);
|
||||
$service = AnalyticsQueryService::for($website, $from, $to);
|
||||
|
||||
return new StatsResource([
|
||||
'from' => $from->toDateString(),
|
||||
'to' => $to->toDateString(),
|
||||
'metrics' => $service->summary(),
|
||||
'timeseries' => $service->visitorsOverTime(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function pages(Request $request, Website $website): AnonymousResourceCollection
|
||||
{
|
||||
$this->authorizeWebsite($request, $website);
|
||||
[$from, $to] = $this->parseDateRange($request);
|
||||
$limit = $this->parseLimit($request);
|
||||
$service = AnalyticsQueryService::for($website, $from, $to);
|
||||
|
||||
return PageResource::collection($service->topPages($limit));
|
||||
}
|
||||
|
||||
public function referrers(Request $request, Website $website): AnonymousResourceCollection
|
||||
{
|
||||
$this->authorizeWebsite($request, $website);
|
||||
[$from, $to] = $this->parseDateRange($request);
|
||||
$limit = $this->parseLimit($request);
|
||||
$service = AnalyticsQueryService::for($website, $from, $to);
|
||||
|
||||
return ReferrerResource::collection($service->trafficSources($limit));
|
||||
}
|
||||
|
||||
public function events(Request $request, Website $website): AnonymousResourceCollection
|
||||
{
|
||||
$this->authorizeWebsite($request, $website);
|
||||
[$from, $to] = $this->parseDateRange($request);
|
||||
$limit = $this->parseLimit($request);
|
||||
$service = AnalyticsQueryService::for($website, $from, $to);
|
||||
|
||||
return EventResource::collection($service->eventsOverview($limit));
|
||||
}
|
||||
|
||||
public function visitors(Request $request, Website $website): VisitorBreakdownResource
|
||||
{
|
||||
$this->authorizeWebsite($request, $website);
|
||||
[$from, $to] = $this->parseDateRange($request);
|
||||
$service = AnalyticsQueryService::for($website, $from, $to);
|
||||
|
||||
return new VisitorBreakdownResource([
|
||||
'from' => $from->toDateString(),
|
||||
'to' => $to->toDateString(),
|
||||
'countries' => $service->visitorsByCountry(20)->map(fn ($r) => [
|
||||
'country' => $r->country,
|
||||
'visitors' => $r->visitors,
|
||||
]),
|
||||
'browsers' => $service->visitorsByBrowser(10)->map(fn ($r) => [
|
||||
'browser' => $r->browser,
|
||||
'visitors' => $r->visitors,
|
||||
]),
|
||||
'operating_systems' => $service->visitorsByOS(10)->map(fn ($r) => [
|
||||
'os' => $r->os,
|
||||
'visitors' => $r->visitors,
|
||||
]),
|
||||
'device_types' => $service->visitorsByDeviceType(5)->map(fn ($r) => [
|
||||
'device_type' => $r->device_type,
|
||||
'visitors' => $r->visitors,
|
||||
]),
|
||||
'languages' => $service->visitorsByLanguage(10)->map(fn ($r) => [
|
||||
'language' => $r->language,
|
||||
'visitors' => $r->visitors,
|
||||
]),
|
||||
'new_vs_returning' => $service->newVsReturning(),
|
||||
]);
|
||||
}
|
||||
|
||||
private function authorizeWebsite(Request $request, Website $website): void
|
||||
{
|
||||
if ($website->user_id !== $request->user()->id) {
|
||||
abort(403, 'You do not own this website.');
|
||||
}
|
||||
}
|
||||
|
||||
private function parseDateRange(Request $request): array
|
||||
{
|
||||
$request->validate([
|
||||
'from' => 'nullable|date|before_or_equal:to',
|
||||
'to' => 'nullable|date|after_or_equal:from',
|
||||
]);
|
||||
|
||||
$from = $request->has('from')
|
||||
? Carbon::parse($request->get('from'))
|
||||
: Carbon::today()->subDays(6);
|
||||
|
||||
$to = $request->has('to')
|
||||
? Carbon::parse($request->get('to'))
|
||||
: Carbon::today();
|
||||
|
||||
return [$from, $to];
|
||||
}
|
||||
|
||||
private function parseLimit(Request $request): int
|
||||
{
|
||||
return min((int) $request->get('limit', 50), 200);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user