Site Builder
Editing:
subscriptions.php
writable 0666
<?php /***************************************************************** * Admin · Manual subscription overrides (v2 – JSON sync) * /members/admin/subscriptions.php *****************************************************************/ require_once __DIR__.'/../lib/auth.php'; require_login(); if (current_user()['role'] !== 'admin') forbidden_page(); require_once __DIR__.'/../lib/db.php'; /** * Toggle the "premium" flag inside /ph/<phone>/profile.json * or /social/<handle>/profile.json. * * @param string $username the same value stored in users.username * @param bool $isPremium true = "on", false = "off" */ function update_profile_json(string $username, bool $isPremium): void { $root = rtrim($_SERVER['DOCUMENT_ROOT'], '/'); if (ctype_digit($username) && strlen($username) === 10) { // business $file = $root . "/ph/$username/profile.json"; } else { // social $slug = ltrim($username, '@'); $file = $root . "/social/$slug/profile.json"; } if (!is_readable($file)) { /* nothing to update – silent return */ return; } $data = json_decode(file_get_contents($file), true); if (!is_array($data)) return; // corrupt? $data['premium'] = $isPremium ? 'on' : 'off'; file_put_contents( $file, json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES), LOCK_EX ); } /* ---------- handle POST actions --------------------------------- */ if ($_SERVER['REQUEST_METHOD'] === 'POST') { if (!hash_equals($_SESSION['csrf'] ?? '', $_POST['csrf'] ?? '')) exit('Bad CSRF'); $uid = intval($_POST['uid'] ?? 0); $mode = $_POST['mode'] ?? ''; /* we need the username to locate the profile.json later */ $uRow = $db->prepare('SELECT username FROM users WHERE id = ?'); $uRow->execute([$uid]); $uRec = $uRow->fetch(PDO::FETCH_ASSOC); if (!$uRec) exit('Unknown user'); $username = $uRec['username']; $premiumFlag = false; // computed below for JSON update switch ($mode) { case 'grantYear': $db->prepare('UPDATE users SET premium_until = DATE_ADD(NOW(), INTERVAL 1 YEAR) WHERE id = ?') ->execute([$uid]); $premiumFlag = true; break; case 'remove': $db->prepare('UPDATE users SET premium_until = NULL WHERE id = ?') ->execute([$uid]); $premiumFlag = false; break; case 'custom': $date = preg_replace('/[^0-9\-]/', '', $_POST['date'] ?? ''); if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) { $db->prepare('UPDATE users SET premium_until = ? WHERE id = ?') ->execute([$date, $uid]); $premiumFlag = (strtotime($date) > time()); } else { /* bad date – leave DB untouched and keep existing premium flag */ $sel = $db->prepare('SELECT premium_until FROM users WHERE id = ?'); $sel->execute([$uid]); $cur = $sel->fetchColumn(); $premiumFlag = ($cur && strtotime($cur) > time()); } break; } /* --- keep the profile.json in sync with DB --- */ update_profile_json($username, $premiumFlag); header('Location: subscriptions.php?saved=1'); exit; } /* ---------- table data ------------------------------------------ */ $search = trim($_GET['q'] ?? ''); $params = []; $where = ''; if ($search !== '') { $where = 'WHERE email LIKE ? OR username LIKE ?'; $params = ["%$search%", "%$search%"]; } $rows = $db->prepare(" SELECT id, username, email, premium_until FROM users $where ORDER BY id DESC LIMIT 500 "); $rows->execute($params); /* ---------- CSRF token ------------------------------------------ */ $_SESSION['csrf'] = bin2hex(random_bytes(16)); ?> <!doctype html> <title>Subscriptions – BestDealOn</title> <meta name=viewport content="width=device-width,initial-scale=1"> <style> :root{--b:#0066ff;--bg:#f5f7fc;--fg:#111;--ok:#0a7b38} *{box-sizing:border-box;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif} body{margin:0;background:var(--bg);color:var(--fg)} main{max-width:920px;margin:2.4rem auto;padding:0 1rem} h1{margin:0 0 1.6rem;font-size:1.7rem} table{width:100%;border-collapse:collapse;font-size:.93rem} th,td{padding:.55rem .7rem;border-bottom:1px solid #e2e8f3;text-align:left} th{background:#eff3ff;font-weight:600} .badge{display:inline-block;padding:.25rem .55rem;border-radius:12px;font-size:.8rem;font-weight:700} .active{background:#d1f1d9;color:var(--ok)} .none {background:#ffe1e1;color:#b40000} form[action] select,form[action] input[type=date]{padding:.25rem .45rem;font:inherit} form[action] button{padding:.25rem .6rem;font:inherit;border:1px solid #ccc;border-radius:6px;cursor:pointer} .notice{background:#d7f4d7;color:var(--ok);padding:.7rem 1rem;border-radius:8px;margin-bottom:1.4rem} </style> <main> <h1>Manual subscription overrides</h1> <?php if(isset($_GET['saved'])):?><p class=notice>✔ Changes saved.</p><?php endif;?> <form style="margin-bottom:1.4rem"> <input name=q value="<?=htmlspecialchars($search)?>" placeholder="Search user / email" style="padding:.55rem .75rem;width:260px;border:1px solid #ccd;border-radius:6px"> <button style="padding:.55rem 1.1rem;border:0;background:var(--b);color:#fff;border-radius:6px"> Filter </button> </form> <table> <tr><th>ID</th><th>User</th><th>E‑mail</th><th>Status</th><th>Action</th></tr> <?php foreach($rows as $r):?> <tr> <td><?=$r['id']?></td> <td><?=htmlspecialchars($r['username'])?></td> <td><?=htmlspecialchars($r['email'])?></td> <td> <?php if($r['premium_until'] && strtotime($r['premium_until']) > time()):?> <span class="badge active">Premium until <?=date('Y‑m‑d',strtotime($r['premium_until']))?></span> <?php else:?> <span class="badge none">No subscription</span> <?php endif;?> </td> <td> <form method=post style="display:flex;gap:.4rem;align-items:center"> <input type=hidden name=csrf value="<?=$_SESSION['csrf']?>"> <input type=hidden name=uid value="<?=$r['id']?>"> <select name=mode onchange="this.form.submit()"> <option value="">— choose —</option> <option value="grantYear">Grant 1 year</option> <option value="remove">Remove premium</option> </select> <!-- custom date --> <input type=date name=date> <button name=mode value=custom>Set</button> </form> </td> </tr> <?php endforeach?> </table> <p style="margin-top:2rem"><a href="users.php">← Back to user manager</a></p> </main>
Save changes
Create folder
writable 0777
Create
Cancel