SIMON Master Console Rebuild
True command center for SIMON + WEB360
This rebuild gives you a cleaner production spine: interactive tree, live viewer, guarded editor, dynamic graphics, architecture map, and note storage. It is designed to sit beside your existing
console.php
and become the stronger replacement path.
Dashboard
Tree
Viewer
System Map
File Registry
Notes
Files
15,282
Folders
406
Scanned Size
3.84 GB
PHP Files
876
Editable Text Files
12,545
File viewer
guarded to /htdocs
/connlink/test1/ui/old/gsearch_proxy.php
<?php /* ============================================================ * SIMON ยท Google Custom Search Proxy * ------------------------------------------------------------ * Upload to: /htdocs/connlink/test1/ui/gsearch_proxy.php * Reached at: https://www.gaylordsinclair.com/connlink/test1/ui/gsearch_proxy.php?q=QUERY * * Keeps GOOGLE_CSE_KEY and GOOGLE_CSE_CX on the server (secrets.php). * Caches each unique query for CACHE_TTL seconds to protect the * free 100/day quota. Normalizes the response to a compact shape: * { query, results:[{title, snippet, url, source, image}], meta:{...} } * * Query params: * q : query string (required) * num : 1..10 results (default 10) * start : 1..91 pagination offset (default 1) * safe : off | active (default off) * lr : language restrict, e.g. lang_en * gl : country code, e.g. us * ============================================================ */ header('Content-Type: application/json; charset=utf-8'); header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Methods: GET, OPTIONS'); if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { http_response_code(204); exit; } $q = trim((string)($_GET['q'] ?? '')); if ($q === '') { echo json_encode(['ok'=>false, 'err'=>'missing q']); exit; } /* ----- load secrets (tries /private/secure/ first, then local) ----- */ $secrets = []; $secretPaths = [ dirname($_SERVER['DOCUMENT_ROOT'] ?? '') . '/private/secure/secrets.php', __DIR__ . '/secrets.php', ]; foreach ($secretPaths as $sp) { if ($sp && file_exists($sp)) { $s = @include $sp; if (is_array($s)) { $secrets = $s; break; } } } if (!is_array($secrets) || empty($secrets['GOOGLE_CSE_KEY']) || empty($secrets['GOOGLE_CSE_CX'])) { http_response_code(200); // non-fatal: SIMON can still use DuckDuckGo + Wikipedia echo json_encode([ 'ok' => false, 'err' => 'Google CSE not configured. Add GOOGLE_CSE_KEY and GOOGLE_CSE_CX to secrets.php.', 'query' => $q, 'results' => [], ]); exit; } $KEY = $secrets['GOOGLE_CSE_KEY']; $CX = $secrets['GOOGLE_CSE_CX']; $num = max(1, min(10, intval($_GET['num'] ?? 10))); $start = max(1, min(91, intval($_GET['start'] ?? 1))); $safe = in_array(($_GET['safe'] ?? 'off'), ['off','active'], true) ? $_GET['safe'] : 'off'; $lr = preg_replace('/[^A-Za-z0-9_]/','', (string)($_GET['lr'] ?? '')); $gl = preg_replace('/[^a-z]/', '', strtolower((string)($_GET['gl'] ?? ''))); $params = [ 'key' => $KEY, 'cx' => $CX, 'q' => $q, 'num' => $num, 'start' => $start, 'safe' => $safe, ]; if ($lr !== '') $params['lr'] = $lr; if ($gl !== '') $params['gl'] = $gl; $upstream = 'https://www.googleapis.com/customsearch/v1?' . http_build_query($params); /* ----- cache ----- */ $CACHE_DIR = __DIR__ . '/cache'; $CACHE_TTL = 600; // 10 minutes if (!is_dir($CACHE_DIR)) { @mkdir($CACHE_DIR, 0755, true); } $ckey = sha1($upstream); $cfile = $CACHE_DIR . '/gsearch_' . $ckey . '.json'; if (file_exists($cfile) && (time() - filemtime($cfile)) < $CACHE_TTL) { header('X-SIMON-Cache: HIT'); readfile($cfile); exit; } /* ----- fetch ----- */ $ch = curl_init($upstream); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 12, CURLOPT_HTTPHEADER => [ 'Accept: application/json', 'User-Agent: SIMON/1.0 (+https://www.gaylordsinclair.com)', ], ]); $resp = curl_exec($ch); $http = curl_getinfo($ch, CURLINFO_HTTP_CODE); $err = curl_error($ch); curl_close($ch); if ($resp === false || $http >= 500) { if (file_exists($cfile)) { header('X-SIMON-Cache: STALE'); readfile($cfile); exit; } http_response_code(502); echo json_encode(['ok'=>false,'err'=>'upstream failed','detail'=>$err,'status'=>$http,'query'=>$q]); exit; } $raw = json_decode($resp, true); if (!is_array($raw)) { http_response_code(502); echo json_encode(['ok'=>false,'err'=>'bad upstream json','query'=>$q]); exit; } /* ----- normalize ----- */ $items = []; if (!empty($raw['items']) && is_array($raw['items'])) { foreach ($raw['items'] as $it) { $img = ''; if (!empty($it['pagemap']['cse_image'][0]['src'])) { $img = $it['pagemap']['cse_image'][0]['src']; } elseif (!empty($it['pagemap']['cse_thumbnail'][0]['src'])) { $img = $it['pagemap']['cse_thumbnail'][0]['src']; } $items[] = [ 'title' => $it['title'] ?? '', 'snippet' => $it['snippet'] ?? ($it['htmlSnippet'] ?? ''), 'url' => $it['link'] ?? '', 'source' => $it['displayLink'] ?? '', 'image' => $img, ]; } } $out = [ 'ok' => true, 'query' => $q, 'results' => $items, 'meta' => [ 'total' => (int)($raw['searchInformation']['totalResults'] ?? 0), 'time' => (float)($raw['searchInformation']['searchTime'] ?? 0), 'next' => $raw['queries']['nextPage'][0]['startIndex'] ?? null, ], ]; $encoded = json_encode($out, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE); @file_put_contents($cfile, $encoded, LOCK_EX); header('X-SIMON-Cache: MISS'); echo $encoded;
Save file
Quick jump
open a path
Open