plugin = $plugin; } public function hooks(): void { add_action('admin_menu', [$this, 'menu']); add_action('admin_init', [$this, 'register_settings']); add_action('admin_notices', [$this, 'environment_notice']); add_action('admin_enqueue_scripts', [$this, 'enqueue_admin_assets']); } public function enqueue_admin_assets(string $hook_suffix): void { if ($hook_suffix !== 'woocommerce_page_3dl-central-checkout') { return; } wp_enqueue_script( '3dl-cc-free-admin', THREEDL_CC_FREE_URL . 'assets/js/admin.js', [], THREEDL_CC_FREE_VERSION, true ); } public function menu(): void { if (!current_user_can('manage_woocommerce')) { return; } add_submenu_page( 'woocommerce', __('3DL Central Checkout', '3dl-central-checkout-for-woocommerce'), __('3DL Central Checkout', '3dl-central-checkout-for-woocommerce'), 'manage_woocommerce', '3dl-central-checkout', [$this, 'render_page'] ); } public function register_settings(): void { register_setting('3dl_cc_free_settings', ThreeDL_CC_Free_Plugin::OPTION_KEY, [ 'type' => 'array', 'sanitize_callback' => [$this, 'sanitize_options'], 'default' => ThreeDL_CC_Free_Plugin::default_options(), ]); } public function sanitize_options($input): array { $input = is_array($input) ? $input : []; $old = $this->plugin->get_options(); $mode = isset($input['mode']) ? sanitize_key((string) $input['mode']) : 'disabled'; if (!in_array($mode, ['disabled', 'main', 'source'], true)) { $mode = 'disabled'; } $secret = isset($input['secret_key']) ? preg_replace('/[^A-Za-z0-9_\-]/', '', (string) $input['secret_key']) : ''; $secret = substr((string) $secret, 0, 128); $trusted = isset($input['trusted_sources']) ? sanitize_textarea_field((string) $input['trusted_sources']) : ''; $trusted_lines = preg_split('/\r\n|\r|\n/', $trusted) ?: []; $clean_trusted = []; foreach ($trusted_lines as $line) { $url = esc_url_raw(trim((string) $line)); if ($url !== '') { $clean_trusted[] = trailingslashit(untrailingslashit($url)); } } $result = [ 'mode' => $mode, 'main_store_url' => isset($input['main_store_url']) ? esc_url_raw((string) $input['main_store_url']) : '', 'secret_key' => $secret, 'trusted_sources' => implode("\n", array_values(array_unique($clean_trusted))), 'transfer_ttl' => min(1800, max(60, absint($input['transfer_ttl'] ?? 600))), 'after_add' => isset($input['after_add']) && in_array(sanitize_key((string) $input['after_add']), ['return_source', 'cart'], true) ? sanitize_key((string) $input['after_add']) : 'return_source', ]; // Keep role-specific settings clean so a Source store cannot accidentally retain a Main-store allow-list, // and a Main store always derives its own URL from WordPress rather than a stale saved value. if ($mode === 'main') { $result['main_store_url'] = ''; } elseif ($mode === 'source') { $result['trusted_sources'] = ''; } else { // Disabling the runtime should not destroy a configuration the administrator may want to re-enable later. $result['main_store_url'] = (string) ($old['main_store_url'] ?? $result['main_store_url']); $result['secret_key'] = (string) ($old['secret_key'] ?? $result['secret_key']); $result['trusted_sources'] = (string) ($old['trusted_sources'] ?? $result['trusted_sources']); $result['transfer_ttl'] = absint($old['transfer_ttl'] ?? $result['transfer_ttl']); $result['after_add'] = (string) ($old['after_add'] ?? $result['after_add']); } if ($mode === 'main' && $result['secret_key'] === '' && empty($old['secret_key'])) { $result['secret_key'] = wp_generate_password(64, false, false); } $this->plugin->clear_options_cache(); return $result; } public function environment_notice(): void { if (!current_user_can('manage_woocommerce')) { return; } if (!is_multisite()) { echo '
' . esc_html__('3DL Central Checkout:', '3dl-central-checkout-for-woocommerce') . ' ' . esc_html__('This free plugin is designed for WordPress Multisite.', '3dl-central-checkout-for-woocommerce') . '
' . esc_html__('3DL Central Checkout:', '3dl-central-checkout-for-woocommerce') . ' ' . esc_html__('WooCommerce must be active on every store that participates in the central cart.', '3dl-central-checkout-for-woocommerce') . '
' . esc_html__('3DL Central Checkout:', '3dl-central-checkout-for-woocommerce') . ' ' . esc_html__('PRO is active on this site, so the free runtime is paused to avoid duplicate cart handlers.', '3dl-central-checkout-for-woocommerce') . '
plugin->woocommerce_active() ? esc_html__('Active', '3dl-central-checkout-for-woocommerce') : esc_html__('Not active', '3dl-central-checkout-for-woocommerce'); ?>
plugin->get_secret() !== '' ? esc_html__('Configured', '3dl-central-checkout-for-woocommerce') : esc_html__('Missing', '3dl-central-checkout-for-woocommerce'); ?>