"/foo") if ($BASE && $BASE !== '/' && strpos($path, $BASE) === 0) { $path = substr($path, strlen($BASE)); } // Normalize empty string to "/" $path = ($path === '') ? '/' : $path; // Normalize trailing slash: "/foo/" -> "/foo" if ($path !== '/') { $path = rtrim($path, '/'); } /* ---------------------- TEMP DEBUG ROUTE -------------------- */ /* Visit https://www.dumpdesk.com/app/__debug to see what PHP sees */ if ($path === '/__debug') { header('Content-Type: text/plain; charset=UTF-8'); echo "uriPath: " . ($uriPath ?? '') . "\n"; echo "scriptName: " . ($scriptName ?? '') . "\n"; echo "reportedDir: " . ($reportedDir ?? '') . "\n"; echo "BASE: " . ($BASE ?? '') . "\n"; echo "path: " . $path . "\n"; echo "logged in: " . (!empty($_SESSION['user_id']) ? 'yes' : 'no') . "\n"; exit; } /* ---------------------- public landing/health -------------------- */ if ($path === '/' || $path === '/index.php') { // If logged in -> Jobs, else Admin Login if (!empty($_SESSION['user_id'])) { header('Location: ' . ($scriptDir ?: '') . '/jobs'); exit; } header('Location: ' . ($scriptDir ?: '') . '/admin/login'); exit; } if ($path === '/health') { echo "OK"; exit; } /* ================================================================ * AUTH (simple starter) * ================================================================ */ if ($path === '/admin/login') { if ($_SERVER['REQUEST_METHOD'] !== 'POST') { include __DIR__ . '/pages/admin/login.php'; exit; } $user = trim($_POST['user'] ?? ''); $pass = trim($_POST['pass'] ?? ''); if ($user !== '' && $pass !== '') { $_SESSION['user_id'] = 1; $_SESSION['user_name'] = $user; flash('Welcome back!'); header('Location: ' . ($scriptDir ?: '') . '/jobs'); exit; } else { flash('Invalid login.'); header('Location: ' . ($scriptDir ?: '') . '/admin/login'); exit; } } if ($path === '/logout') { session_destroy(); header('Location: ' . ($scriptDir ?: '') . '/admin/login'); exit; } /* ------------- guard for admin pages ------------- */ function require_admin(): void { if (empty($_SESSION['user_id'])) { $base = rtrim(dirname($_SERVER['SCRIPT_NAME'] ?? ''), '/'); // If PHP reports "/", fall back to "/app" when URI starts with it if ($base === '' || $base === '/') { $uriPath = parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH) ?? '/'; $base = ((strpos($uriPath, '/app/') === 0 || $uriPath === '/app') ? '/app' : ''); } header('Location: ' . ($base ?: '') . '/admin/login'); exit; } } /* ================================================================ * DRIVERS (Admin) * ================================================================ */ if ($path === '/drivers') { require_admin(); $pdo = db(); $drivers = $pdo->query('SELECT id, name, phone FROM drivers ORDER BY name')->fetchAll(PDO::FETCH_ASSOC); include __DIR__ . '/pages/admin/drivers.php'; exit; } if ($path === '/drivers/store' && $_SERVER['REQUEST_METHOD']==='POST') { require_admin(); $pdo = db(); $name = trim($_POST['name'] ?? ''); $phone = trim($_POST['phone'] ?? ''); if ($name !== '') { $stmt = $pdo->prepare('INSERT INTO drivers(name,phone) VALUES(?,?)'); $stmt->execute([$name, $phone !== '' ? $phone : null]); flash('Driver added.'); } $base = rtrim(dirname($_SERVER['SCRIPT_NAME'] ?? ''), '/'); if ($base === '' || $base === '/') { $base = ((strpos($uriPath, '/app/') === 0 || $uriPath === '/app') ? '/app' : ''); } header('Location: ' . ($base ?: '') . '/drivers'); exit; } if ($path === '/drivers/delete' && $_SERVER['REQUEST_METHOD']==='POST') { require_admin(); $pdo = db(); $id = (int)($_POST['id'] ?? 0); if ($id > 0) { $stmt = $pdo->prepare('DELETE FROM drivers WHERE id=?'); $stmt->execute([$id]); flash('Driver deleted.'); } $base = rtrim(dirname($_SERVER['SCRIPT_NAME'] ?? ''), '/'); if ($base === '' || $base === '/') { $base = ((strpos($uriPath, '/app/') === 0 || $uriPath === '/app') ? '/app' : ''); } header('Location: ' . ($base ?: '') . '/drivers'); exit; } /* ================================================================ * CUSTOMERS (Admin) * ================================================================ */ if ($path === '/customers') { require_admin(); $pdo = db(); $customers = $pdo->query('SELECT id,name,phone,email,address,lat,lng FROM customers ORDER BY id DESC')->fetchAll(PDO::FETCH_ASSOC); include __DIR__ . '/pages/admin/customers.php'; exit; } if ($path === '/customers/store' && $_SERVER['REQUEST_METHOD']==='POST') { require_admin(); $pdo = db(); $name = trim($_POST['name'] ?? ''); $phone = trim($_POST['phone'] ?? ''); $email = trim($_POST['email'] ?? ''); $addr = trim($_POST['address'] ?? ''); $lat = ($_POST['lat'] ?? '') !== '' ? (float)$_POST['lat'] : null; $lng = ($_POST['lng'] ?? '') !== '' ? (float)$_POST['lng'] : null; if ($name !== '') { $stmt = $pdo->prepare('INSERT INTO customers(name,phone,email,address,lat,lng) VALUES(?,?,?,?,?,?)'); $stmt->execute([$name, $phone ?: null, $email ?: null, $addr ?: null, $lat, $lng]); flash('Customer added.'); } $base = rtrim(dirname($_SERVER['SCRIPT_NAME'] ?? ''), '/'); if ($base === '' || $base === '/') { $base = ((strpos($uriPath, '/app/') === 0 || $uriPath === '/app') ? '/app' : ''); } header('Location: ' . ($base ?: '') . '/customers'); exit; } if ($path === '/customers/delete' && $_SERVER['REQUEST_METHOD']==='POST') { require_admin(); $pdo = db(); $id = (int)($_POST['id'] ?? 0); if ($id > 0) { $stmt = $pdo->prepare('DELETE FROM customers WHERE id=?'); $stmt->execute([$id]); flash('Customer deleted.'); } $base = rtrim(dirname($_SERVER['SCRIPT_NAME'] ?? ''), '/'); if ($base === '' || $base === '/') { $base = ((strpos($uriPath, '/app/') === 0 || $uriPath === '/app') ? '/app' : ''); } header('Location: ' . ($base ?: '') . '/customers'); exit; } /* ================================================================ * DUMPSTERS (Admin) * ================================================================ */ if ($path === '/dumpsters') { require_admin(); $pdo = db(); $dumpsters = $pdo->query('SELECT id,label,size,status FROM dumpsters ORDER BY id DESC')->fetchAll(PDO::FETCH_ASSOC); include __DIR__ . '/pages/admin/dumpsters.php'; exit; } if ($path === '/dumpsters/store' && $_SERVER['REQUEST_METHOD']==='POST') { require_admin(); $pdo = db(); $label = trim($_POST['label'] ?? ''); $size = trim($_POST['size'] ?? ''); $st = trim($_POST['status'] ?? 'available'); if ($label !== '') { $stmt = $pdo->prepare('INSERT INTO dumpsters(label,size,status) VALUES(?,?,?)'); $stmt->execute([$label, $size !== '' ? $size : null, $st]); flash('Dumpster added.'); } $base = rtrim(dirname($_SERVER['SCRIPT_NAME'] ?? ''), '/'); if ($base === '' || $base === '/') { $base = ((strpos($uriPath, '/app/') === 0 || $uriPath === '/app') ? '/app' : ''); } header('Location: ' . ($base ?: '') . '/dumpsters'); exit; } if ($path === '/dumpsters/delete' && $_SERVER['REQUEST_METHOD']==='POST') { require_admin(); $pdo = db(); $id = (int)($_POST['id'] ?? 0); if ($id > 0) { $stmt = $pdo->prepare('DELETE FROM dumpsters WHERE id=?'); $stmt->execute([$id]); flash('Dumpster deleted.'); } $base = rtrim(dirname($_SERVER['SCRIPT_NAME'] ?? ''), '/'); if ($base === '' || $base === '/') { $base = ((strpos($uriPath, '/app/') === 0 || $uriPath === '/app') ? '/app' : ''); } header('Location: ' . ($base ?: '') . '/dumpsters'); exit; } /* ================================================================ * JOBS (Admin) – list / add / delete * ================================================================ */ if ($path === '/jobs') { require_admin(); $pdo = db(); $drivers = $pdo->query('SELECT id, name FROM drivers ORDER BY name')->fetchAll(PDO::FETCH_ASSOC); $sql = 'SELECT j.*, d.name AS driver_name FROM jobs j LEFT JOIN drivers d ON d.id = j.driver_id ORDER BY j.id DESC'; $jobs = $pdo->query($sql)->fetchAll(PDO::FETCH_ASSOC); include __DIR__ . '/pages/admin/jobs.php'; exit; } if ($path === '/jobs/store' && $_SERVER['REQUEST_METHOD']==='POST') { require_admin(); $pdo = db(); $type = $_POST['type'] ?? 'drop'; $address = trim($_POST['address'] ?? ''); $scheduled = $_POST['scheduled_at'] ?? null; $driver_id = !empty($_POST['driver_id']) ? (int)$_POST['driver_id'] : null; $lat = ($_POST['lat'] ?? '') !== '' ? (float)$_POST['lat'] : null; $lng = ($_POST['lng'] ?? '') !== '' ? (float)$_POST['lng'] : null; if ($address === '') { flash('Address is required.'); $base=rtrim(dirname($_SERVER['SCRIPT_NAME']??''),'/'); if ($base===''||$base==='/'){$base=((strpos($uriPath,'/app/')===0||$uriPath==='/app')?'/app':'');} header('Location: '.($base?:'').'/jobs'); exit; } $stmt = $pdo->prepare('INSERT INTO jobs(type,address,scheduled_at,driver_id,status,lat,lng) VALUES(?,?,?,?,?,?,?)'); $stmt->execute([$type, $address, $scheduled ?: null, $driver_id, 'new', $lat, $lng]); flash('Job added.'); $base = rtrim(dirname($_SERVER['SCRIPT_NAME'] ?? ''), '/'); if ($base === '' || $base === '/') { $base = ((strpos($uriPath, '/app/') === 0 || $uriPath === '/app') ? '/app' : ''); } header('Location: ' . ($base ?: '') . '/jobs'); exit; } if ($path === '/jobs/delete' && $_SERVER['REQUEST_METHOD']==='POST') { require_admin(); $pdo = db(); $id = (int)($_POST['id'] ?? 0); if ($id > 0) { $stmt = $pdo->prepare('DELETE FROM jobs WHERE id=?'); $stmt->execute([$id]); flash('Job deleted.'); } $base = rtrim(dirname($_SERVER['SCRIPT_NAME'] ?? ''), '/'); if ($base === '' || $base === '/') { $base = ((strpos($uriPath, '/app/') === 0 || $uriPath === '/app') ? '/app' : ''); } header('Location: ' . ($base ?: '') . '/jobs'); exit; } /* ================================================================ * JOBS (Admin) – Edit + Update * ================================================================ */ if ($path === '/jobs/edit') { require_admin(); $pdo = db(); $id = isset($_GET['id']) ? (int)$_GET['id'] : 0; $stmt = $pdo->prepare('SELECT * FROM jobs WHERE id = ?'); $stmt->execute([$id]); $job = $stmt->fetch(PDO::FETCH_ASSOC); if (!$job) { flash('Job not found.'); $base=rtrim(dirname($_SERVER['SCRIPT_NAME']??''),'/'); if ($base===''||$base==='/'){$base=((strpos($uriPath,'/app/')===0||$uriPath==='/app')?'/app':'');} header('Location: '.($base?:'').'/jobs'); exit; } $drivers = $pdo->query('SELECT id, name FROM drivers ORDER BY name')->fetchAll(PDO::FETCH_ASSOC); include __DIR__ . '/pages/admin/job_edit.php'; exit; } if ($path === '/jobs/update' && $_SERVER['REQUEST_METHOD']==='POST') { require_admin(); $pdo = db(); $id = (int)$_POST['id']; $type = $_POST['type'] ?? 'drop'; $address = trim($_POST['address'] ?? ''); $scheduled = $_POST['scheduled_at'] ?? null; $driver_id = !empty($_POST['driver_id']) ? (int)$_POST['driver_id'] : null; $lat = ($_POST['lat'] ?? '') !== '' ? (float)$_POST['lat'] : null; $lng = ($_POST['lng'] ?? '') !== '' ? (float)$_POST['lng'] : null; if ($id <= 0 || $address === '') { flash('Missing required fields.'); $base=rtrim(dirname($_SERVER['SCRIPT_NAME']??''),'/'); if ($base===''||$base==='/'){$base=((strpos($uriPath,'/app/')===0||$uriPath==='/app')?'/app':'');} header('Location: '.($base?:'').'/jobs'); exit; } $sql = 'UPDATE jobs SET type=:type, address=:address, scheduled_at=:scheduled_at, driver_id=:driver_id, lat=:lat, lng=:lng WHERE id=:id'; $stmt = $pdo->prepare($sql); $stmt->execute([ ':type' => $type, ':address' => $address, ':scheduled_at' => $scheduled ?: null, ':driver_id' => $driver_id, ':lat' => $lat, ':lng' => $lng, ':id' => $id, ]); flash('Job updated.'); $base = rtrim(dirname($_SERVER['SCRIPT_NAME'] ?? ''), '/'); if ($base === '' || $base === '/') { $base = ((strpos($uriPath, '/app/') === 0 || $uriPath === '/app') ? '/app' : ''); } header('Location: ' . ($base ?: '') . '/jobs'); exit; } /* ================================================================ * DUMP SITES (Admin) – full CRUD * ================================================================ */ if ($path === '/dumpsites') { require_admin(); $pdo = db(); $dumpsites = $pdo->query('SELECT * FROM dumpsites ORDER BY id DESC')->fetchAll(PDO::FETCH_ASSOC); // Try real view; if missing, render fallback so we know route is matched $view = __DIR__ . '/pages/admin/dumpsites.php'; if (is_file($view)) { include $view; } else { include __DIR__ . '/pages/_head.php'; echo '

