First Commit
This commit is contained in:
1 parent
5eb9dd037d
commit
2e62c0e60b
11877 files changed
+2035312
No files matched your search
@@ -0,0 +1,211 @@
|
||||
<?php
|
||||
/**
|
||||
* square_connected.php — TEMPORARY admin view of Square-connected schools.
|
||||
*
|
||||
* Read-only. Lists every school that has a Square connection (and recent pending
|
||||
* onboarding attempts) so you can confirm onboarding worked without DB access.
|
||||
* NEVER displays access/refresh tokens — only whether they are present.
|
||||
*
|
||||
* ⚠️ DELETE THIS FILE FROM PRODUCTION when you're done. It is gated by a key
|
||||
* below to avoid casual exposure, but it is not part of the real app.
|
||||
*
|
||||
* Usage: https://dev.hotlunches.net/square/square_connected.php?key=sq-admin-7f3a
|
||||
*/
|
||||
|
||||
ini_set('display_errors', 0);
|
||||
|
||||
// ── Simple access gate ───────────────────────────────────────────────────────
|
||||
// Change this value (or delete the file) before leaving it on a public server.
|
||||
$ACCESS_KEY = 'sq-admin-7f3a';
|
||||
if (($_GET['key'] ?? '') !== $ACCESS_KEY) {
|
||||
http_response_code(403);
|
||||
header('Content-Type: text/plain; charset=utf-8');
|
||||
echo "Forbidden. Append ?key=YOUR_KEY (see the top of square_connected.php).";
|
||||
exit;
|
||||
}
|
||||
|
||||
// ── Bootstrap the DB layer (MerchantStore loads the host include/database.php) ─
|
||||
require_once __DIR__ . '/lib/MerchantStore.php';
|
||||
$config = require __DIR__ . '/config.php';
|
||||
$store = new MerchantStore($config); // constructor bootstraps the db_* layer
|
||||
|
||||
header('Content-Type: text/html; charset=utf-8');
|
||||
|
||||
$dbReady = function_exists('db_query');
|
||||
|
||||
/** Format a unix timestamp (or '-' when empty). */
|
||||
function ts($v) {
|
||||
$v = (int)$v;
|
||||
return $v > 0 ? date('Y-m-d H:i', $v) : '-';
|
||||
}
|
||||
function h($v) { return htmlspecialchars((string)$v, ENT_QUOTES, 'UTF-8'); }
|
||||
|
||||
// ── Connected schools (tokens are NOT selected) ──────────────────────────────
|
||||
$connected = [];
|
||||
$pending = [];
|
||||
$error = '';
|
||||
|
||||
if ($dbReady) {
|
||||
$sql = "SELECT record_num, school_name,
|
||||
square_merchant_id, square_merchant_name,
|
||||
square_location_id, square_currency, square_country,
|
||||
square_ready, square_connected_at, square_token_expires_at,
|
||||
square_merchant_key, square_status_issues, square_status_checked_at,
|
||||
square_authorization_revoked,
|
||||
(square_access_token IS NOT NULL AND square_access_token <> '') AS has_access,
|
||||
(square_refresh_token IS NOT NULL AND square_refresh_token <> '') AS has_refresh
|
||||
FROM schools
|
||||
WHERE square_merchant_id IS NOT NULL AND square_merchant_id <> ''
|
||||
ORDER BY square_connected_at DESC";
|
||||
$r = db_query($sql);
|
||||
if ($r) {
|
||||
while ($row = db_fetch_assoc($r)) {
|
||||
$connected[] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
$pr = db_query(
|
||||
"SELECT state, school_num, status, merchant_id, created_at, connected_at, last_callback
|
||||
FROM square_pending_onboarding
|
||||
ORDER BY created_at DESC
|
||||
LIMIT 50"
|
||||
);
|
||||
if ($pr) {
|
||||
while ($row = db_fetch_assoc($pr)) {
|
||||
$pending[] = $row;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$error = 'Host database layer (db_query) is not available — cannot read.';
|
||||
}
|
||||
?>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Square — Connected Schools</title>
|
||||
<style>
|
||||
body { font-family: system-ui, -apple-system, Segoe UI, Arial, sans-serif; margin: 0; background: #f7fafc; color: #1a202c; }
|
||||
.wrap { max-width: 1200px; margin: 0 auto; padding: 28px 20px 60px; }
|
||||
h1 { font-size: 22px; margin: 0 0 4px; }
|
||||
.sub { color: #718096; font-size: 13px; margin: 0 0 24px; }
|
||||
.warn { background: #fffaf0; border: 1px solid #fbd38d; color: #7b341e; padding: 10px 14px; border-radius: 8px; font-size: 13px; margin-bottom: 20px; }
|
||||
.err { background: #fff5f5; border: 1px solid #feb2b2; color: #c53030; padding: 10px 14px; border-radius: 8px; font-size: 13px; margin-bottom: 20px; }
|
||||
h2 { font-size: 16px; margin: 28px 0 10px; }
|
||||
table { width: 100%; border-collapse: collapse; background: #fff; border: 1px solid #e2e8f0; border-radius: 10px; overflow: hidden; font-size: 13px; }
|
||||
th, td { text-align: left; padding: 9px 12px; border-bottom: 1px solid #edf2f7; vertical-align: top; }
|
||||
th { background: #f1f5f9; font-weight: 600; color: #475569; white-space: nowrap; }
|
||||
tr:last-child td { border-bottom: none; }
|
||||
code { background: #f1f5f9; padding: 1px 5px; border-radius: 4px; font-size: 12px; }
|
||||
.pill { display: inline-block; padding: 2px 8px; border-radius: 999px; font-size: 11px; font-weight: 600; }
|
||||
.ok { background: #c6f6d5; color: #22543d; }
|
||||
.no { background: #fed7d7; color: #742a2a; }
|
||||
.muted{ color: #a0aec0; }
|
||||
.count { color: #718096; font-weight: 400; font-size: 13px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrap">
|
||||
<h1>Square — Connected Schools</h1>
|
||||
<p class="sub">Read-only snapshot from the live database. Tokens are never shown.</p>
|
||||
<div class="warn">⚠️ Temporary diagnostic page — delete <code>square_connected.php</code> from production when finished.</div>
|
||||
|
||||
<?php if ($error !== ''): ?>
|
||||
<div class="err"><?php echo h($error); ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<h2>Connected schools <span class="count">(<?php echo count($connected); ?>)</span></h2>
|
||||
<?php if (empty($connected)): ?>
|
||||
<p class="muted">No schools have a Square connection yet.</p>
|
||||
<?php else: ?>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>record_num</th>
|
||||
<th>School</th>
|
||||
<th>Merchant</th>
|
||||
<th>Location</th>
|
||||
<th>Currency</th>
|
||||
<th>Ready</th>
|
||||
<th>Tokens</th>
|
||||
<th>Connected</th>
|
||||
<th>Token expires</th>
|
||||
<th>Embed key</th>
|
||||
<th>Issues</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($connected as $c): ?>
|
||||
<tr>
|
||||
<td><code><?php echo h($c['record_num']); ?></code></td>
|
||||
<td><?php echo h($c['school_name']); ?></td>
|
||||
<td>
|
||||
<?php echo h($c['square_merchant_name'] ?: '—'); ?><br>
|
||||
<code><?php echo h($c['square_merchant_id']); ?></code>
|
||||
</td>
|
||||
<td><?php echo h($c['square_location_id'] ?: '—'); ?></td>
|
||||
<td><?php echo h($c['square_currency'] ?: '—'); ?><?php echo $c['square_country'] ? ' / ' . h($c['square_country']) : ''; ?></td>
|
||||
<td>
|
||||
<?php if (!empty($c['square_authorization_revoked'])): ?>
|
||||
<span class="pill no">revoked</span>
|
||||
<?php elseif (!empty($c['square_ready'])): ?>
|
||||
<span class="pill ok">ready</span>
|
||||
<?php else: ?>
|
||||
<span class="pill no">not ready</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td>
|
||||
<span class="pill <?php echo !empty($c['has_access']) ? 'ok' : 'no'; ?>">access</span>
|
||||
<span class="pill <?php echo !empty($c['has_refresh']) ? 'ok' : 'no'; ?>">refresh</span>
|
||||
</td>
|
||||
<td><?php echo h($c['square_connected_at'] ?: '—'); ?></td>
|
||||
<td><?php echo h($c['square_token_expires_at'] ?: '—'); ?></td>
|
||||
<td><?php echo $c['square_merchant_key'] ? '<code>' . h($c['square_merchant_key']) . '</code>' : '<span class="muted">—</span>'; ?></td>
|
||||
<td><?php echo $c['square_status_issues'] ? nl2br(h($c['square_status_issues'])) : '<span class="muted">none</span>'; ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php endif; ?>
|
||||
|
||||
<h2>Recent onboarding attempts <span class="count">(<?php echo count($pending); ?>)</span></h2>
|
||||
<?php if (empty($pending)): ?>
|
||||
<p class="muted">No onboarding attempts recorded.</p>
|
||||
<?php else: ?>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>school_num<br>(record_num)</th>
|
||||
<th>Status</th>
|
||||
<th>Merchant id</th>
|
||||
<th>Created</th>
|
||||
<th>Connected</th>
|
||||
<th>Last callback</th>
|
||||
<th>State</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($pending as $p): ?>
|
||||
<tr>
|
||||
<td><code><?php echo h($p['school_num']); ?></code></td>
|
||||
<td>
|
||||
<?php
|
||||
$st = (string)$p['status'];
|
||||
$cls = $st === 'connected' ? 'ok' : ($st === 'pending' ? '' : 'no');
|
||||
echo '<span class="pill ' . $cls . '">' . h($st) . '</span>';
|
||||
?>
|
||||
</td>
|
||||
<td><?php echo $p['merchant_id'] ? '<code>' . h($p['merchant_id']) . '</code>' : '<span class="muted">—</span>'; ?></td>
|
||||
<td><?php echo ts($p['created_at']); ?></td>
|
||||
<td><?php echo ts($p['connected_at']); ?></td>
|
||||
<td><?php echo ts($p['last_callback']); ?></td>
|
||||
<td><span class="muted"><?php echo h(substr((string)$p['state'], 0, 12)); ?>…</span></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in new issue
Block a user