BROOKO icon
BROOKO UK NETWORK
Where code meets creativity & adventure
File viewer

exports.php

Type
php
Size
5.87 KB
Modified
15 May
exports.php 5.87 KB
<?php
require_once __DIR__ . '/../bootstrap.php';
require_once __DIR__ . '/../lib/feature_modules.php';
wp_feature_require_admin();
$pageTitle = 'Exports';
wp_feature_ensure_rota_schema();

function wp_export_clock_csv(PDO $pdo): void {
    wp_feature_ensure_time_clock_schema();
    $stmt = $pdo->query("SELECT * FROM time_clock_entries ORDER BY clock_in_at DESC");
    $rows = [];
    foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $r) {
        $hours = '';
        if (!empty($r['clock_in_at']) && !empty($r['clock_out_at'])) {
            $minutes = (strtotime((string)$r['clock_out_at']) - strtotime((string)$r['clock_in_at'])) / 60;
            $hours = number_format(max(0, $minutes) / 60, 2);
        }
        $startMeta = !empty($r['start_meta_json']) ? json_decode((string)$r['start_meta_json'], true) : [];
        $endMeta = !empty($r['end_meta_json']) ? json_decode((string)$r['end_meta_json'], true) : [];
        if (!is_array($startMeta)) $startMeta = [];
        if (!is_array($endMeta)) $endMeta = [];
        $rows[] = [
            $r['id'],
            $r['username'],
            $r['display_name'],
            $r['role_name'],
            $r['van_label'] ?? '',
            $r['van_reg'] ?? '',
            $r['partner_name'] ?? '',
            $r['mileage_in'] ?? '',
            $r['mileage_out'] ?? '',
            $r['clock_in_at'],
            $r['clock_out_at'],
            $hours,
            $r['status'],
            json_encode($startMeta['checks'] ?? [], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
            json_encode($endMeta['checks'] ?? [], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
            $r['notes'],
            $r['photo_count'] ?? 0,
            $r['ip_address'],
        ];
    }
    wp_feature_csv_download('time_clock_' . date('Ymd_His') . '.csv', ['ID','Username','Display Name','Role','Van / Assignment','Van Reg','Working With','Odometer In','Odometer Out','Clock In','Clock Out','Hours','Status','Start Checks','End Checks','Notes','Photo Count','IP Address'], $rows);
}

function wp_export_calendar_csv(PDO $pdo): void {
    $stmt = $pdo->query("SELECT id, title, run_number, van_id, van_plate_temp, driver_user_id, driver_name_other, porter_user_id, porter_name_other, office_user_id, office_user_other, is_run_event, description, location, meeting_with, meeting_by_user_id, meeting_status, start_at, end_at, all_day, category_id, meta, created_by, updated_by, created_at, updated_at FROM calendar_events ORDER BY start_at DESC");
    $rows = [];
    foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $r) {
        $rows[] = [$r['id'], $r['title'], $r['run_number'], $r['van_id'], $r['van_plate_temp'], $r['driver_user_id'], $r['driver_name_other'], $r['porter_user_id'], $r['porter_name_other'], $r['office_user_id'], $r['office_user_other'], $r['is_run_event'], $r['description'], $r['location'], $r['meeting_with'], $r['meeting_by_user_id'], $r['meeting_status'], $r['start_at'], $r['end_at'], $r['all_day'], $r['category_id'], $r['meta'], $r['created_by'], $r['updated_by'], $r['created_at'], $r['updated_at']];
    }
    wp_feature_csv_download('calendar_events_' . date('Ymd_His') . '.csv', ['ID','Title','Run Number','Van ID','Van Temp','Driver User ID','Driver Other','Porter User ID','Porter Other','Office User ID','Office Other','Run Event','Description','Location','Meeting With','Meeting By','Meeting Status','Start At','End At','All Day','Category ID','Meta','Created By','Updated By','Created At','Updated At'], $rows);
}

$exports = [
    'rota' => ['title' => 'Rota', 'description' => 'All rota entries and assignments.', 'count_query' => 'SELECT COUNT(*) FROM rota_entries', 'handler' => app_url('management/rota?export=csv')],
    'holidays' => ['title' => 'Holiday Requests', 'description' => 'Holiday request queue with statuses.', 'count_query' => 'SELECT COUNT(*) FROM holiday_requests', 'handler' => app_url('management/holidays?export=csv')],
    'incidents' => ['title' => 'Incidents', 'description' => 'Incident log including photo counts.', 'count_query' => 'SELECT COUNT(*) FROM incidents', 'handler' => app_url('management/incidents?export=csv')],
    'clock' => ['title' => 'Clock In / Out', 'description' => 'Clock in, clock out and worked hours.', 'count_query' => 'SELECT COUNT(*) FROM time_clock_entries', 'handler' => 'self'],
    'calendar' => ['title' => 'Calendar Events', 'description' => 'Full calendar event dataset.', 'count_query' => 'SELECT COUNT(*) FROM calendar_events', 'handler' => 'self'],
];

$exportKey = trim((string)($_GET['export'] ?? ''));
if ($exportKey !== '' && isset($exports[$exportKey])) {
    if ($exportKey === 'clock') {
        wp_export_clock_csv($pdo);
        exit;
    } elseif ($exportKey === 'calendar') {
        wp_export_calendar_csv($pdo);
        exit;
    }
}

$counts = [];
foreach ($exports as $key => $cfg) {
    try {
        $counts[$key] = (int)$pdo->query($cfg['count_query'])->fetchColumn();
    } catch (Throwable $e) {
        $counts[$key] = 0;
    }
}
include __DIR__ . '/../partials/header.php';
?>
<div class="content-header">
  <div>
    <h1 class="content-title">📤 Exports</h1>
    <p class="content-subtitle">Spreadsheet-ready CSV exports for operational data, calendar events and time clock entries.</p>
  </div>
  <div class="d-flex gap-md" style="flex-wrap:wrap;"><a class="btn btn-secondary" href="<?= e(app_url('admin')) ?>">← Back to Admin</a></div>
</div>
<div class="grid grid-2">
<?php foreach ($exports as $key => $cfg): ?>
  <div class="card">
    <div class="card-header"><h3 class="card-title"><?= e($cfg['title']) ?></h3></div>
    <p class="text-muted"><?= e($cfg['description']) ?></p>
    <p class="text-muted">Rows in database: <strong><?= (int)$counts[$key] ?></strong></p>
    <a class="btn btn-primary" href="<?= e($cfg['handler'] === 'self' ? app_url('admin/exports?export=' . $key) : $cfg['handler']) ?>">Download CSV</a>
  </div>
<?php endforeach; ?>
</div>
<?php include __DIR__ . '/../partials/footer.php'; ?>