Plugin Directory

Changeset 3455156


Ignore:
Timestamp:
02/06/2026 06:22:53 AM (8 weeks ago)
Author:
samybaxy
Message:

Fix: rest restrictions for payment methods in checkout

Location:
samybaxy-hyperdrive
Files:
2 edited
1 copied

Legend:

Unmodified
Added
Removed
  • samybaxy-hyperdrive/tags/6.0.2/trunk/mu-loader/shypdr-mu-loader.php

    r3454875 r3455156  
    11<?php
    22/**
    3  * Samybaxy's Hyperdrive - MU-Plugin Loader (High Performance Edition)
     3 * Plugin Name: Samybaxy's Hyperdrive - MU Loader
     4 * Plugin URI: https://github.com/samybaxy/samybaxy-hyperdrive
     5 * Description: High-performance plugin filter that intercepts plugin loading before WordPress loads regular plugins. Requires the main Samybaxy's Hyperdrive plugin.
     6 * Version: 6.0.2
     7 * Author: samybaxy
     8 * Author URI: https://github.com/samybaxy
     9 * License: GPL v2 or later
    410 *
    511 * This file MUST be placed in wp-content/mu-plugins/ to work.
    6  * It intercepts plugin loading BEFORE WordPress loads regular plugins.
    712 *
    813 * PERFORMANCE OPTIMIZATIONS:
     
    1419 *
    1520 * @package SamybaxyHyperdrive
    16  * @version 6.0.1
    1721 *
    18  * CHANGELOG 6.0.1:
    19  * - Removed WooCommerce reverse deps (was loading too many plugins on all WooCommerce pages)
    20  * - Streamlined checkout detection to use only dynamic payment gateway detection
    21  * - Made membership plugin loading conditional on logged-in users
     22 * CHANGELOG 6.0.2:
     23 * - Integrated WordPress 6.5+ Plugin Dependencies API for forward deps
     24 * - Fixed reverse dependency cascade (was loading all plugins)
     25 * - Curated reverse deps list: only jet-engine core UI and elementor-pro
     26 * - Added circular dependency protection
    2227 *
    2328 * CHANGELOG 6.0.1:
    2429 * - Added get_payment_gateway_plugins() for dynamic payment gateway detection
    2530 * - Fixed checkout page detection to use uri_contains_keyword()
     31 * - Made membership plugin loading conditional on logged-in users
    2632 */
    2733
     
    3440if (!defined('SHYPDR_MU_LOADER_ACTIVE')) {
    3541    define('SHYPDR_MU_LOADER_ACTIVE', true);
    36     define('SHYPDR_MU_LOADER_VERSION', '6.0.2'); // Enhanced: WP 6.5+ Plugin Dependencies integration, circular dep protection
     42    define('SHYPDR_MU_LOADER_VERSION', '6.0.2');
    3743}
    3844
     
    4753}
    4854
     55// Note: REST_REQUEST constant isn't defined yet at MU-plugin load time
     56// We detect REST requests via URL below instead
    4957if (defined('REST_REQUEST') && REST_REQUEST) {
    5058    return;
     
    5967}
    6068
    61 // Fast URI checks for admin paths (string operations only, no regex)
     69// Fast URI checks for admin paths, REST API, and AJAX (string operations only, no regex)
     70// CRITICAL: REST API and AJAX must bypass filtering for checkout payment gateways
    6271// phpcs:ignore WordPress.Security.ValidatedSanitizedInput -- Read-only early detection, no actions performed
    6372$shypdr_request_uri = isset($_SERVER['REQUEST_URI']) ? esc_url_raw(wp_unslash($_SERVER['REQUEST_URI'])) : '';
    6473if (strpos($shypdr_request_uri, '/wp-admin') !== false ||
    6574    strpos($shypdr_request_uri, '/wp-login') !== false ||
     75    strpos($shypdr_request_uri, '/wp-json/') !== false ||    // REST API - CRITICAL for WooCommerce Blocks
     76    strpos($shypdr_request_uri, 'rest_route=') !== false ||  // REST API alternate format
     77    strpos($shypdr_request_uri, 'admin-ajax.php') !== false || // AJAX - CRITICAL for Elementor checkout
     78    strpos($shypdr_request_uri, 'wc-ajax=') !== false ||     // WooCommerce AJAX (checkout, cart updates)
    6679    strpos($shypdr_request_uri, 'wp-activate.php') !== false ||
    6780    strpos($shypdr_request_uri, 'wp-signup.php') !== false ||
     
    346359            $detected[] = 'jet-smart-filters'; // CRITICAL FIX: Required for category filters and search widgets on shop pages
    347360
    348             // Checkout/Cart pages: Load payment gateways
    349             // CRITICAL: Payment gateways MUST be loaded for checkout to work
     361            // Checkout/Cart pages: Load payment gateways and checkout essentials
     362            // CRITICAL: Payment gateways and related plugins MUST be loaded for checkout to work
    350363            static $checkout_keywords = ['cart', 'checkout', 'order-pay', 'order-received'];
    351364            if (self::uri_contains_keyword($uri, $slug, $parent_slug, $checkout_keywords)) {
     
    353366                $detected = array_merge($detected, self::get_payment_gateway_plugins());
    354367
    355                 // Checkout-related plugins (only if user is logged in for memberships)
     368                // Essential checkout plugins (always load on checkout)
     369                $detected[] = 'woocommerce-services';          // WooCommerce Services (shipping labels, taxes)
     370                $detected[] = 'woocommerce-product-bundles';   // Product Bundles support
     371                $detected[] = 'woocommerce-smart-coupons';     // Coupons/gift cards
     372                $detected[] = 'woocommerce-subscriptions';     // Subscriptions (needed for recurring)
     373                $detected[] = 'woocommerce-legacy-rest-api';   // Legacy REST API (some gateways need this)
     374
     375                // Membership plugins (only if user is logged in)
    356376                if (self::is_user_logged_in_early()) {
    357377                    $detected[] = 'woocommerce-memberships';
    358                     $detected[] = 'woocommerce-subscriptions';
     378                    $detected[] = 'restrict-content-pro';
    359379                }
    360                 $detected[] = 'woocommerce-smart-coupons';
    361380            }
    362381
     
    775794
    776795        // Reverse dependencies (when parent is loaded, also load these children if active)
    777         // NOTE: Payment gateways are NOT here - they're loaded via direct detection on checkout pages only
     796        // IMPORTANT: This is a CURATED list - only include plugins that are needed for
     797        // core site functionality (menus, theme, UI). Do NOT include plugins that would
     798        // cascade to load other ecosystems (e.g., jet-woo-builder loads woocommerce).
     799        // WooCommerce-related plugins are loaded via URL/content detection, not here.
    778800        static $fallback_reverse_deps = [
    779801            'jet-engine' => [
     802                // Core UI/Theme plugins - always needed for site appearance
    780803                'jet-menu', 'jet-blocks', 'jet-theme-core', 'jet-elements', 'jet-tabs',
    781                 'jet-popup', 'jet-blog', 'jet-search', 'jet-reviews', 'jet-smart-filters',
    782                 'jet-compare-wishlist', 'jet-tricks', 'jet-woo-builder', 'jet-woo-product-gallery',
    783                 'jetformbuilder',
    784                 // JetEngine Extensions
     804                'jet-popup', 'jet-tricks', 'jet-style-manager',
     805                // JetEngine Extensions - small utilities, no external deps
    785806                'jet-engine-trim-callback', 'jet-engine-attachment-link-callback',
    786807                'jet-engine-custom-visibility-conditions', 'jet-engine-dynamic-charts-module',
    787808                'jet-engine-dynamic-tables-module', 'jet-engine-items-number-filter',
    788809                'jet-engine-layout-switcher', 'jet-engine-post-expiration-period'
     810                // NOTE: jet-woo-builder, jet-woo-product-gallery, jet-blog, jet-search,
     811                // jet-smart-filters, jet-reviews, jet-compare-wishlist, jetformbuilder
     812                // are NOT here - they load based on page content/URL detection
    789813            ],
    790             'elementor' => ['elementor-pro'],
     814            'elementor' => ['elementor-pro', 'the-plus-addons-for-elementor-page-builder'],
    791815        ];
    792816
     
    822846            $to_load[$slug] = true;
    823847
    824             // Get dependencies from DB map first, then fallback
     848            // Get FORWARD dependencies from DB map first, then fallback
     849            // IMPORTANT: We use DB for forward deps (what this plugin requires)
     850            // but ONLY use curated static list for reverse deps (to prevent cascade)
    825851            $deps = [];
    826             $rdeps = [];
    827 
    828             if (!empty($db_dependency_map[$slug])) {
    829                 // Use database-stored dependencies (includes WP 6.5+ header data)
    830                 $deps = $db_dependency_map[$slug]['depends_on'] ?? [];
    831                 $rdeps = $db_dependency_map[$slug]['plugins_depending'] ?? [];
    832             } else {
    833                 // Fallback to static map
    834                 $deps = $fallback_dependencies[$slug] ?? [];
    835                 $rdeps = $fallback_reverse_deps[$slug] ?? [];
    836             }
    837 
    838             // Add direct dependencies
     852
     853            if (!empty($db_dependency_map[$slug]['depends_on'])) {
     854                // Use database-stored forward dependencies (includes WP 6.5+ header data)
     855                $deps = $db_dependency_map[$slug]['depends_on'];
     856            } elseif (isset($fallback_dependencies[$slug])) {
     857                // Fallback to static map for forward deps
     858                $deps = $fallback_dependencies[$slug];
     859            }
     860
     861            // Add direct dependencies (forward: what this plugin requires)
    839862            foreach ($deps as $dep) {
    840863                // Check for circular dependency before adding
     
    849872            }
    850873
    851             // Add reverse dependencies (if active)
    852             foreach ($rdeps as $rdep) {
    853                 if (!isset($to_load[$rdep]) && isset($active_set[$rdep])) {
    854                     // Check for circular dependency
    855                     $pair_key = $slug . '|' . $rdep;
    856                     if (!isset($circular_set[$pair_key])) {
    857                         $queue[] = $rdep;
     874            // Add reverse dependencies ONLY from curated static list
     875            // This prevents cascade loading of all WooCommerce/AffiliateWP extensions
     876            // Only jet-engine and elementor should pull in their core UI plugins
     877            if (isset($fallback_reverse_deps[$slug])) {
     878                foreach ($fallback_reverse_deps[$slug] as $rdep) {
     879                    if (!isset($to_load[$rdep]) && isset($active_set[$rdep])) {
     880                        // Check for circular dependency
     881                        $pair_key = $slug . '|' . $rdep;
     882                        if (!isset($circular_set[$pair_key])) {
     883                            $queue[] = $rdep;
     884                        }
    858885                    }
    859886                }
  • samybaxy-hyperdrive/trunk/mu-loader/shypdr-mu-loader.php

    r3454875 r3455156  
    11<?php
    22/**
    3  * Samybaxy's Hyperdrive - MU-Plugin Loader (High Performance Edition)
     3 * Plugin Name: Samybaxy's Hyperdrive - MU Loader
     4 * Plugin URI: https://github.com/samybaxy/samybaxy-hyperdrive
     5 * Description: High-performance plugin filter that intercepts plugin loading before WordPress loads regular plugins. Requires the main Samybaxy's Hyperdrive plugin.
     6 * Version: 6.0.2
     7 * Author: samybaxy
     8 * Author URI: https://github.com/samybaxy
     9 * License: GPL v2 or later
    410 *
    511 * This file MUST be placed in wp-content/mu-plugins/ to work.
    6  * It intercepts plugin loading BEFORE WordPress loads regular plugins.
    712 *
    813 * PERFORMANCE OPTIMIZATIONS:
     
    1419 *
    1520 * @package SamybaxyHyperdrive
    16  * @version 6.0.1
    1721 *
    18  * CHANGELOG 6.0.1:
    19  * - Removed WooCommerce reverse deps (was loading too many plugins on all WooCommerce pages)
    20  * - Streamlined checkout detection to use only dynamic payment gateway detection
    21  * - Made membership plugin loading conditional on logged-in users
     22 * CHANGELOG 6.0.2:
     23 * - Integrated WordPress 6.5+ Plugin Dependencies API for forward deps
     24 * - Fixed reverse dependency cascade (was loading all plugins)
     25 * - Curated reverse deps list: only jet-engine core UI and elementor-pro
     26 * - Added circular dependency protection
    2227 *
    2328 * CHANGELOG 6.0.1:
    2429 * - Added get_payment_gateway_plugins() for dynamic payment gateway detection
    2530 * - Fixed checkout page detection to use uri_contains_keyword()
     31 * - Made membership plugin loading conditional on logged-in users
    2632 */
    2733
     
    3440if (!defined('SHYPDR_MU_LOADER_ACTIVE')) {
    3541    define('SHYPDR_MU_LOADER_ACTIVE', true);
    36     define('SHYPDR_MU_LOADER_VERSION', '6.0.2'); // Enhanced: WP 6.5+ Plugin Dependencies integration, circular dep protection
     42    define('SHYPDR_MU_LOADER_VERSION', '6.0.2');
    3743}
    3844
     
    4753}
    4854
     55// Note: REST_REQUEST constant isn't defined yet at MU-plugin load time
     56// We detect REST requests via URL below instead
    4957if (defined('REST_REQUEST') && REST_REQUEST) {
    5058    return;
     
    5967}
    6068
    61 // Fast URI checks for admin paths (string operations only, no regex)
     69// Fast URI checks for admin paths, REST API, and AJAX (string operations only, no regex)
     70// CRITICAL: REST API and AJAX must bypass filtering for checkout payment gateways
    6271// phpcs:ignore WordPress.Security.ValidatedSanitizedInput -- Read-only early detection, no actions performed
    6372$shypdr_request_uri = isset($_SERVER['REQUEST_URI']) ? esc_url_raw(wp_unslash($_SERVER['REQUEST_URI'])) : '';
    6473if (strpos($shypdr_request_uri, '/wp-admin') !== false ||
    6574    strpos($shypdr_request_uri, '/wp-login') !== false ||
     75    strpos($shypdr_request_uri, '/wp-json/') !== false ||    // REST API - CRITICAL for WooCommerce Blocks
     76    strpos($shypdr_request_uri, 'rest_route=') !== false ||  // REST API alternate format
     77    strpos($shypdr_request_uri, 'admin-ajax.php') !== false || // AJAX - CRITICAL for Elementor checkout
     78    strpos($shypdr_request_uri, 'wc-ajax=') !== false ||     // WooCommerce AJAX (checkout, cart updates)
    6679    strpos($shypdr_request_uri, 'wp-activate.php') !== false ||
    6780    strpos($shypdr_request_uri, 'wp-signup.php') !== false ||
     
    346359            $detected[] = 'jet-smart-filters'; // CRITICAL FIX: Required for category filters and search widgets on shop pages
    347360
    348             // Checkout/Cart pages: Load payment gateways
    349             // CRITICAL: Payment gateways MUST be loaded for checkout to work
     361            // Checkout/Cart pages: Load payment gateways and checkout essentials
     362            // CRITICAL: Payment gateways and related plugins MUST be loaded for checkout to work
    350363            static $checkout_keywords = ['cart', 'checkout', 'order-pay', 'order-received'];
    351364            if (self::uri_contains_keyword($uri, $slug, $parent_slug, $checkout_keywords)) {
     
    353366                $detected = array_merge($detected, self::get_payment_gateway_plugins());
    354367
    355                 // Checkout-related plugins (only if user is logged in for memberships)
     368                // Essential checkout plugins (always load on checkout)
     369                $detected[] = 'woocommerce-services';          // WooCommerce Services (shipping labels, taxes)
     370                $detected[] = 'woocommerce-product-bundles';   // Product Bundles support
     371                $detected[] = 'woocommerce-smart-coupons';     // Coupons/gift cards
     372                $detected[] = 'woocommerce-subscriptions';     // Subscriptions (needed for recurring)
     373                $detected[] = 'woocommerce-legacy-rest-api';   // Legacy REST API (some gateways need this)
     374
     375                // Membership plugins (only if user is logged in)
    356376                if (self::is_user_logged_in_early()) {
    357377                    $detected[] = 'woocommerce-memberships';
    358                     $detected[] = 'woocommerce-subscriptions';
     378                    $detected[] = 'restrict-content-pro';
    359379                }
    360                 $detected[] = 'woocommerce-smart-coupons';
    361380            }
    362381
     
    775794
    776795        // Reverse dependencies (when parent is loaded, also load these children if active)
    777         // NOTE: Payment gateways are NOT here - they're loaded via direct detection on checkout pages only
     796        // IMPORTANT: This is a CURATED list - only include plugins that are needed for
     797        // core site functionality (menus, theme, UI). Do NOT include plugins that would
     798        // cascade to load other ecosystems (e.g., jet-woo-builder loads woocommerce).
     799        // WooCommerce-related plugins are loaded via URL/content detection, not here.
    778800        static $fallback_reverse_deps = [
    779801            'jet-engine' => [
     802                // Core UI/Theme plugins - always needed for site appearance
    780803                'jet-menu', 'jet-blocks', 'jet-theme-core', 'jet-elements', 'jet-tabs',
    781                 'jet-popup', 'jet-blog', 'jet-search', 'jet-reviews', 'jet-smart-filters',
    782                 'jet-compare-wishlist', 'jet-tricks', 'jet-woo-builder', 'jet-woo-product-gallery',
    783                 'jetformbuilder',
    784                 // JetEngine Extensions
     804                'jet-popup', 'jet-tricks', 'jet-style-manager',
     805                // JetEngine Extensions - small utilities, no external deps
    785806                'jet-engine-trim-callback', 'jet-engine-attachment-link-callback',
    786807                'jet-engine-custom-visibility-conditions', 'jet-engine-dynamic-charts-module',
    787808                'jet-engine-dynamic-tables-module', 'jet-engine-items-number-filter',
    788809                'jet-engine-layout-switcher', 'jet-engine-post-expiration-period'
     810                // NOTE: jet-woo-builder, jet-woo-product-gallery, jet-blog, jet-search,
     811                // jet-smart-filters, jet-reviews, jet-compare-wishlist, jetformbuilder
     812                // are NOT here - they load based on page content/URL detection
    789813            ],
    790             'elementor' => ['elementor-pro'],
     814            'elementor' => ['elementor-pro', 'the-plus-addons-for-elementor-page-builder'],
    791815        ];
    792816
     
    822846            $to_load[$slug] = true;
    823847
    824             // Get dependencies from DB map first, then fallback
     848            // Get FORWARD dependencies from DB map first, then fallback
     849            // IMPORTANT: We use DB for forward deps (what this plugin requires)
     850            // but ONLY use curated static list for reverse deps (to prevent cascade)
    825851            $deps = [];
    826             $rdeps = [];
    827 
    828             if (!empty($db_dependency_map[$slug])) {
    829                 // Use database-stored dependencies (includes WP 6.5+ header data)
    830                 $deps = $db_dependency_map[$slug]['depends_on'] ?? [];
    831                 $rdeps = $db_dependency_map[$slug]['plugins_depending'] ?? [];
    832             } else {
    833                 // Fallback to static map
    834                 $deps = $fallback_dependencies[$slug] ?? [];
    835                 $rdeps = $fallback_reverse_deps[$slug] ?? [];
    836             }
    837 
    838             // Add direct dependencies
     852
     853            if (!empty($db_dependency_map[$slug]['depends_on'])) {
     854                // Use database-stored forward dependencies (includes WP 6.5+ header data)
     855                $deps = $db_dependency_map[$slug]['depends_on'];
     856            } elseif (isset($fallback_dependencies[$slug])) {
     857                // Fallback to static map for forward deps
     858                $deps = $fallback_dependencies[$slug];
     859            }
     860
     861            // Add direct dependencies (forward: what this plugin requires)
    839862            foreach ($deps as $dep) {
    840863                // Check for circular dependency before adding
     
    849872            }
    850873
    851             // Add reverse dependencies (if active)
    852             foreach ($rdeps as $rdep) {
    853                 if (!isset($to_load[$rdep]) && isset($active_set[$rdep])) {
    854                     // Check for circular dependency
    855                     $pair_key = $slug . '|' . $rdep;
    856                     if (!isset($circular_set[$pair_key])) {
    857                         $queue[] = $rdep;
     874            // Add reverse dependencies ONLY from curated static list
     875            // This prevents cascade loading of all WooCommerce/AffiliateWP extensions
     876            // Only jet-engine and elementor should pull in their core UI plugins
     877            if (isset($fallback_reverse_deps[$slug])) {
     878                foreach ($fallback_reverse_deps[$slug] as $rdep) {
     879                    if (!isset($to_load[$rdep]) && isset($active_set[$rdep])) {
     880                        // Check for circular dependency
     881                        $pair_key = $slug . '|' . $rdep;
     882                        if (!isset($circular_set[$pair_key])) {
     883                            $queue[] = $rdep;
     884                        }
    858885                    }
    859886                }
Note: See TracChangeset for help on using the changeset viewer.