$l) { if (is_array($l) && !empty($l['name']) && in_array((string) $l['name'], $names, true)) { $out[] = 'pickup_location:' . $i; } } } return $out; } private static function base_pickup_rate($rid) { $colon = strpos($rid, ':'); if ($colon === false) { return $rid; } $method = substr($rid, 0, $colon); $rest = substr($rid, $colon + 1); if (preg_match('/^(\d+)/', $rest, $mm)) { return $method . ':' . $mm[1]; } return $rid; } public static function bootstrap() { static $done = false; if ($done) { return; } $done = true; add_action('wp_ajax_aieo_dmm_payment_gating_save', array(__CLASS__, 'ajax_save')); $s = self::get_settings(); if ($s['enabled'] !== 'yes') { return; } add_filter('woocommerce_available_payment_gateways', array(__CLASS__, 'gate_payment'), 1002); add_action('wp_enqueue_scripts', array(__CLASS__, 'enqueue_block_support')); } public static function get_settings() { $stored = get_option(self::OPTION_KEY, array()); if (!is_array($stored)) { $stored = array(); } $s = array_merge(array( 'enabled' => 'no', 'gated_gateway_id' => 'cheque', 'pickup_any' => 'yes', 'pickup_locations' => array(), 'shipping_match_token' => self::PICKUP_ANY_TOKEN, ), $stored); if (!is_array($s['pickup_locations'])) { $s['pickup_locations'] = array(); } $s['pickup_any'] = ($s['pickup_any'] === 'no') ? 'no' : 'yes'; return $s; } public static function ajax_save() { AIEO_DMM::verify_ajax_request(); $pickup_any = !empty($_POST['pickup_any']) ? 'yes' : 'no'; $locs = array(); if ($pickup_any === 'no' && isset($_POST['pickup_locations']) && is_array($_POST['pickup_locations'])) { $valid = array(); if (class_exists('AIEO_DMM_Local_Pickup')) { foreach (AIEO_DMM_Local_Pickup::blocks_locations() as $bl) { if (!empty($bl['name'])) { $valid[] = (string) $bl['name']; } } } $raw = array_map('sanitize_text_field', wp_unslash($_POST['pickup_locations'])); $locs = array_values(array_intersect($raw, $valid)); } $patch = array( 'enabled' => !empty($_POST['enabled']) ? 'yes' : 'no', 'gated_gateway_id' => isset($_POST['gated_gateway_id']) ? sanitize_key(wp_unslash($_POST['gated_gateway_id'])) : 'cheque', 'pickup_any' => $pickup_any, 'pickup_locations' => $locs, 'shipping_match_token' => self::PICKUP_ANY_TOKEN, ); update_option(self::OPTION_KEY, $patch, false); wp_send_json_success(array('message' => __('Cash-on-pickup settings saved.', 'ai-eshop-optimizer'))); } public static function gate_payment($gateways) { if (!is_array($gateways)) { return $gateways; } if (is_admin() && !wp_doing_ajax()) { return $gateways; } if (!function_exists('WC') || !WC() || !WC()->session) { return $gateways; } $s = self::get_settings(); $gateway_id = (string) $s['gated_gateway_id']; if ($gateway_id === '') { return $gateways; } $chosen = WC()->session->get('chosen_shipping_methods'); if (!is_array($chosen) || empty($chosen)) { unset($gateways[$gateway_id]); return $gateways; } $matches_pickup = self::chosen_matches_pickup($chosen, $s); if ($matches_pickup) { if (!isset($gateways[$gateway_id]) && WC()->payment_gateways) { $all = WC()->payment_gateways->payment_gateways(); if (isset($all[$gateway_id])) { $gateways[$gateway_id] = $all[$gateway_id]; } } } else { unset($gateways[$gateway_id]); } return $gateways; } private static function cart_or_checkout_is_block() { $is_checkout = function_exists('is_checkout') && is_checkout(); $is_cart = function_exists('is_cart') && is_cart(); if (!$is_checkout && !$is_cart) { return false; } if (!class_exists('Automattic\\WooCommerce\\Blocks\\Utils\\CartCheckoutUtils')) { return true; } if ($is_checkout) { return (bool) \Automattic\WooCommerce\Blocks\Utils\CartCheckoutUtils::is_checkout_block_default(); } return (bool) \Automattic\WooCommerce\Blocks\Utils\CartCheckoutUtils::is_cart_block_default(); } public static function enqueue_block_support() { $s = self::get_settings(); if ($s['enabled'] !== 'yes') { return; } $slug = (string) $s['gated_gateway_id']; if ($slug === '') { return; } if (!self::cart_or_checkout_is_block()) { return; } $handle = 'wc-blocks-registry'; if (!wp_script_is($handle, 'registered') && !wp_script_is($handle, 'enqueued')) { return; } wp_enqueue_script($handle); $any = ($s['pickup_any'] !== 'no'); $cfg = wp_json_encode(array( 'slug' => $slug, 'anyPickup' => $any, 'pickupIds' => $any ? self::local_pickup_method_ids() : array(), 'allowedRateIds' => $any ? array() : self::selected_pickup_rate_ids((array) $s['pickup_locations']), )); if (!is_string($cfg)) { return; } $js = <<payment_gateways) { return $out; } foreach (WC()->payment_gateways->payment_gateways() as $id => $gw) { $id = (string) $id; if ($id === '') { continue; } $title = method_exists($gw, 'get_title') ? (string) $gw->get_title() : ''; if ($title === '') { $title = isset($gw->method_title) ? (string) $gw->method_title : $id; } $out[$id] = array( 'title' => $title, 'enabled' => (isset($gw->enabled) ? $gw->enabled : 'no') === 'yes', ); } return $out; } private static function shipping_methods_list() { $out = array(self::PICKUP_ANY_TOKEN => __('Any local pickup (legacy + Blocks)', 'ai-eshop-optimizer')); if (!class_exists('WC_Shipping_Zones')) { return $out; } $zones = WC_Shipping_Zones::get_zones(); $rest = WC_Shipping_Zones::get_zone(0); if ($rest) { $zones[] = array('shipping_methods' => $rest->get_shipping_methods(false)); } foreach ($zones as $z) { foreach ((isset($z['shipping_methods']) ? $z['shipping_methods'] : array()) as $m) { if (method_exists($m, 'is_enabled') && !$m->is_enabled()) { continue; } $mid = (string) $m->id; if ($mid === '' || isset($out[$mid])) { continue; } $title = (isset($m->method_title) && $m->method_title !== '') ? (string) $m->method_title : $mid; $out[$mid] = $title; } } return $out; } public static function render_card() { $s = self::get_settings(); $cur_gw = (string) $s['gated_gateway_id']; $gateways = self::gateways_list(); $loc_names = array(); if (class_exists('AIEO_DMM_Local_Pickup')) { foreach (AIEO_DMM_Local_Pickup::blocks_locations() as $bl) { if (!empty($bl['name'])) { $loc_names[] = (string) $bl['name']; } } } $pickup_any = ($s['pickup_any'] !== 'no'); $selected = (array) $s['pickup_locations']; $nonce = wp_create_nonce(AIEO_DMM::NONCE_ACTION); $ajax = admin_url('admin-ajax.php'); ?> 'payment-gating-cash-payment-during-pick-up', 'title' => __('Cash payment during pick-up', 'ai-eshop-optimizer'), 'description' => __('Show a payment method ONLY when the customer chooses store pickup — for paying in cash at the store on collection (this is NOT Cash on Delivery). Typically the WooCommerce Cheque gateway, renamed. The gateway must be enabled in WooCommerce → Payments; the name the customer sees is that gateway\'s own title (rename it there, e.g. to "Cash payment during pick-up").', 'ai-eshop-optimizer'), 'footer' => '' . ' ' . \Rooster\Admin\States::outcome('', '', array('id' => 'aieo-dmm-pg-status')), )); echo $open; $aieo_pg_choices = array(); if ($cur_gw !== '' && !isset($gateways[$cur_gw])) { $aieo_pg_choices[$cur_gw] = $cur_gw; } foreach ($gateways as $id => $info) { $aieo_pg_choices[(string) $id] = $info['title'] . ' (' . $id . ')' . (!$info['enabled'] ? ' — ' . __('disabled in WooCommerce', 'ai-eshop-optimizer') : ''); } $aieo_pg_locs = empty($loc_names) ? '

