$row) { $id = (int)$id; if ($id <= 0) continue; if ($onlyIds && !isset($wanted[$id])) continue; if (!is_array($row)) continue; facebookEventSaveCandidateFields($id, $row); } } $filter = gs('filter') ?: p('filter', 'staged'); if (!in_array($filter, ['staged', 'imported', 'skipped', 'all'], true)) $filter = 'staged'; if (isPost()) { csrfCheck(); $eventStatus = in_array(p('event_status', 'pending'), ['pending', 'approved'], true) ? p('event_status', 'pending') : 'pending'; $allowDuplicate = p('allow_duplicates', '0') === '1'; if (($saveId = (int)p('save_id', 0)) > 0) { eventImportSavePostedRows([$saveId]); flash('Import candidate saved.', 'success'); go('/admin/event_imports.php?filter='.$filter); } if (($importId = (int)p('import_id', 0)) > 0) { eventImportSavePostedRows([$importId]); $result = facebookEventImportCandidate($importId, uid(), $eventStatus, $allowDuplicate); flash($result['ok'] ? 'Event imported.'.(!empty($result['warning']) ? ' '.$result['warning'] : '') : $result['error'], $result['ok'] ? 'success' : 'error'); go('/admin/event_imports.php?filter='.$filter); } if (($skipId = (int)p('skip_id', 0)) > 0) { qrun("UPDATE event_imports SET status='skipped',updated_at=datetime('now') WHERE id=? AND status!='imported'", [$skipId]); flash('Import candidate skipped.', 'success'); go('/admin/event_imports.php?filter='.$filter); } if (($restoreId = (int)p('restore_id', 0)) > 0) { qrun("UPDATE event_imports SET status='staged',updated_at=datetime('now') WHERE id=? AND status='skipped'", [$restoreId]); flash('Import candidate restored.', 'success'); go('/admin/event_imports.php?filter=staged'); } if (($deleteId = (int)p('delete_id', 0)) > 0) { qrun("DELETE FROM event_imports WHERE id=? AND status!='imported'", [$deleteId]); flash('Import candidate deleted.', 'success'); go('/admin/event_imports.php?filter='.$filter); } $act = p('_act', ''); if ($act === 'save_all') { eventImportSavePostedRows(); flash('Import candidates saved.', 'success'); go('/admin/event_imports.php?filter='.$filter); } if ($act === 'bulk_import') { $ids = eventImportSelectedIds(); eventImportSavePostedRows($ids); $ok = 0; $errors = []; foreach ($ids as $id) { $result = facebookEventImportCandidate($id, uid(), $eventStatus, $allowDuplicate); if ($result['ok']) $ok++; else $errors[] = '#'.$id.': '.$result['error']; } if ($ok) flash($ok.' event'.($ok === 1 ? '' : 's').' imported.', 'success'); if ($errors) flash(implode(' ', $errors), 'error'); if (!$ids) flash('Select at least one staged import first.', 'warning'); go('/admin/event_imports.php?filter='.$filter); } if ($act === 'bulk_skip') { $ids = eventImportSelectedIds(); foreach ($ids as $id) qrun("UPDATE event_imports SET status='skipped',updated_at=datetime('now') WHERE id=? AND status!='imported'", [$id]); flash($ids ? count($ids).' import candidate'.(count($ids) === 1 ? '' : 's').' skipped.' : 'Select at least one staged import first.', $ids ? 'success' : 'warning'); go('/admin/event_imports.php?filter='.$filter); } if ($act === 'bulk_delete') { $ids = eventImportSelectedIds(); foreach ($ids as $id) qrun("DELETE FROM event_imports WHERE id=? AND status!='imported'", [$id]); flash($ids ? count($ids).' import candidate'.(count($ids) === 1 ? '' : 's').' deleted.' : 'Select at least one staged import first.', $ids ? 'success' : 'warning'); go('/admin/event_imports.php?filter='.$filter); } } $where = match ($filter) { 'staged' => "WHERE status='staged'", 'imported' => "WHERE status='imported'", 'skipped' => "WHERE status='skipped'", default => '', }; $imports = qall("SELECT * FROM event_imports $where ORDER BY CASE status WHEN 'staged' THEN 0 WHEN 'skipped' THEN 1 ELSE 2 END, created_at DESC LIMIT 200"); $counts = [ 'staged' => (int)qval("SELECT COUNT(*) FROM event_imports WHERE status='staged'"), 'imported' => (int)qval("SELECT COUNT(*) FROM event_imports WHERE status='imported'"), 'skipped' => (int)qval("SELECT COUNT(*) FROM event_imports WHERE status='skipped'"), 'all' => (int)qval("SELECT COUNT(*) FROM event_imports"), ]; include __DIR__.'/admin_header.php'; ?>
CLI STAGING

Stage Facebook event candidates through the official Graph API, then return here to verify titles, dates, locations, duplicates, and photos before publishing or sending them to pending review.

FACEBOOK_GRAPH_ACCESS_TOKEN=... php scripts/facebook-events-import.php --area="Keyser, WV" --page-id=123456789 --limit=20
'Staged','imported'=>'Imported','skipped'=>'Skipped','all'=>'All'] as $key => $label): ?> ()
Manage Events
+

No event imports here

Run the Graph API CLI importer to stage Facebook event candidates for review.

'badge-gold', 'imported' => 'badge-green', 'skipped' => 'badge-gray'][$imp['status']] ?? 'badge-gray'; $preview = $imp['image_path'] ?: $imp['image_url']; $canEdit = $imp['status'] !== 'imported'; ?>
<?=e($imp['title'] ?: 'Event image')?> No image
READY NEEDS FIX DUPLICATE?

View source

Edit imported event #

>
>
>
>
>
>
>
>
>
Needs review:
Possible duplicate: existing event # has the same title and start date.
Note: