goals()->where('is_active', true)->get(); foreach ($goals as $goal) { if ($this->alreadyConverted($goal, $session)) { continue; } if ($this->matches($goal, $session, $payload)) { GoalConversion::create([ 'goal_id' => $goal->id, 'website_id' => $website->id, 'visitor_id' => $visitor->id, 'analytics_session_id' => $session->id, 'value' => $goal->default_value, 'converted_at' => $now, ]); } } } private function alreadyConverted(Goal $goal, AnalyticsSession $session): bool { return GoalConversion::where('goal_id', $goal->id) ->where('analytics_session_id', $session->id) ->exists(); } private function matches(Goal $goal, AnalyticsSession $session, array $payload): bool { return match ($goal->type) { 'url_destination' => $this->matchesUrlDestination($goal, $payload), 'event_match' => $this->matchesEvent($goal, $payload), 'duration' => $this->matchesDuration($goal, $session), 'pages_per_session' => $this->matchesPagesPerSession($goal, $session), default => false, }; } private function matchesUrlDestination(Goal $goal, array $payload): bool { $conditions = $goal->conditions; $path = $payload['path'] ?? ''; $targetPath = $conditions['path'] ?? ''; $matchType = $conditions['match_type'] ?? 'exact'; if (! $path || ! $targetPath) { return false; } return match ($matchType) { 'exact' => $path === $targetPath, 'starts_with' => str_starts_with($path, $targetPath), 'contains' => str_contains($path, $targetPath), 'regex' => (bool) @preg_match($targetPath, $path), default => false, }; } private function matchesEvent(Goal $goal, array $payload): bool { if (($payload['type'] ?? '') !== 'event') { return false; } $conditions = $goal->conditions; $eventName = $conditions['event_name'] ?? ''; if (! $eventName || ($payload['event_name'] ?? '') !== $eventName) { return false; } $requiredCategory = $conditions['event_category'] ?? null; if ($requiredCategory && ($payload['event_category'] ?? '') !== $requiredCategory) { return false; } return true; } private function matchesDuration(Goal $goal, AnalyticsSession $session): bool { $requiredSeconds = $goal->conditions['seconds'] ?? 0; return $session->duration >= $requiredSeconds; } private function matchesPagesPerSession(Goal $goal, AnalyticsSession $session): bool { $requiredPages = $goal->conditions['page_count'] ?? 0; return $session->pages_count >= $requiredPages; } }