' . esc_html__('No pickup locations defined yet — add them above (Local Pickup tab).', 'ai-eshop-optimizer') . '

' : AIEO_Kit::checks('pickup_locations', array_combine($loc_names, $loc_names), $selected); $aieo_pg_html = AIEO_Kit::row(__('Enable this rule', 'ai-eshop-optimizer'), AIEO_Kit::check('enabled', __('Hide the payment method below until its shipping method is chosen', 'ai-eshop-optimizer'), $s['enabled'] === 'yes', array('id' => 'aieo-pg-enabled')), '', array('id' => 'aieo-pg-enabled', 'group' => true)) . AIEO_Kit::row( __('Payment method to gate', 'ai-eshop-optimizer'), AIEO_Kit::select('gated_gateway_id', $aieo_pg_choices, $cur_gw, array('id' => 'aieo-pg-gateway')), __('This method stays hidden until store pickup is chosen. Default: Cheque. (Must be enabled in WooCommerce → Payments to ever show.)', 'ai-eshop-optimizer'), array('id' => 'aieo-pg-gateway') ) . AIEO_Kit::row( __('Show it for these pickup locations', 'ai-eshop-optimizer'), AIEO_Kit::check('pickup_any', __('Any pickup location', 'ai-eshop-optimizer') . ' — ' . __('show for every store pickup (legacy + Blocks, both checkouts). Recommended.', 'ai-eshop-optimizer'), $pickup_any, array('id' => 'aieo-pg-any')) . '
' . $aieo_pg_locs . '
', __('Untick "Any pickup location" to restrict the payment method to specific stores (block checkout). Default: any.', 'ai-eshop-optimizer'), array('id' => 'aieo-pg-locations', 'group' => true) ); echo '
' . $aieo_pg_html . '
'; echo $close; ?>