0, 'week_page_views' => 0, 'month_page_views' => 0, 'today_visitors' => 0, 'week_visitors' => 0, 'month_visitors' => 0, 'avg_load_time' => 'N/A', 'bounce_rate' => 'N/A', 'avg_session_duration' => 'N/A', ]; $topPages = []; $trafficSources = []; $data = [ 'title' => 'Analytics Dashboard', 'today_page_views' => $overview['today_page_views'] ?? 0, 'week_page_views' => $overview['week_page_views'] ?? 0, 'month_page_views' => $overview['month_page_views'] ?? 0, 'today_visitors' => $overview['today_visitors'] ?? 0, 'week_visitors' => $overview['week_visitors'] ?? 0, 'month_visitors' => $overview['month_visitors'] ?? 0, 'avg_load_time' => $overview['avg_load_time'] ?? 'N/A', 'bounce_rate' => $overview['bounce_rate'] ?? 'N/A', 'avg_session_duration' => $overview['avg_session_duration'] ?? 'N/A', 'top_pages' => $topPages, 'traffic_sources' => $trafficSources, 'last_update' => date('Y-m-d H:i:s'), ]; return new ViewResult( template: 'analytics-dashboard', metaData: new MetaData('Analytics Dashboard', 'Website Analytics and User Behavior'), data: $data ); } #[Route(path: '/admin/analytics/api/overview', method: Method::GET)] public function getOverview(): JsonResult { try { $endDate = $_GET['end_date'] ?? date('Y-m-d'); $startDate = $_GET['start_date'] ?? date('Y-m-d', strtotime('-30 days')); // Calculate days between dates $days = max(1, (strtotime($endDate) - strtotime($startDate)) / 86400 + 1); $overview = $this->dashboardService->getOverview($startDate, $endDate); return new JsonResult([ 'success' => true, 'data' => $overview, 'period' => [ 'start' => $startDate, 'end' => $endDate, 'days' => (int)$days, ], ]); } catch (\Exception $e) { return new JsonResult([ 'success' => false, 'error' => $e->getMessage(), ], Status::from(500)); } } #[Route(path: '/admin/analytics/api/timeseries', method: Method::GET)] public function getTimeSeries(): JsonResult { try { $metric = $_GET['metric'] ?? 'page_views'; $period = $_GET['period'] ?? 'day'; $days = (int) ($_GET['days'] ?? 30); $endDate = date('Y-m-d'); $startDate = date('Y-m-d', strtotime("-{$days} days")); $timeSeries = $this->storage->getTimeSeries($metric, $startDate, $endDate, $period); return new JsonResult([ 'success' => true, 'data' => $timeSeries, 'metric' => $metric, 'period' => $period, 'range' => [ 'start' => $startDate, 'end' => $endDate, 'days' => $days, ], ]); } catch (\Exception $e) { return new JsonResult([ 'success' => false, 'error' => $e->getMessage(), ], Status::from(500)); } } #[Route(path: '/admin/analytics/api/top-pages', method: Method::GET)] public function getTopPages(): JsonResult { try { $limit = (int) ($_GET['limit'] ?? 10); $days = (int) ($_GET['days'] ?? 30); $endDate = date('Y-m-d'); $startDate = date('Y-m-d', strtotime("-{$days} days")); $topPages = $this->dashboardService->getTopPages($startDate, $endDate, $limit); return new JsonResult([ 'success' => true, 'data' => $topPages, 'limit' => $limit, 'period' => [ 'start' => $startDate, 'end' => $endDate, 'days' => $days, ], ]); } catch (\Exception $e) { return new JsonResult([ 'success' => false, 'error' => $e->getMessage(), ], Status::from(500)); } } #[Route(path: '/admin/analytics/api/traffic-sources', method: Method::GET)] public function getTrafficSources(): JsonResult { try { $days = (int) ($_GET['days'] ?? 30); $endDate = date('Y-m-d'); $startDate = date('Y-m-d', strtotime("-{$days} days")); $sources = $this->dashboardService->getTrafficSources($startDate, $endDate); return new JsonResult([ 'success' => true, 'data' => $sources, 'period' => [ 'start' => $startDate, 'end' => $endDate, 'days' => $days, ], ]); } catch (\Exception $e) { return new JsonResult([ 'success' => false, 'error' => $e->getMessage(), ], Status::from(500)); } } #[Route(path: '/admin/analytics/api/user-behavior', method: Method::GET)] public function getUserBehavior(): JsonResult { try { $days = (int) ($_GET['days'] ?? 30); $endDate = date('Y-m-d'); $startDate = date('Y-m-d', strtotime("-{$days} days")); $behavior = $this->reportService->getUserBehavior($startDate, $endDate); return new JsonResult([ 'success' => true, 'data' => $behavior, 'period' => [ 'start' => $startDate, 'end' => $endDate, 'days' => $days, ], ]); } catch (\Exception $e) { return new JsonResult([ 'success' => false, 'error' => $e->getMessage(), ], Status::from(500)); } } #[Route(path: '/admin/analytics/api/business-metrics', method: Method::GET)] public function getBusinessMetrics(): JsonResult { try { $days = (int) ($_GET['days'] ?? 30); $endDate = date('Y-m-d'); $startDate = date('Y-m-d', strtotime("-{$days} days")); $metrics = $this->reportService->getBusinessMetrics($startDate, $endDate); return new JsonResult([ 'success' => true, 'data' => $metrics, 'period' => [ 'start' => $startDate, 'end' => $endDate, 'days' => $days, ], ]); } catch (\Exception $e) { return new JsonResult([ 'success' => false, 'error' => $e->getMessage(), ], Status::from(500)); } } #[Route(path: '/admin/analytics/api/real-time', method: Method::GET)] public function getRealTimeData(): JsonResult { try { $realTime = $this->realTimeService->getRealTimeData(); return new JsonResult([ 'success' => true, 'data' => $realTime, 'timestamp' => time(), 'updated_at' => date('Y-m-d H:i:s'), ]); } catch (\Exception $e) { return new JsonResult([ 'success' => false, 'error' => $e->getMessage(), ], Status::from(500)); } } #[Route(path: '/admin/analytics/api/events', method: Method::GET)] public function getEvents(): JsonResult { try { $category = $_GET['category'] ?? null; $limit = (int) ($_GET['limit'] ?? 100); $offset = (int) ($_GET['offset'] ?? 0); $days = (int) ($_GET['days'] ?? 7); $endDate = date('Y-m-d'); $startDate = date('Y-m-d', strtotime("-{$days} days")); $categoryFilter = $category ? AnalyticsCategory::tryFrom($category) : null; $events = $this->reportService->getEvents($startDate, $endDate, $categoryFilter, $limit, $offset); $total = $this->reportService->getEventsCount($startDate, $endDate, $categoryFilter); return new JsonResult([ 'success' => true, 'data' => $events, 'pagination' => [ 'limit' => $limit, 'offset' => $offset, 'total' => $total, 'has_more' => ($offset + $limit) < $total, ], 'filter' => [ 'category' => $category, 'start' => $startDate, 'end' => $endDate, ], ]); } catch (\Exception $e) { return new JsonResult([ 'success' => false, 'error' => $e->getMessage(), ], Status::from(500)); } } #[Route(path: '/admin/analytics/api/export', method: Method::GET)] public function exportData(): JsonResult { try { $format = $_GET['format'] ?? 'json'; $category = $_GET['category'] ?? null; $days = (int) ($_GET['days'] ?? 30); $endDate = date('Y-m-d'); $startDate = date('Y-m-d', strtotime("-{$days} days")); $categoryFilter = $category ? AnalyticsCategory::tryFrom($category) : null; $data = $this->reportService->exportData($startDate, $endDate, $categoryFilter, $format); return new JsonResult([ 'success' => true, 'data' => $data, 'format' => $format, 'exported_at' => date('Y-m-d H:i:s'), 'period' => [ 'start' => $startDate, 'end' => $endDate, 'days' => $days, ], ]); } catch (\Exception $e) { return new JsonResult([ 'success' => false, 'error' => $e->getMessage(), ], Status::from(500)); } } #[Route(path: '/admin/analytics/api/track', method: Method::POST)] public function trackEvent(): JsonResult { try { $action = $_POST['action'] ?? null; $category = $_POST['category'] ?? 'user_behavior'; $properties = json_decode($_POST['properties'] ?? '{}', true); if (! $action) { return new JsonResult([ 'success' => false, 'error' => 'Action is required', ], Status::from(400)); } $categoryEnum = AnalyticsCategory::tryFrom($category); if (! $categoryEnum) { return new JsonResult([ 'success' => false, 'error' => 'Invalid category', ], Status::from(400)); } $this->analyticsCollector->trackAction($action, $categoryEnum, $properties); return new JsonResult([ 'success' => true, 'message' => 'Event tracked successfully', 'tracked_at' => date('Y-m-d H:i:s'), ]); } catch (\Exception $e) { return new JsonResult([ 'success' => false, 'error' => $e->getMessage(), ], Status::from(500)); } } }