Analytics administration dashboard
* Page-view tracking * Unique visitor and session metrics * Content-view events * Search analytics * Conversion tracking * Form-submission events * Commerce events * Site-aware analytics * Privacy-conscious visitor hashing * Optional IP anonymisation * Do Not Track support * Configurable excluded paths * Daily metric aggregation * Top-page reporting * Recent-event activity * Report definitions * Scheduled report foundation * CSV and JSON report formats * Report execution history schema * Analytics retention and pruning * Administration navigation * Analytics permissions * Module registration * Feature test
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
namespace Modules\Analytics\Http\Controllers;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller;
|
||||
use Illuminate\View\View;
|
||||
use Modules\Analytics\Models\AnalyticsEvent;
|
||||
use Modules\Analytics\Models\AnalyticsReport;
|
||||
final class AnalyticsController extends Controller
|
||||
{
|
||||
public function index(Request $request): View
|
||||
{
|
||||
$days=max(1,min(365,(int)$request->integer('days',30))); $from=now()->subDays($days-1)->startOfDay();
|
||||
$events=AnalyticsEvent::query()->where('occurred_at','>=',$from);
|
||||
return view('analytics::index',[
|
||||
'days'=>$days,'pageViews'=>$events->clone()->where('event_type','page_view')->count(),
|
||||
'visitors'=>$events->clone()->whereNotNull('visitor_hash')->distinct('visitor_hash')->count('visitor_hash'),
|
||||
'conversions'=>$events->clone()->where('event_type','conversion')->count(),
|
||||
'searches'=>$events->clone()->where('event_type','search')->count(),
|
||||
'topPages'=>$events->clone()->where('event_type','page_view')->selectRaw('path, count(*) as total')->groupBy('path')->orderByDesc('total')->limit(10)->get(),
|
||||
'recentEvents'=>$events->clone()->latest('occurred_at')->limit(20)->get(), 'reports'=>AnalyticsReport::latest()->limit(20)->get(),
|
||||
]);
|
||||
}
|
||||
public function storeReport(Request $request): RedirectResponse
|
||||
{
|
||||
AnalyticsReport::create($request->validate(['name'=>'required|string|max:255','report_type'=>'required|in:overview,content,search,conversion,commerce','schedule'=>'nullable|string|max:50','format'=>'required|in:csv,json','is_active'=>'nullable|boolean']) + ['created_by'=>$request->user()->id,'is_active'=>$request->boolean('is_active',true)]);
|
||||
return back()->with('status','Report created.');
|
||||
}
|
||||
public function destroyReport(AnalyticsReport $report): RedirectResponse { $report->delete(); return back()->with('status','Report deleted.'); }
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
namespace Modules\Analytics\Http\Controllers;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Modules\Analytics\Services\AnalyticsTracker;
|
||||
final class TrackingController extends Controller
|
||||
{
|
||||
public function store(Request $request, AnalyticsTracker $tracker): JsonResponse
|
||||
{
|
||||
$data=$request->validate([
|
||||
'event_type'=>['required',Rule::in(['page_view','search','conversion','content_view','form_submit','commerce'])],
|
||||
'path'=>['nullable','string','max:2048'],'title'=>['nullable','string','max:255'],'referrer'=>['nullable','string','max:2048'],
|
||||
'visitor_id'=>['nullable','string','max:255'],'session_id'=>['nullable','string','max:255'],
|
||||
'subject_type'=>['nullable','string','max:255'],'subject_id'=>['nullable','integer'],'properties'=>['nullable','array'],
|
||||
]);
|
||||
$event=$tracker->track($request,$data);
|
||||
return response()->json(['recorded'=>(bool)$event],$event?201:202);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user