e só entra na página // quando se carrega no botão; o link «Abrir no Google Maps» funciona sem ele; // - review_avatar_url(): o servidor guarda a foto uma vez em uploads/reviews/ // e o browser pede-a ao próprio site. function map_click_to_load(string $iframeHtml, string $mapsLink = ''): string { if (trim($iframeHtml) === '') return ''; static $n = 0; $id = 'map-consent-' . (++$n); $esc = fn(string $s): string => htmlspecialchars($s, ENT_QUOTES, 'UTF-8'); $link = $mapsLink !== '' ? 'Abrir no Google Maps' : ''; return ''; } function review_avatar_url(array $r): string { $src = (string) ($r['author_photo'] ?? ''); if ($src === '' || !preg_match('#^https://[a-z0-9.-]*googleusercontent\.com/#i', $src)) return ''; $base = substr(sha1($src), 0, 24); $dir = dirname(__DIR__) . '/uploads/reviews/'; foreach (['jpg', 'png', 'webp'] as $ext) { if (is_file($dir . $base . '.' . $ext)) return base_url('uploads/reviews/' . $base . '.' . $ext); } // Uma falha recente não se repete a cada visita (cada tentativa custa até 4 s). $fail = $dir . '.' . $base . '.fail'; if (is_file($fail) && filemtime($fail) > time() - 86400) return ''; if (!function_exists('curl_init')) return ''; $ch = curl_init($src); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_FOLLOWLOCATION => true, CURLOPT_MAXREDIRS => 2, CURLOPT_TIMEOUT => 4, CURLOPT_CONNECTTIMEOUT => 3, CURLOPT_PROTOCOLS => CURLPROTO_HTTPS, ]); $bin = curl_exec($ch); curl_close($ch); $info = (is_string($bin) && strlen($bin) > 0 && strlen($bin) < 512 * 1024) ? @getimagesizefromstring($bin) : false; $ext = $info ? (['image/jpeg' => 'jpg', 'image/png' => 'png', 'image/webp' => 'webp'][$info['mime']] ?? null) : null; if (!is_dir($dir)) @mkdir($dir, 0775, true); if ($ext === null || !@file_put_contents($dir . $base . '.' . $ext, $bin)) { @touch($fail); return ''; } return base_url('uploads/reviews/' . $base . '.' . $ext); }