. Returns null if the URL is empty or the host * isn't recognized (in which case we fall back to a plain link). */ public function getVideoEmbedUrl(): ?string { $tenant = app(\App\Tenancy\TenantManager::class)->current(); $raw = trim((string) ($tenant?->settings['faq_video_url'] ?? '')); if ($raw === '') return null; // YouTube: watch?v=ID | youtu.be/ID | shorts/ID if (preg_match('#(?:youtube\.com/(?:watch\?v=|shorts/|embed/)|youtu\.be/)([A-Za-z0-9_-]{6,})#', $raw, $m)) { return 'https://www.youtube.com/embed/' . $m[1]; } // Vimeo: vimeo.com/ID if (preg_match('#vimeo\.com/(\d+)#', $raw, $m)) { return 'https://player.vimeo.com/video/' . $m[1]; } return null; } public function getVideoRawUrl(): ?string { $tenant = app(\App\Tenancy\TenantManager::class)->current(); $raw = trim((string) ($tenant?->settings['faq_video_url'] ?? '')); return $raw !== '' ? $raw : null; } public function getGrouped(): array { $q = mb_strtolower(trim($this->search)); $lc = Hints::locale(); $grouped = Hints::byArea(); if ($q === '') return $grouped; $out = []; foreach ($grouped as $area => $hints) { $matched = array_filter($hints, function ($h) use ($q, $lc) { $t = mb_strtolower(($h['title'][$lc] ?? '') . ' ' . ($h['body'][$lc] ?? '')); return str_contains($t, $q); }); if (! empty($matched)) $out[$area] = $matched; } return $out; } }