Files
Reservair/includes/Views/RsvGoogleCalendarSettingsPage.php
T
Martas f4d3972d07 (#2) - forms improvements (#4)
Co-authored-by: Martin Slachta <martin.slachta@outlook.com>
Reviewed-on: #4
2026-06-12 14:05:49 +00:00

130 lines
7.1 KiB
PHP

<?php
class RsvGoogleCalendarSettingsPage extends RsvAdminPage {
protected function render_content(): void {
$service = new RsvGoogleCalendarService();
$notice = null;
if (isset($_GET['connected'])) {
$notice = ['type' => 'success', 'message' => 'Google Calendar connected successfully.'];
}
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['rsv_google_settings_nonce'])) {
if (!wp_verify_nonce($_POST['rsv_google_settings_nonce'], 'rsv_google_settings')) {
wp_die('Security check failed.');
}
if (isset($_POST['rsv_disconnect'])) {
$service->disconnect();
$notice = ['type' => 'success', 'message' => 'Disconnected from Google Calendar.'];
} elseif (isset($_POST['rsv_register_webhook'])) {
$result = $service->register_webhook();
$notice = isset($result['id'])
? ['type' => 'success', 'message' => 'Webhook registered.']
: ['type' => 'error', 'message' => 'Webhook registration failed: ' . ($result['error'] ?? json_encode($result))];
} elseif (isset($_POST['rsv_stop_webhook'])) {
$service->stop_webhook();
$notice = ['type' => 'success', 'message' => 'Webhook stopped.'];
} else {
update_option('rsv_google_client_id', sanitize_text_field($_POST['rsv_google_client_id'] ?? ''));
update_option('rsv_google_calendar_id', sanitize_text_field($_POST['rsv_google_calendar_id'] ?? 'primary'));
// Only overwrite the (encrypted) client secret when a new value is
// supplied — the field renders blank, so otherwise saving any other
// setting would wipe the stored secret.
$client_secret = sanitize_text_field($_POST['rsv_google_client_secret'] ?? '');
if ($client_secret !== '') {
$service->set_client_secret($client_secret);
}
$notice = ['type' => 'success', 'message' => 'Settings saved.'];
}
}
$connected = $service->is_google_connected();
$webhook_registered = $service->is_webhook_registered();
$webhook_expiry = (int) get_option('rsv_google_webhook_expiration', 0);
$client_id = esc_attr(get_option('rsv_google_client_id', ''));
$cal_id = esc_attr(get_option('rsv_google_calendar_id', 'primary'));
$oauth_url = esc_url($service->get_oauth_url());
?>
<h1>Google Calendar</h1>
<?php if ($notice): ?>
<div class="notice notice-<?= esc_attr($notice['type']) ?> is-dismissible">
<p><?= esc_html($notice['message']) ?></p>
</div>
<?php endif; ?>
<form method="post">
<?php wp_nonce_field('rsv_google_settings', 'rsv_google_settings_nonce'); ?>
<h2>OAuth Credentials</h2>
<p>Create a project in <a href="https://console.cloud.google.com/" target="_blank">Google Cloud Console</a>, enable the <strong>Google Calendar API</strong>, and create OAuth 2.0 credentials. Set the authorised redirect URI to <code><?= esc_html(site_url('/wp-json/reservations/v1/google-callback')) ?></code>.</p>
<table class="form-table">
<tr>
<th><label for="rsv_google_client_id">Client ID</label></th>
<td><input class="regular-text" type="text" id="rsv_google_client_id" name="rsv_google_client_id" value="<?= $client_id ?>"></td>
</tr>
<tr>
<th><label for="rsv_google_client_secret">Client Secret</label></th>
<td><input class="regular-text" type="password" id="rsv_google_client_secret" name="rsv_google_client_secret" placeholder="<?= $connected ? '(saved)' : '' ?>"></td>
</tr>
<tr>
<th><label for="rsv_google_calendar_id">Calendar ID</label></th>
<td>
<input class="regular-text" type="text" id="rsv_google_calendar_id" name="rsv_google_calendar_id" value="<?= $cal_id ?>">
<p class="description">Use <code>primary</code> for the account's main calendar, or paste a specific calendar ID from Google Calendar settings.</p>
</td>
</tr>
</table>
<?php submit_button('Save Settings'); ?>
<hr>
<h2>Connection</h2>
<?php if ($connected): ?>
<p><span style="color:#46b450; font-weight:600;">&#10004; Connected to Google Calendar.</span></p>
<button type="submit" name="rsv_disconnect" value="1" class="button button-secondary" style="color:#b32d2e;">
Disconnect
</button>
<?php else: ?>
<p><span style="color:#dc3232; font-weight:600;">&#10008; Not connected.</span></p>
<a href="<?= $oauth_url ?>" class="button button-primary">Connect with Google</a>
<p class="description" style="margin-top:.5rem;">You must save the Client ID and Secret first.</p>
<?php endif; ?>
<?php if ($connected): ?>
<hr>
<h2>Webhook</h2>
<p>The webhook lets Google Calendar notify this site when you confirm or cancel a reservation event, so the reservation state is updated automatically.</p>
<?php $webhook_url = site_url('/wp-json/reservations/v1/google-calendar-hook'); ?>
<p>Webhook URL: <code><?= esc_html($webhook_url) ?></code></p>
<?php if (!str_starts_with($webhook_url, 'https://')): ?>
<div class="notice notice-warning inline">
<p><strong>HTTPS required.</strong> Google Calendar only accepts webhook URLs served over HTTPS. This site is currently on HTTP, so webhook registration will be rejected by Google. Use a publicly accessible HTTPS address in production.</p>
</div>
<?php endif; ?>
<?php if ($webhook_registered): ?>
<p><span style="color:#46b450; font-weight:600;">&#10004; Webhook active.</span>
<?php if ($webhook_expiry): ?>
Expires <?= esc_html(date_i18n(get_option('date_format') . ' ' . get_option('time_format'), $webhook_expiry)) ?>.
<?php endif; ?>
</p>
<button type="submit" name="rsv_register_webhook" value="1" class="button">Re-register</button>
<button type="submit" name="rsv_stop_webhook" value="1" class="button button-secondary" style="color:#b32d2e;">Stop</button>
<?php else: ?>
<p><span style="color:#dc3232; font-weight:600;">&#10008; Webhook not registered.</span></p>
<button type="submit" name="rsv_register_webhook" value="1" class="button button-primary">Register Webhook</button>
<?php endif; ?>
<?php endif; ?>
</form>
<?php
}
}