SiteโฏBuilder
Editing:
links.php
writable 0666
<script src="/geo/geofence-guard.js" defer></script><?php /************************************************************************** * LINKSย EDITOR โ Business & Social (autoโdetect) * ---------------------------------------------------------------------- * If ?user=slug โ /social/<slug>/links.json * If ?ph=######## โ /ph/<phone>/links.json * ยฉย 2025ย BestDealOn โ PHPย 8.1+ *************************************************************************/ // --------------------------------------------------------- // 1. Figure out which mode weโre in (?user vs ?ph) // --------------------------------------------------------- $root = $_SERVER['DOCUMENT_ROOT']; $slug = preg_replace('/[^a-z0-9_]/i','', $_GET['user'] ?? ''); $ph = preg_replace('/\D/','', $_GET['ph'] ?? ''); if ($slug) { $dir = "$root/social/$slug"; $file = "$dir/links.json"; $label= '@'.$slug; } elseif ($ph && strlen($ph)===10) { // US 10โdigit $dir = "$root/ph/$ph"; $file = "$dir/links.json"; $label= $ph; } else { lookup(); // nothing valid supplied } // bail early if folder invalid if (!is_dir($dir)) lookup('Profile not found.'); // --------------------------------------------------------- // 2. Lookup screen helper (shown when no query params) // --------------------------------------------------------- function lookup(string $err=''){ ?> <!DOCTYPE html><html lang="en"><head> <meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"> <title>Edit Links | BestDealOn</title> <style> body{background:#f6f8fb;font-family:system-ui,Arial,sans-serif;margin:0;color:#234} .wrap{max-width:480px;margin:3em auto;background:#fff;padding:2em;border-radius:18px; box-shadow:0 2px 18px #dde3fa50;text-align:center} h1{font-size:1.5em;margin-bottom:.9em} input{width:100%;padding:.7em;border:1.4px solid #b7c2df;border-radius:7px;font-size:1.05em} button{margin-top:1em;padding:.7em 1.6em;font-size:1.05em;font-weight:700;background:#2357d7; color:#fff;border:none;border-radius:8px;cursor:pointer} .err{color:#c62828;margin-bottom:.8em} </style></head><body> <div class="wrap"> <h1>Lookย upย Yourย Links</h1> <?php if($err) echo "<div class='err'>$err</div>"; ?> <form method="get" style="display:flex;flex-direction:column;gap:.8rem"> <input type="text" name="user" placeholder="@username"> <div>โย orย โ</div> <input type="tel" name="ph" placeholder="10โdigitย phone"> <button type="submit">Loadย Links</button> </form> </div></body></html><?php exit; } // --------------------------------------------------------- // 3. Read + write JSON (AJAX save) // --------------------------------------------------------- if ($_SERVER['REQUEST_METHOD']==='POST'){ $json = file_get_contents('php://input'); if (!is_dir($dir)) mkdir($dir,0777,true); file_put_contents($file,$json,LOCK_EX); echo '{"success":true}'; exit; } $links = is_file($file) ? json_decode(file_get_contents($file),true,512,JSON_THROW_ON_ERROR):[]; if(!is_array($links)) $links=[]; // --------------------------------------------------------- // 4. Page HTML // --------------------------------------------------------- ?><!doctype html><html lang="en"><head> <meta charset="utf-8"><title>Edit Links โ <?= htmlspecialchars($label) ?></title> <meta name="viewport" content="width=device-width,initial-scale=1"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css" referrerpolicy="no-referrer"> <style> :root{ --bg:#f5f8fb;--fg:#234;--card:#fffbe6;--card-brd:#ffd973; --accent:#2357d7;--accent-dk:#1347c0;--warn:#c9302c; } body{margin:0;font-family:system-ui,Arial,sans-serif;background:var(--bg);color:var(--fg)} .top{background:#eee;padding:.8em 1.2em;font-weight:900} a{color:var(--accent);text-decoration:none} .container{max-width:820px;margin:2.4rem auto;padding:0 1rem} h1{font-size:1.55rem;margin:.2em 0 1.2rem} #list{list-style:none;margin:0;padding:0} .item{background:var(--card);border:2px solid var(--card-brd);border-radius:18px; box-shadow:0 3px 20px #f5db9c55;padding:1.3rem 1.2rem;margin-bottom:1.35rem; display:flex;flex-direction:column;gap:.65rem} .item.dragging{opacity:.55} .item input,.item textarea{ width:100%;padding:.55rem;border:1px solid #b7c2df;border-radius:8px;font-size:1.04rem} .item input.url{font-family:monospace} .row-btns{display:flex;gap:.65rem;margin-top:.2rem} .move,.del{padding:.45rem .75rem;border-radius:8px;font-weight:700;border:none;cursor:pointer} .move{background:#aac8ff;color:#103e9d} .move:hover{background:#90b4ff} .del {background:#ffd5d5;color:var(--warn)} .del:hover{background:#ffcbcb} #addBtn{background:var(--accent);color:#fff;font-size:1.03rem;padding:.6rem 1.2rem;margin-top:.4rem} #addBtn:hover{background:var(--accent-dk)} #saveBtn{background:#ef8f13;color:#fff;font-size:1.08rem;padding:.68rem 2rem} #msg{font-weight:700;margin-top:1rem} </style> <!-- universal geofence (works for /social & /ph) --> </head><body> <div class="top"><a href="/">BestDealOn</a>ย ยปย Linksย Editor</div> <div class="container"> <h1><i class="fa-solid fa-link"></i> Links forย <?= htmlspecialchars($label) ?></h1> <ul id="list"></ul> <button id="addBtn"><i class="fa-solid fa-plus"></i>ย Addย Link</button> <div style="margin-top:2rem;text-align:right"> <button id="saveBtn"><i class="fa-solid fa-floppy-disk"></i>ย Saveย All</button> </div> <div id="msg"></div> </div> <script> /* ---------- initial data from PHP --------- */ const links = <?= json_encode($links, JSON_UNESCAPED_SLASHES) ?>; const list = document.getElementById('list'); /* ---------- helpers ----------------------- */ function esc(s){return String(s).replace(/[&<>"']/g,m=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[m]));} function makeItem(o={title:'',url:'',excerpt:''}){ const li=document.createElement('li'); li.className='item'; li.draggable=true; li.innerHTML=` <input class="title" placeholder="Title" value="${esc(o.title)}"> <input class="url" placeholder="https://example.com" value="${esc(o.url)}"> <textarea rows="2" class="ex" placeholder="Short excerptโฆ">${esc(o.excerpt)}</textarea> <div class="row-btns"> <button class="move up">โ</button> <button class="move down">โ</button> <button class="del">โ</button> </div>`; return li; } /* ---------- render existing ---------- */ if(links.length) links.forEach(l=>list.appendChild(makeItem(l))); else list.appendChild(makeItem()); /* ---------- D&D reโorder ------------- */ let dragEl; list.addEventListener('dragstart',e=>{dragEl=e.target;dragEl.classList.add('dragging');}); list.addEventListener('dragend', e=>{dragEl.classList.remove('dragging');dragEl=null;}); list.addEventListener('dragover', e=>{ e.preventDefault(); const after=[...list.querySelectorAll('.item:not(.dragging)')] .find(li=>e.clientY<li.getBoundingClientRect().top+li.offsetHeight/2); list.insertBefore(dragEl,after||null); }); /* ---------- add / move / delete ------- */ document.getElementById('addBtn').onclick=()=>list.appendChild(makeItem()); list.addEventListener('click',e=>{ const li=e.target.closest('.item'); if(!li) return; if(e.target.classList.contains('del')) li.remove(); if(e.target.classList.contains('up')) li.previousElementSibling&&list.insertBefore(li,li.previousElementSibling); if(e.target.classList.contains('down'))li.nextElementSibling&&list.insertBefore(li.nextElementSibling,li); }); /* ---------- save ---------------------- */ document.getElementById('saveBtn').onclick=async()=>{ const arr=[...list.children].map(li=>({ title :li.querySelector('.title').value.trim(), url :li.querySelector('.url').value.trim(), excerpt:li.querySelector('.ex').value.trim() })).filter(x=>x.title&&x.url); const r=await fetch(location.href,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(arr)}); const m=document.getElementById('msg'); m.textContent=r.ok?'โ ย Saved':'โย Error'; m.style.color=r.ok?'green':'#c62828'; setTimeout(()=>m.textContent='',2000); }; </script> </body></html>
Save changes
Create folder
writable 0777
Create
Cancel