Site Builder
Editing:
boundary.php
writable 0666
<?php /************************************************************************** * boundary.php – Creator sets or adjusts their geofence * ------------------------------------------------------ * Requirements: * • PHP 8.1+ * • Must live in /social/ or be copied into /social/<slug>/ *************************************************************************/ // ---------- locate slug (same helper used before) ---------------------- $slug=$_GET['user']??''; if($slug===''){ if(isset($_SERVER['PATH_INFO'])) $slug=trim($_SERVER['PATH_INFO'],'/'); elseif(preg_match('~/boundary\.php/([^/?]+)~',$_SERVER['REQUEST_URI'],$m))$slug=$m[1]; else $slug=basename(dirname(__FILE__)); // when copied into /social/<slug>/ } $slug=preg_replace('/[^a-z0-9_]/i','',$slug); $root=$_SERVER['DOCUMENT_ROOT']; $dir="$root/social/$slug"; if($slug===''||!is_dir($dir)) { http_response_code(400); exit('Invalid user'); } $file="$dir/boundary.json"; $boundary=is_file($file)?json_decode(file_get_contents($file),true):null; // ---------- save (AJAX) ------------------------------------------------- if($_SERVER['REQUEST_METHOD']==='POST'){ $raw=file_get_contents('php://input'); $j=json_decode($raw,true); if(!isset($j['lat'],$j['lon'],$j['radius_km'])){http_response_code(400);exit;} file_put_contents($file,json_encode($j,JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES),LOCK_EX); echo '{"success":true}'; exit; } ?><!doctype html><html lang="en"><head> <meta charset="utf-8"><title>Set Geofence – @<?=htmlspecialchars($slug)?></title> <meta name="viewport" content="width=device-width,initial-scale=1"> <style> body{font-family:system-ui,Arial,sans-serif;background:#f5f8fb;margin:0;color:#234} .top{background:#eee;padding:.8em 1.2em;font-weight:900} .container{max-width:500px;margin:2rem auto;padding:0 1rem;text-align:center} #canvas{border:1px solid #ccd;width:260px;height:260px;border-radius:50%;margin:1rem auto} button{cursor:pointer;border:none;border-radius:8px;font-weight:700;padding:.6rem 1.4rem} #save{background:#2357d7;color:#fff;margin-top:1.2rem} #locate{background:#4caf50;color:#fff;margin-top:1.2rem} select{padding:.5rem;border:1px solid #b7c2df;border-radius:7px;font-size:1rem} .lock{color:#c00;font-weight:700;margin-top:2rem} </style> </head><body> <div class="top"><a href="/" style="text-decoration:none;color:#2a3ca5">BestDealOn</a> » Geofence</div> <div class="container"> <h1>Geofence for @<?=htmlspecialchars($slug)?></h1> <!-- step 1 locate --> <button id="locate"<?php if($boundary)echo'style="display:none"';?>>Locate Me</button> <!-- step 2 radius selector --> <div id="radiusWrap" style="display:<?= $boundary?'block':'none'?>"> <p>Select radius: <select id="radius"> <?php foreach([0.5,1,2,5,10] as $r): ?> <option value="<?=$r?>"<?=$boundary&&$boundary['radius_km']==$r?' selected':''?>><?=$r?> km</option> <?php endforeach; ?> </select> </p> <canvas id="canvas" width="260" height="260"></canvas> <button id="save">Save Boundary</button> <div id="msg"></div> </div> <!-- lock notice (shown by JS if user is outside fence) --> <div id="lock" class="lock" style="display:none">🔒 You are outside the current geofence and cannot modify it.</div> </div> <script> let center=null; // {lat,lon} let boundary = <?= json_encode($boundary) ?>; const canvas=document.getElementById('canvas'); const ctx=canvas.getContext('2d'); const radiusSel=document.getElementById('radius'); const draw=()=>{ ctx.clearRect(0,0,260,260); if(!boundary) return; const rPx = boundary.radius_km*20; // visual scale 1 km ≈ 20 px ctx.fillStyle='#ffe1e1'; ctx.beginPath(); ctx.arc(130,130,rPx,0,Math.PI*2);ctx.fill(); ctx.fillStyle='#e62a19'; ctx.beginPath();ctx.arc(130,130,4,0,Math.PI*2);ctx.fill(); }; draw(); /* locate current position */ document.getElementById('locate')?.addEventListener('click',()=>{ navigator.geolocation.getCurrentPosition(pos=>{ center={lat:pos.coords.latitude,lon:pos.coords.longitude}; boundary={lat:center.lat,lon:center.lon,radius_km:+radiusSel.value}; document.getElementById('radiusWrap').style.display='block'; draw(); },err=>alert('Unable to get location – '+err.message),{enableHighAccuracy:false,timeout:8000}); }); /* update radius preview */ radiusSel.onchange=()=>{ if(boundary){boundary.radius_km=+radiusSel.value;draw();} }; /* save */ document.getElementById('save').onclick=async()=>{ if(!boundary){alert('Locate yourself first');return;} boundary.radius_km = +radiusSel.value; const r=await fetch(location.href,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(boundary)}); document.getElementById('msg').textContent = r.ok?'✅ Saved':'❌ Error'; }; /* optional: block edits if viewer is outside existing fence */ if(boundary){ navigator.geolocation.getCurrentPosition(pos=>{ const dist=hv(pos.coords.latitude,pos.coords.longitude,boundary.lat,boundary.lon); if(dist>boundary.radius_km){ document.getElementById('radiusWrap').style.display='none'; document.getElementById('lock').style.display='block'; } }); } function hv(a,b,c,d){const R=6371,rad=x=>x*Math.PI/180; const dLa=rad(c-a),dLo=rad(d-b); const aa=Math.sin(dLa/2)**2+Math.cos(rad(a))*Math.cos(rad(c))*Math.sin(dLo/2)**2; return 2*R*Math.atan2(Math.sqrt(aa),Math.sqrt(1-aa)); } </script> </body></html>
Save changes
Create folder
writable 0777
Create
Cancel