2026-06-11 19:03:29 +02:00
< ? php
2026-06-12 14:05:49 +00:00
class RsvGoogleCalendarSettingsPage extends RsvAdminPage {
2026-06-11 19:03:29 +02:00
2026-06-12 14:05:49 +00:00
protected function render_content () : void {
$service = new RsvGoogleCalendarService ();
$notice = null ;
2026-06-11 19:03:29 +02:00
2026-06-12 14:05:49 +00:00
if ( isset ( $_GET [ 'connected' ])) {
$notice = [ 'type' => 'success' , 'message' => 'Google Calendar connected successfully.' ];
2026-06-11 19:03:29 +02:00
}
2026-06-12 14:05:49 +00:00
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.' ];
2026-06-11 19:03:29 +02:00
}
}
2026-06-12 14:05:49 +00:00
$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 ());
?>
2026-06-11 19:03:29 +02:00
<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;">✔ 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;">✘ 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;">✔ 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;">✘ 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>
2026-06-12 14:05:49 +00:00
<?php
}
2026-06-11 19:03:29 +02:00
}