Dump Sites

'; echo '

View missing at /app/pages/admin/dumpsites.php — showing fallback.

'; echo ''; foreach ($dumpsites as $s) { echo ''; } echo '
IDNameAddress
'.e($s['id']).''.e($s['name']).''.e($s['address'] ?? '').'
'; include __DIR__ . '/pages/_foot.php'; } exit; } if ($path === '/dumpsites/store' && $_SERVER['REQUEST_METHOD']==='POST') { require_admin(); $pdo = db(); $name = trim($_POST['name'] ?? ''); $addr = trim($_POST['address'] ?? ''); $acc = trim($_POST['accepted'] ?? ''); $fee = ($_POST['tipping_fee'] ?? '') !== '' ? (float)$_POST['tipping_fee'] : null; $phone = trim($_POST['phone'] ?? ''); $hours = trim($_POST['hours'] ?? ''); $notes = trim($_POST['notes'] ?? ''); $lat = ($_POST['lat'] ?? '') !== '' ? (float)$_POST['lat'] : null; $lng = ($_POST['lng'] ?? '') !== '' ? (float)$_POST['lng'] : null; if ($name === '') { flash('Name is required.'); $base=rtrim(dirname($_SERVER['SCRIPT_NAME']??''),'/'); if ($base===''||$base==='/'){$base=((strpos($uriPath,'/app/')===0||$uriPath==='/app')?'/app':'');} header('Location: '.($base?:'').'/dumpsites'); exit; } $stmt = $pdo->prepare('INSERT INTO dumpsites(name,address,accepted,tipping_fee,phone,hours,notes,lat,lng) VALUES(?,?,?,?,?,?,?,?,?)'); $stmt->execute([$name,$addr ?: null,$acc ?: null,$fee,$phone ?: null,$hours ?: null,$notes ?: null,$lat,$lng]); flash('Dump site added.'); $base = rtrim(dirname($_SERVER['SCRIPT_NAME'] ?? ''), '/'); if ($base === '' || $base === '/') { $base = ((strpos($uriPath, '/app/') === 0 || $uriPath === '/app') ? '/app' : ''); } header('Location: ' . ($base ?: '') . '/dumpsites'); exit; } if ($path === '/dumpsites/edit') { require_admin(); $pdo = db(); $id = (int)($_GET['id'] ?? 0); $stmt = $pdo->prepare('SELECT * FROM dumpsites WHERE id=?'); $stmt->execute([$id]); $site = $stmt->fetch(PDO::FETCH_ASSOC); if (!$site) { flash('Dump site not found.'); $base=rtrim(dirname($_SERVER['SCRIPT_NAME']??''),'/'); if ($base===''||$base==='/'){$base=((strpos($uriPath,'/app/')===0||$uriPath==='/app')?'/app':'');} header('Location: '.($base?:'').'/dumpsites'); exit; } include __DIR__ . '/pages/admin/dumpsite_edit.php'; exit; } if ($path === '/dumpsites/update' && $_SERVER['REQUEST_METHOD']==='POST') { require_admin(); $pdo = db(); $id = (int)($_POST['id'] ?? 0); $name = trim($_POST['name'] ?? ''); $addr = trim($_POST['address'] ?? ''); $acc = trim($_POST['accepted'] ?? ''); $fee = ($_POST['tipping_fee'] ?? '') !== '' ? (float)$_POST['tipping_fee'] : null; $phone = trim($_POST['phone'] ?? ''); $hours = trim($_POST['hours'] ?? ''); $notes = trim($_POST['notes'] ?? ''); $lat = ($_POST['lat'] ?? '') !== '' ? (float)$_POST['lat'] : null; $lng = ($_POST['lng'] ?? '') !== '' ? (float)$_POST['lng'] : null; if ($id<=0 || $name==='') { flash('Missing required fields.'); $base=rtrim(dirname($_SERVER['SCRIPT_NAME']??''),'/'); if ($base===''||$base==='/'){$base=((strpos($uriPath,'/app/')===0||$uriPath==='/app')?'/app':'');} header('Location: '.($base?:'').'/dumpsites'); exit; } $stmt = $pdo->prepare('UPDATE dumpsites SET name=?, address=?, accepted=?, tipping_fee=?, phone=?, hours=?, notes=?, lat=?, lng=? WHERE id=?'); $stmt->execute([$name,$addr ?: null,$acc ?: null,$fee,$phone ?: null,$hours ?: null,$notes ?: null,$lat,$lng,$id]); flash('Dump site updated.'); $base = rtrim(dirname($_SERVER['SCRIPT_NAME'] ?? ''), '/'); if ($base === '' || $base === '/') { $base = ((strpos($uriPath, '/app/') === 0 || $uriPath === '/app') ? '/app' : ''); } header('Location: ' . ($base ?: '') . '/dumpsites'); exit; } if ($path === '/dumpsites/delete' && $_SERVER['REQUEST_METHOD']==='POST') { require_admin(); $pdo = db(); $id = (int)($_POST['id'] ?? 0); if ($id>0) { $stmt = $pdo->prepare('DELETE FROM dumpsites WHERE id=?'); $stmt->execute([$id]); flash('Dump site deleted.'); } $base = rtrim(dirname($_SERVER['SCRIPT_NAME'] ?? ''), '/'); if ($base === '' || $base === '/') { $base = ((strpos($uriPath, '/app/') === 0 || $uriPath === '/app') ? '/app' : ''); } header('Location: ' . ($base ?: '') . '/dumpsites'); exit; } /* ================================================================ * ROUTES (Admin) – placeholder to avoid 404 for now * ================================================================ */ if ($path === '/routes') { require_admin(); echo "

