public function render_settings_page() { // Handle form submission if (isset($_POST['bbs_save_settings'])) { $options = array( // General Settings 'business_label' => sanitize_text_field($_POST['business_label'] ?? 'GetGear Bookings'), 'bays_count' => intval($_POST['bays_count'] ?? 3), 'bay_price' => floatval($_POST['bay_price'] ?? 120), 'booking_duration' => intval($_POST['booking_duration'] ?? 50), 'max_advance_days' => intval($_POST['max_advance_days'] ?? 7), 'payment_hold_minutes' => intval($_POST['payment_hold_minutes'] ?? 15), 'dashboard_page_title' => sanitize_text_field($_POST['dashboard_page_title'] ?? 'My Range Bookings'), // Shooter & Group Settings 'max_shooters_per_bay' => intval($_POST['max_shooters_per_bay'] ?? 2), 'max_group_size' => intval($_POST['max_group_size'] ?? 6), 'group_booking_rule' => sanitize_text_field($_POST['group_booking_rule'] ?? 'all_bays'), 'allow_two_shooters_separate_bays' => isset($_POST['allow_two_shooters_separate_bays']) ? 1 : 0, // Yoco Settings 'enable_payments' => isset($_POST['enable_payments']) ? 1 : 0, 'test_mode' => isset($_POST['test_mode']) ? 1 : 0, 'yoco_public_key' => sanitize_text_field($_POST['yoco_public_key'] ?? ''), 'yoco_secret_key' => sanitize_text_field($_POST['yoco_secret_key'] ?? ''), // Branding Settings 'booking_header_badge_text' => sanitize_text_field($_POST['booking_header_badge_text'] ?? 'GetGear Bookings'), 'booking_header_title' => sanitize_text_field($_POST['booking_header_title'] ?? 'Book your range time with GetGear'), 'booking_header_subtitle' => sanitize_textarea_field($_POST['booking_header_subtitle'] ?? 'Choose your date, time, and bay. One booking reserves one full bay for your group.'), 'brand_primary_color' => sanitize_hex_color($_POST['brand_primary_color'] ?? '#111827'), 'brand_primary_end_color' => sanitize_hex_color($_POST['brand_primary_end_color'] ?? '#1f2937'), 'brand_accent_color' => sanitize_hex_color($_POST['brand_accent_color'] ?? '#f59e0b'), 'booking_header_title_color' => sanitize_hex_color($_POST['booking_header_title_color'] ?? '#ffffff'), 'booking_header_subtitle_color' => sanitize_hex_color($_POST['booking_header_subtitle_color'] ?? '#ffffff'), 'booking_header_badge_text_color' => sanitize_hex_color($_POST['booking_header_badge_text_color'] ?? '#ffffff'), 'booking_header_badge_bg_color' => sanitize_hex_color($_POST['booking_header_badge_bg_color'] ?? '#334155'), // Flow Text Settings 'hub_calendar_title' => sanitize_text_field($_POST['hub_calendar_title'] ?? 'Pick a date'), 'hub_calendar_help' => sanitize_textarea_field($_POST['hub_calendar_help'] ?? 'Choose an open day first.'), 'hub_flow_time_title' => sanitize_text_field($_POST['hub_flow_time_title'] ?? 'Choose a time'), 'hub_flow_bay_title' => sanitize_text_field($_POST['hub_flow_bay_title'] ?? 'Choose your bay'), 'form_intro_title' => sanitize_text_field($_POST['form_intro_title'] ?? 'Finish your booking'), 'form_intro_help' => sanitize_textarea_field($_POST['form_intro_help'] ?? 'Your date, time, and bay are already selected.'), 'rental_group_step_title' => sanitize_text_field($_POST['rental_group_step_title'] ?? 'Choose rental option and group size'), 'rental_selected_step_title' => sanitize_text_field($_POST['rental_selected_step_title'] ?? 'Rental selected and group size'), 'rental_group_help' => sanitize_textarea_field($_POST['rental_group_help'] ?? 'Choose your rental option first.'), 'own_firearm_title' => sanitize_text_field($_POST['own_firearm_title'] ?? 'Bring own firearm'), 'rent_firearm_title' => sanitize_text_field($_POST['rent_firearm_title'] ?? 'Use a GetGear rental'), 'group_size_title' => sanitize_text_field($_POST['group_size_title'] ?? 'How many shooters are coming?'), 'details_title' => sanitize_text_field($_POST['details_title'] ?? 'Fill in your details'), 'age_warning_text' => sanitize_textarea_field($_POST['age_warning_text'] ?? 'You must be 21+ years old and have valid ID.'), 'review_button_text' => sanitize_text_field($_POST['review_button_text'] ?? 'Next: Review Booking'), 'review_help_text' => sanitize_textarea_field($_POST['review_help_text'] ?? 'Check your booking summary below.'), 'summary_title' => sanitize_text_field($_POST['summary_title'] ?? 'Booking Summary'), 'pay_button_text' => sanitize_text_field($_POST['pay_button_text'] ?? 'Pay'), // Telegram Settings 'telegram_disable_all' => isset($_POST['telegram_disable_all']) ? 1 : 0, 'telegram_notifications_enabled' => isset($_POST['telegram_notifications_enabled']) ? 1 : 0, 'telegram_bot_token' => sanitize_text_field($_POST['telegram_bot_token'] ?? ''), 'telegram_chat_id' => sanitize_text_field($_POST['telegram_chat_id'] ?? ''), 'telegram_interactive_enabled' => isset($_POST['telegram_interactive_enabled']) ? 1 : 0, 'telegram_allowed_user_ids' => sanitize_textarea_field($_POST['telegram_allowed_user_ids'] ?? ''), 'telegram_poll_interval' => intval($_POST['telegram_poll_interval'] ?? 5), 'telegram_notify_new_booking' => isset($_POST['telegram_notify_new_booking']) ? 1 : 0, 'telegram_notify_payment_paid' => isset($_POST['telegram_notify_payment_paid']) ? 1 : 0, 'telegram_notify_status_changes' => isset($_POST['telegram_notify_status_changes']) ? 1 : 0, 'telegram_notify_events' => isset($_POST['telegram_notify_events']) ? 1 : 0, // Discord Settings 'discord_alerts_enabled' => isset($_POST['discord_alerts_enabled']) ? 1 : 0, 'discord_webhook_url' => esc_url_raw($_POST['discord_webhook_url'] ?? ''), 'discord_bot_api_enabled' => isset($_POST['discord_bot_api_enabled']) ? 1 : 0, 'discord_bot_api_key' => sanitize_text_field($_POST['discord_bot_api_key'] ?? ''), 'discord_notify_new_booking' => isset($_POST['discord_notify_new_booking']) ? 1 : 0, 'discord_notify_payment_paid' => isset($_POST['discord_notify_payment_paid']) ? 1 : 0, 'discord_notify_status_changes' => isset($_POST['discord_notify_status_changes']) ? 1 : 0, 'discord_notify_events' => isset($_POST['discord_notify_events']) ? 1 : 0, ); // Save flow text defaults foreach (self::flow_text_defaults() as $key => $config) { if (isset($_POST[$key])) { $options[$key] = $config['type'] === 'textarea' ? sanitize_textarea_field($_POST[$key]) : sanitize_text_field($_POST[$key]); } } update_option('bbs_payment_options', $options); echo '

Settings saved successfully!

'; } $settings = get_option('bbs_payment_options', array()); ?>
Configuration

GetGear Bookings Settings

Configure every aspect of your booking system.

General Settings

Name shown in WordPress admin menu.

Number of shooting bays available.

Base price per shooter.

How long a pending booking holds the bay.

Shooter & Group Settings

Yoco Payment Gateway

Your Yoco secret API key. Keep this private.

Frontend Branding

Header background start color.

Header background end color.

Button and highlight color.

Booking Flow Text

Customize the text shown to customers during booking.

Telegram Bot Notifications

Send booking alerts to your Telegram admin group.

Token from BotFather

Comma or line separated Telegram user IDs

Discord Bot & Alerts

Send booking alerts to your Discord channel.

Key for external bot to authenticate


Fatal error: Uncaught Error: Call to undefined function submit_button() in /home/getgearc/gunshop.getgear.co.za/wp-content/plugins/better-booking-system/includes/class-payment-settings.php:365 Stack trace: #0 /home/getgearc/gunshop.getgear.co.za/wp-content/plugins/better-booking-system/better-booking.php(31): require_once() #1 /home/getgearc/gunshop.getgear.co.za/wp-settings.php(560): include_once('/home/getgearc/...') #2 /home/getgearc/gunshop.getgear.co.za/wp-config.php(76): require_once('/home/getgearc/...') #3 /home/getgearc/gunshop.getgear.co.za/wp-load.php(50): require_once('/home/getgearc/...') #4 /home/getgearc/gunshop.getgear.co.za/wp-blog-header.php(13): require_once('/home/getgearc/...') #5 /home/getgearc/gunshop.getgear.co.za/index.php(17): require('/home/getgearc/...') #6 {main} thrown in /home/getgearc/gunshop.getgear.co.za/wp-content/plugins/better-booking-system/includes/class-payment-settings.php on line 365