{"repo": "adakash26434/akashdigital-wp", "files": {"includes/helpers.php": {"b3b6e2caa71fb31b0e2341a0671bbd5a493bc97d": {"t": 1786068385.1102471, "n": 75733, "h": "221460a137201e2d", "c": "getMessage());\n return 0;\n }\n}\n\nfunction redirectSelf(array $extra = []): void {\n $url = strtok($_SERVER['REQUEST_URI'] ?? '/', '?');\n $params = array_merge($_GET ?? [], $extra);\n if ($params) $url .= '?' . http_build_query($params);\n redirect($url);\n}\n\nfunction e($v): string {\n return htmlspecialchars((string)($v ?? ''), ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');\n}\n\n// नेपालीमा: Asset (CSS/JS/image) ko full URL banaune\nfunction asset(string $path): string {\n return rtrim(SITE_URL, '/') . '/assets/' . ltrim($path, '/');\n}\n\n// नेपालीमा: Site relative path lai full URL banaune\nfunction url(string $path): string {\n return rtrim(SITE_URL, '/') . '/' . ltrim($path, '/');\n}\n\n// नेपालीमा: Browser lai arko URL ma pathaune\nfunction redirect(string $path): void {\n header(\"Location: \" . url($path));\n exit;\n}\n\n// नेपालीमा: Flash message session ma store garne\nfunction setFlash(string $key, string $msg): void {\n if (session_status() === PHP_SESSION_NONE) session_start();\n $_SESSION['flash'][$key] = $msg;\n}\n\n// Legacy alias\nfunction flash(string $key, string $msg): void { setFlash($key, $msg); }\n\n// नेपालीमा: Flash message read garera mitaune (one-shot)\nfunction getFlash(string $key): ?string {\n if (session_status() === PHP_SESSION_NONE) session_start();\n $msg = $_SESSION['flash'][$key] ?? null;\n unset($_SESSION['flash'][$key]);\n return $msg;\n}\n\n// ── Site settings from key-value table ─────────────────────────\nfunction siteSettings(bool $refresh = false): array {\n static $cache = null;\n if ($refresh) $cache = null;\n if ($cache !== null) return $cache;\n $defaults = [\n 'site_name' => SITE_NAME,\n 'site_tagline' => 'Cooperative Software for Nepal',\n 'logo_url' => null,\n 'favicon_url' => null,\n 'company_name' => SITE_NAME,\n 'company_logo_url' => null,\n 'contact_email' => '',\n 'contact_phone' => '',\n 'address' => '',\n 'social_links' => [],\n 'whatsapp_number' => null,\n 'whatsapp_enabled' => true,\n 'whatsapp_message' => \"Hello! I'm interested in your software.\",\n 'whatsapp_label' => 'Support WhatsApp',\n 'maintenance_mode' => false,\n ];\n // Try to get site settings, but gracefully fall back to defaults if DB is unavailable\n try {\n $rows = @query(\"SELECT setting_key, setting_val FROM site_settings\");\n if (!empty($rows)) {\n $map = [];\n foreach ($rows as $r) $map[$r['setting_key']] = $r['setting_val'];\n if (isset($map['social_links'])) {\n $map['social_links'] = json_decode($map['social_links'], true) ?? [];\n }\n $cache = array_merge($defaults, $map);\n return $cache;\n }\n } catch (\\Throwable $e) { \n error_log('[helpers.php] siteSettings query failed: ' . $e->getMessage()); \n }\n $cache = $defaults;\n return $cache;\n} // यहाँ Bracket बन्द गरिएको छ\n\n/**\n * Homepage trust strip — cooperative clients / partners / provinces.\n * Single source for index.php, partners.php, and any other public surface.\n * Client count = unique(active CRM clients ∪ partners table) + admin offset.\n */\nfunction siteTrustStats(?array $settings = null): array {\n $s = $settings ?? siteSettings();\n $offsetRaw = $s['client_count_offset'] ?? '';\n $offset = ($offsetRaw !== '' && $offsetRaw !== null) ? (int)$offsetRaw : 300;\n\n $crm = [];\n try {\n $crm = query(\n \"SELECT org_name, logo_url, district, province FROM clients\n WHERE LOWER(TRIM(status)) = 'active'\n AND TRIM(org_name) IS NOT NULL AND TRIM(org_name) != ''\n ORDER BY org_name ASC\"\n );\n } catch (\\Throwable $e) {\n error_log('[helpers] siteTrustStats clients: ' . $e->getMessage());\n }\n\n $partners = [];\n try {\n $partners = query(\n \"SELECT name AS org_name, logo_url, district, '' AS province\n FROM partners ORDER BY position ASC, id ASC\"\n );\n } catch (\\Throwable $e) {\n error_log('[helpers] siteTrustStats partners: ' . $e->getMessage());\n }\n\n $seen = [];\n $merged = [];\n foreach (array_merge($crm, $partners) as $row) {\n $key = strtolower(trim((string)($row['org_name'] ?? '')));\n if ($key === '' || isset($seen[$key])) continue;\n $seen[$key] = true;\n $merged[] = $row;\n }\n\n $unique = count($merged);\n $clientCount = $unique + $offset;\n\n $marquee = $merged;\n if (count($marquee) > 40) {\n shuffle($marquee);\n $marquee = array_slice($marquee, 0, 40);\n }\n\n $coopLabel = trim((string)($s['stat_coop_clients_label'] ?? ''));\n $partnersLabel = trim((string)($s['stat_partners_label'] ?? ''));\n $provincesLabel = trim((string)($s['stat_provinces_label'] ?? ''));\n // Guard: admins sometimes put numbers in Label fields by mistake\n if ($coopLabel === '' || preg_match('/^[\\d.,+\\s%]+$/u', $coopLabel)) {\n $coopLabel = 'Cooperative Clients';\n }\n if ($partnersLabel === '' || preg_match('/^[\\d.,+\\s%]+$/u', $partnersLabel)) {\n $partnersLabel = 'Technology Partners';\n }\n if ($provincesLabel === '' || preg_match('/^[\\d.,+\\s%]+$/u', $provincesLabel)) {\n $provincesLabel = 'Provinces Covered';\n }\n\n return [\n 'client_count' => $clientCount,\n 'client_display' => $clientCount . '+',\n 'coop_label' => $coopLabel,\n 'partners_value' => trim((string)($s['stat_partners_value'] ?? '')) ?: '15+',\n 'partners_label' => $partnersLabel,\n 'provinces_value' => trim((string)($s['stat_provinces_value'] ?? '')) ?: '7',\n 'provinces_label' => $provincesLabel,\n 'marquee_items' => $marquee,\n 'unique_orgs' => $unique,\n ];\n}\n\n/** True when a public stat label means client HEADCOUNT (not retention / years / etc.). */\nfunction siteTrustLabelIsClientCount(string $label): bool {\n $l = mb_strtolower(trim($label));\n if ($l === '') return false;\n // Never overwrite metrics that only mention \"client\" incidentally\n if (preg_match('/retention|rate|satisfaction|uptime|response|year|experience|product|ticket|sla|nps|churn|revenue/', $l)) {\n return false;\n }\n // Headcount-style labels only\n return (bool)preg_match(\n '/^(happy\\s+)?clients?(?:\\s+served)?$|^(cooperative\\s+)?clients?$|clients?\\s+served|cooperatives?\\s+(served|trust)|सहकारी|ग्राहक/',\n $l\n );\n}\n\n/**\n * CTA subtitle with the same client count as the homepage trust strip.\n */\nfunction siteTrustCtaSubtitle(?array $settings = null): string {\n $t = siteTrustStats($settings);\n if (function_exists('isNepali') && isNepali()) {\n return $t['client_display'] . ' सहकारीहरू पहिले नै हाम्रो डिजिटल प्लेटफर्ममा चलिरहेका छन्। विशेषज्ञसँग कुरा गर्नुस।';\n }\n return 'Join ' . $t['client_display'] . ' happy clients already running on our digital platform. Talk to our experts about a solution tailored to your organisation.';\n}\n\n/**\n * Clean one impact-stat pair so messy admin values don't look broken publicly.\n * @return array{0:string,1:string,2:string,3:string} value, label, icon, hint\n */\nfunction siteStatNormalizeItem(array $row, int $index = 0): array {\n $defaults = [\n ['10+', 'Years of Experience', 'calendar', 'Years in the field'],\n ['650+', 'Happy Clients', 'users', 'Organisations we support'],\n ['7+', 'Major Products', 'layers', 'Core platforms live'],\n ['99.9%', 'Client Retention Rate', 'shield-check', 'Long-term partnerships'],\n ];\n $def = $defaults[$index] ?? ['—', 'Stat', 'star', ''];\n\n $val = trim((string)($row[0] ?? ''));\n $lab = trim((string)($row[1] ?? ''));\n $icon = trim((string)($row[2] ?? ''));\n $hint = trim((string)($row[3] ?? ''));\n\n if ($lab === '' || preg_match('/^[\\d.,+\\s%<]+$/u', $lab)) {\n $lab = $def[1];\n }\n if ($val === '') $val = $def[0];\n\n if (preg_match('/^([\\d,.]+)([A-Za-z].+)$/u', $val, $m)) {\n $val = $m[1] . ' ' . $m[2];\n }\n\n $ll = mb_strtolower($lab);\n\n if (preg_match('/year|experience|वर्ष/', $ll)) {\n if (preg_match('/(\\d+)\\s*years?/i', $val, $m) || preg_match('/(\\d+)\\s*years?/i', $lab, $m)) {\n $val = $m[1] . '+';\n } elseif (!preg_match('/\\d/', $val)) {\n $val = $def[0];\n }\n if ($icon === '') $icon = 'calendar';\n if ($hint === '') $hint = 'Years in the field';\n }\n\n if (preg_match('/product|platform|solution/', $ll)) {\n if ($val === '' || preg_match('/^<\\s*[\\d.]/u', $val) || preg_match('/\\bhr\\b|hour|min|ticket|response/i', $val)) {\n $val = '7+';\n }\n if ($icon === '') $icon = 'layers';\n if ($hint === '') $hint = 'Core platforms live';\n }\n\n if (preg_match('/retention|uptime|sla/', $ll)) {\n if ($val === '' || !preg_match('/\\d/', $val)) $val = '99.9%';\n if ($icon === '') $icon = 'shield-check';\n if ($hint === '') $hint = 'Long-term partnerships';\n }\n\n if (siteTrustLabelIsClientCount($lab)) {\n if ($icon === '') $icon = 'users';\n if ($hint === '') $hint = 'Live client count';\n }\n\n if ($icon === '') $icon = $def[2];\n if ($hint === '') $hint = $def[3];\n\n return [$val, $lab, $icon, $hint];\n}\n\n// ── Form helper functions — always available (not DB-dependent) ──────────────\n\nfunction formInput(string $label, string $name, mixed $value = '', array $opts = []): string {\n $type = $opts['type'] ?? 'text';\n $placeholder = $opts['placeholder'] ?? '';\n $requiredFlag = !empty($opts['required']) || in_array('required', $opts, true);\n $required = $requiredFlag ? ' required' : '';\n $attrs = $opts['attrs'] ?? '';\n $class = $opts['class'] ?? 'form-input';\n $id = $opts['id'] ?? $name;\n $html = '