Routes

Planner coming soon.

"; exit; } /* ================================================================ * DRIVER PORTAL (public) * ================================================================ */ if ($path === '/driver/login') { include __DIR__ . '/pages/driver/login.php'; exit; } if ($path === '/driver/auth' && $_SERVER['REQUEST_METHOD']==='POST') { $pin = trim($_POST['pin'] ?? ''); $pdo = db(); $stmt = $pdo->prepare('SELECT id, name FROM drivers WHERE pin = ?'); $stmt->execute([$pin]); $d = $stmt->fetch(PDO::FETCH_ASSOC); if ($d) { $_SESSION['driver_id'] = (int)$d['id']; $_SESSION['driver_name'] = $d['name']; $base = rtrim(dirname($_SERVER['SCRIPT_NAME'] ?? ''), '/'); if ($base === '' || $base === '/') { $base = ((strpos($uriPath, '/app/') === 0 || $uriPath === '/app') ? '/app' : ''); } header('Location: ' . ($base ?: '') . '/driver/route'); exit; } flash('Invalid PIN.'); $base = rtrim(dirname($_SERVER['SCRIPT_NAME'] ?? ''), '/'); if ($base === '' || $base === '/') { $base = ((strpos($uriPath, '/app/') === 0 || $uriPath === '/app') ? '/app' : ''); } header('Location: ' . ($base ?: '') . '/driver/login'); exit; } if ($path === '/driver/route') { if (empty($_SESSION['driver_id'])) { $base = rtrim(dirname($_SERVER['SCRIPT_NAME'] ?? ''), '/'); if ($base === '' || $base === '/') { $base = ((strpos($uriPath, '/app/') === 0 || $uriPath === '/app') ? '/app' : ''); } header('Location: ' . ($base ?: '') . '/driver/login'); exit; } $pdo = db(); $driverId = (int)$_SESSION['driver_id']; $stmt = $pdo->prepare('SELECT * FROM jobs WHERE driver_id = ? ORDER BY scheduled_at IS NULL, scheduled_at'); $stmt->execute([$driverId]); $jobs = $stmt->fetchAll(PDO::FETCH_ASSOC); include __DIR__ . '/pages/driver/route.php'; exit; } /* ================================================================ * Fallback 404 * ================================================================ */ http_response_code(404); echo "

404

Route not found: ".htmlspecialchars($path)."

";