From 57a6a318f25464b1943d6aabc975109590b34c57 Mon Sep 17 00:00:00 2001 From: David Parker Date: Fri, 9 Jun 2023 09:40:50 -0400 Subject: [PATCH 1/2] Using default level and discount code filters --- .../pmpro/class-swsales-module-pmpro.php | 160 +++++++++++++++++- 1 file changed, 155 insertions(+), 5 deletions(-) diff --git a/modules/ecommerce/pmpro/class-swsales-module-pmpro.php b/modules/ecommerce/pmpro/class-swsales-module-pmpro.php index 1921c10..2635eb9 100644 --- a/modules/ecommerce/pmpro/class-swsales-module-pmpro.php +++ b/modules/ecommerce/pmpro/class-swsales-module-pmpro.php @@ -44,15 +44,21 @@ public static function init() { // For the swsales_coupon helper function add_filter( 'swsales_coupon', array( __CLASS__, 'swsales_coupon' ), 10, 2 ); - // Default level for sale page. - add_action( 'wp', array( __CLASS__, 'load_pmpro_preheader' ), 0 ); // Priority 0 so that the discount code applies. - // Custom PMPro banner rules (hide for levels and hide at checkout). add_filter( 'swsales_is_checkout_page', array( __CLASS__, 'is_checkout_page' ), 10, 2 ); add_filter( 'swsales_show_banner', array( __CLASS__, 'show_banner' ), 10, 2 ); - // PMPro automatic discount application. - add_action( 'init', array( __CLASS__, 'automatic_discount_application' ) ); + // PMPro automatic discount application and default levels. + if ( version_compare( PMPRO_VERSION, '3.0', '>=' ) ) { + // PMPro 3.0+. Use filters for default level and discount code. + add_filter( 'wp', array( __CLASS__, 'enable_shortcodes_for_legacy_sitewide_sale_setups' ), 2 ); // Priority 2 so that it is the same as core PMPro. + add_filter( 'pmpro_default_level', array( __CLASS__, 'filter_default_level' ) ); + add_filter( 'pmpro_default_discount_code', array( __CLASS__, 'filter_default_discount_code' ), 10, 2 ); + } else { + // Use legacy function automatic_discount_application. + add_action( 'wp', array( __CLASS__, 'load_pmpro_preheader' ), 0 ); // Priority 0 so that the discount code applies. + add_action( 'init', array( __CLASS__, 'automatic_discount_application' ) ); + } // Hide discount code fields on SWSales landing page. add_action( 'wp_enqueue_scripts', array( __CLASS__, 'wp_enqueue_scripts' ) ); @@ -614,8 +620,150 @@ public static function get_default_level( $post_id = null ) { return $level_id; } + /** + * If we are on a landing page using the legacy [sitewide_sales] shortcode, + * enable PMPro shortcodes and load the corresponding preheaders. + * + * Only called in PMPro v3.0+. + */ + public static function enable_shortcodes_for_legacy_sitewide_sale_setups() { + // Make sure PMPro is loaded. + if ( ! defined( 'PMPRO_DIR' ) ) { + return; + } + + // Don't do this in the dashboard. + if ( is_admin() ) { + return; + } + + // Check if this is the landing page. + $queried_object = get_queried_object(); + if ( empty( $queried_object ) || empty( $queried_object->ID ) || null === classes\SWSales_Sitewide_Sale::get_sitewide_sale_for_landing_page( $queried_object->ID ) ) { + return; + } + + // If the [sitewide_sales] shortcode is not present, we don't need to force loading PMPro Shortcodes. + if ( ! has_shortcode( $queried_object->post_content, 'sitewide_sales' ) ) { + return; + } + + // Load checkout and levels shortcodes and preheaders in case they are used in the [sitewide_sales] shortcode. + add_shortcode( 'pmpro_checkout', array( __CLASS__, 'manual_pmpro_checkout_shortcode_implementation' ) ); + require_once PMPRO_DIR . '/preheaders/checkout.php'; + add_shortcode( 'pmpro_levels', array( __CLASS__, 'manual_pmpro_levels_shortcode_implementation' ) ); + require_once PMPRO_DIR . '/preheaders/levels.php'; + } + + /** + * Filter the default level at checkout. + * + * If we are on a landing page, use the default level set for the corresponding sale. + * If there is not a default level for this sale but the sale does have a discount code, choose a level that uses that code. + * + * If we we still don't have a level, we likely aren't on a specific landing page. Do the same steps for the active sale. + * + * Only called in PMPro v3.0+. + * + * @param int|null $level_id Default level ID. + * @return int|null + */ + public static function filter_default_level( $level_id ) { + global $post, $wpdb; + + // Check if we have a $post that may be a landing page. + if ( ! empty( $post ) && ! empty( $post->ID ) ) { + // Check if this post is a landing page. + $sitewide_sale = classes\SWSales_Sitewide_Sale::get_sitewide_sale_for_landing_page( $post->ID ); + if ( null !== $sitewide_sale ) { + // If this post has a sale with a default level set, use it. + $default_level_id = $sitewide_sale->get_meta_value( 'swsales_pmpro_landing_page_default_level' ); + if ( ! empty( $default_level_id ) ) { + return (int)$default_level_id; + } + + // If this post has a sale without a default level set, choose a level that the sale applies to and show that. + $discount_code_id = $sitewide_sale->get_meta_value( 'swsales_pmpro_discount_code_id' ); + if ( ! empty( $discount_code_id ) ) { + $first_code_level_id = $wpdb->get_var( "SELECT level_id FROM $wpdb->pmpro_discount_codes_levels WHERE code_id = '" . esc_sql( $discount_code_id ) . "' ORDER BY level_id LIMIT 1" ); + if ( ! empty( $first_code_level_id ) ) { + return (int)$first_code_level_id; + } + } + } + } + + // Check if there is an active sale that we are planning to apply an automatic discount to. + $sitewide_sale = classes\SWSales_Sitewide_Sale::get_active_sitewide_sale(); + if ( null !== $sitewide_sale && $sitewide_sale->should_apply_automatic_discount() ) { + // If the active sale has a default level set, use it. + $default_level_id = $sitewide_sale->get_meta_value( 'swsales_pmpro_landing_page_default_level' ); + if ( ! empty( $default_level_id ) ) { + return (int)$default_level_id; + } + + // If the active sale does not have a default level set, choose a level that the sale applies to and show that. + $discount_code_id = $sitewide_sale->get_meta_value( 'swsales_pmpro_discount_code_id' ); + if ( ! empty( $discount_code_id ) ) { + $first_code_level_id = $wpdb->get_var( "SELECT level_id FROM $wpdb->pmpro_discount_codes_levels WHERE code_id = '" . esc_sql( $discount_code_id ) . "' ORDER BY level_id LIMIT 1" ); + if ( ! empty( $first_code_level_id ) ) { + return (int)$first_code_level_id; + } + } + } + + // If we get here, SWS is not going to overwrite the default level. Return what we were passed. + return $level_id; + } + + /** + * Filter the default discount code at checkout. + * + * If we are on a landing page, use the discount code for that sale. + */ + public static function filter_default_discount_code( $discount_code, $level_id ) { + global $post, $wpdb; + + // Check if we have a $post that may be a landing page. + if ( ! empty( $post ) && ! empty( $post->ID ) ) { + // Check if this post is a landing page. + $sitewide_sale = classes\SWSales_Sitewide_Sale::get_sitewide_sale_for_landing_page( $post->ID ); + if ( null !== $sitewide_sale ) { + // If this post has a sale with a discount code set, use it. + $discount_code_id = $sitewide_sale->get_meta_value( 'swsales_pmpro_discount_code_id' ); + if ( ! empty( $discount_code_id ) ) { + $sale_discount_code = $wpdb->get_var( "SELECT code FROM $wpdb->pmpro_discount_codes WHERE id = '" . esc_sql( $discount_code_id ) . "' LIMIT 1" ); + if ( ! empty( $sale_discount_code ) && pmpro_checkDiscountCode( $sale_discount_code, $level_id ) ) { + return $sale_discount_code; + } + } + } + } + + // Check if there is an active sale that we should apply an automatic discount for. + $sitewide_sale = classes\SWSales_Sitewide_Sale::get_active_sitewide_sale(); + if ( null !== $sitewide_sale && $sitewide_sale->should_apply_automatic_discount() ) { + // If the active sale has a discount code set, use it. + $discount_code_id = $sitewide_sale->get_meta_value( 'swsales_pmpro_discount_code_id' ); + if ( ! empty( $discount_code_id ) ) { + $sale_discount_code = $wpdb->get_var( "SELECT code FROM $wpdb->pmpro_discount_codes WHERE id = '" . esc_sql( $discount_code_id ) . "' LIMIT 1" ); + if ( ! empty( $sale_discount_code ) && pmpro_checkDiscountCode( $sale_discount_code, $level_id ) ) { + return $sale_discount_code; + } + } + } + + // If we get here, SWS is not going to overwrite the default discount code. Return what we were passed. + return $discount_code; + } + + + + /** * Load the checkout and levels preheaders on the landing page. + * + * Legacy function for before PMPro v3.0. */ public static function load_pmpro_preheader() { global $wpdb; @@ -727,6 +875,8 @@ public static function show_banner( $show_banner, $sitewide_sale ) { /** * Automatically applies discount code if user has the cookie set from sale page + * + * Legacy function for before PMPro v3.0. */ public static function automatic_discount_application() { $active_sitewide_sale = classes\SWSales_Sitewide_Sale::get_active_sitewide_sale(); From da55a78eccb24b412d00522d0c03a37e782cc037 Mon Sep 17 00:00:00 2001 From: David Parker Date: Thu, 25 Jan 2024 12:23:14 -0500 Subject: [PATCH 2/2] Checking 3.0 class instead of version --- modules/ecommerce/pmpro/class-swsales-module-pmpro.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ecommerce/pmpro/class-swsales-module-pmpro.php b/modules/ecommerce/pmpro/class-swsales-module-pmpro.php index 2635eb9..ee346be 100644 --- a/modules/ecommerce/pmpro/class-swsales-module-pmpro.php +++ b/modules/ecommerce/pmpro/class-swsales-module-pmpro.php @@ -49,7 +49,7 @@ public static function init() { add_filter( 'swsales_show_banner', array( __CLASS__, 'show_banner' ), 10, 2 ); // PMPro automatic discount application and default levels. - if ( version_compare( PMPRO_VERSION, '3.0', '>=' ) ) { + if ( class_exists( 'PMPro_Subscription' ) ) { // PMPro 3.0+. Use filters for default level and discount code. add_filter( 'wp', array( __CLASS__, 'enable_shortcodes_for_legacy_sitewide_sale_setups' ), 2 ); // Priority 2 so that it is the same as core PMPro. add_filter( 'pmpro_default_level', array( __CLASS__, 'filter_default_level' ) );