this, 'elementor_woocommerce_checkout_login_user' ] ); add_action( 'wp_ajax_nopriv_elementor_woocommerce_checkout_login_user', [ $this, 'elementor_woocommerce_checkout_login_user' ] ); add_action( 'wp_ajax_elementor_menu_cart_fragments', [ $this, 'menu_cart_fragments' ] ); add_action( 'wp_ajax_nopriv_elementor_menu_cart_fragments', [ $this, 'menu_cart_fragments' ] ); add_filter( 'woocommerce_add_to_cart_fragments', [ $this, 'e_cart_count_fragments' ] ); add_filter( 'elementor/theme/need_override_location', [ $this, 'theme_template_include' ], 10, 2 ); add_filter( 'elementor/document/config', [ $this, 'add_loop_recommended_widgets' ], 11, 2 ); add_filter( 'elementor_pro/frontend/localize_settings', [ $this, 'localized_settings_frontend' ] ); // Load our widget Before WooCommerce Ajax. See the variable's PHPDoc for details. add_action( 'woocommerce_checkout_update_order_review', [ $this, 'load_widget_before_wc_ajax' ] ); add_action( 'woocommerce_before_calculate_totals', [ $this, 'load_widget_before_wc_ajax' ] ); // On Editor - Register WooCommerce frontend hooks before the Editor init. // Priority = 5, in order to allow plugins remove/add their wc hooks on init. $action = ProUtils::_unstable_get_super_global_value( $_REQUEST, 'action' ); if ( 'elementor' === $action && is_admin() ) { add_action( 'init', [ $this, 'register_wc_hooks' ], 5 ); } // Allow viewing of Checkout page in the Editor with an empty cart. if ( ( 'elementor' === $action && is_admin() ) // Elementor Editor || 'elementor_ajax' === $action // Elementor Editor Preview - Ajax Render Widget || ProUtils::_unstable_get_super_global_value( $_REQUEST, 'elementor-preview' ) // Elementor Editor Preview ) { add_filter( 'woocommerce_checkout_redirect_empty_cart', '__return_false', 5 ); } if ( $this->use_mini_cart_template ) { add_filter( 'woocommerce_locate_template', [ $this, 'woocommerce_locate_template' ], 10, 3 ); } $wc_ajax = ProUtils::_unstable_get_super_global_value( $_REQUEST, 'wc-ajax' ); if ( 'get_refreshed_fragments' === $wc_ajax ) { add_action( 'woocommerce_add_to_cart_fragments', [ $this, 'products_query_sources_fragments' ] ); // Render the Empty Cart Template on WC fragment refresh add_action( 'woocommerce_add_to_cart_fragments', [ $this, 'empty_cart_fragments' ] ); } add_filter( 'elementor/widgets/wordpress/widget_args', [ $this, 'woocommerce_wordpress_widget_css_class' ], 10, 2 ); add_action( 'elementor/ajax/register_actions', [ $this, 'register_ajax_actions' ] ); // Make the Logout redirect go to our my account widget page instead of the set My Account Page. add_action( 'init', [ $this, 'elementor_wc_my_account_logout' ], 5 ); add_filter( 'elementor_pro/editor/localize_settings', [ $this, 'add_localize_data' ] ); add_action( 'wp', [ $this, 'maybe_define_woocommerce_checkout' ] ); add_filter( 'woocommerce_get_endpoint_url', [ $this, 'get_order_received_endpoint_url' ], 10, 3 ); // Filters for messages on the Shipping calculator add_filter( 'woocommerce_shipping_may_be_available_html', function ( $html ) { return $this->print_woocommerce_shipping_message( $html, 'woocommerce-shipping-may-be-available-html e-checkout-message e-cart-content' ); }, 10, 1 ); add_filter( 'woocommerce_shipping_not_enabled_on_cart_html', function ( $html ) { return $this->print_woocommerce_shipping_message( $html, 'woocommerce-shipping-not_enabled-on-cart-html e-checkout-message e-cart-content' ); }, 10, 1 ); add_filter( 'woocommerce_shipping_estimate_html', function ( $html ) { return $this->print_woocommerce_shipping_message( $html, 'woocommerce-shipping-estimate-html e-checkout-message e-cart-content' ); }, 10, 1 ); add_filter( 'woocommerce_cart_no_shipping_available_html', function ( $html ) { return $this->print_woocommerce_shipping_message( $html, 'woocommerce-cart-no-shipping-available-html e-checkout-message e-cart-content' ); }, 10, 1 ); add_filter( 'woocommerce_no_available_payment_methods_message', function ( $html ) { return $this->print_woocommerce_shipping_message( $html, 'woocommerce-no-available-payment-methods-message e-description' ); }, 10, 1 ); add_filter( 'woocommerce_no_shipping_available_html', function ( $html ) { return $this->print_woocommerce_shipping_message( $html, 'woocommerce-no-shipping-available-html e-checkout-message' ); }, 10, 1 ); add_action( 'woocommerce_add_to_cart', [ $this, 'localize_added_to_cart_on_product_single' ] ); foreach ( LoopBuilderModule::LOOP_WIDGETS as $widget_type ) { add_action( 'elementor/widget/' . $widget_type . '/skins_init', function( Widget_Base $widget ) { $widget->add_skin( new Skin_Loop_Product( $widget ) ); } ); } // WooCommerce Notice Site Settings add_filter( 'body_class', [ $this, 'e_notices_body_classes' ] ); add_filter( 'wp_enqueue_scripts', [ $this, 'e_notices_css' ] ); add_filter( 'elementor/query/query_args', function( $query_args, $widget ) { return $this->loop_query( $query_args, $widget ); }, 10, 2 ); add_filter( 'woocommerce_rest_prepare_system_status', function( $response, $system_status, $request ) { return $this->add_system_status_data( $response, $system_status, $request ); }, 10, 3 ); add_filter( 'elementor/editor/localize_settings', function ( $config ) { return $this->populate_persistent_settings( $config ); }); } public function add_system_status_data( $response, $system_status, $request ) { foreach ( $response->data['pages'] as $index => $wc_page ) { $this->modify_response_if_widget_exists_in_page( $wc_page, $response, $index ); } return $response; } private function modify_response_if_widget_exists_in_page( $wc_page, &$response, $index ) { if ( empty( $wc_page['page_name'] ) || empty( $wc_page['page_id'] ) || ! array_key_exists( $wc_page['page_name'], static::WC_STATUS_PAGES_MAPPED_TO_WIDGETS ) ) { return; } if ( isset( $wc_page['shortcode_present'] ) && false !== $wc_page['shortcode_present'] ) { return; } $document = Plugin::elementor()->documents->get( $wc_page['page_id'] ); if ( ! $document || ! $document->is_built_with_elementor() ) { return; } $elementor_data = get_post_meta( $wc_page['page_id'], '_elementor_data', true ); $widget_name = static::WC_STATUS_PAGES_MAPPED_TO_WIDGETS[ $wc_page['page_name'] ]; $widget_exists_in_page = false !== strpos( $elementor_data, $widget_name ); if ( $widget_exists_in_page ) { $response->data['pages'][ $index ]['shortcode_present'] = true; } } public function loop_query( $query_args, $widget ) { if ( ! $this->is_product_query( $widget ) ) { return $query_args; } return $this->parse_loop_query_args( $widget, $query_args ); } private function is_product_query( $widget ) { $widget_config = $widget->get_config(); return ( ! empty( $widget_config['is_loop'] ) && 'product' === $widget->get_current_skin_id() ); } private function parse_loop_query_args( $widget, $query_args ) { $settings = $this->adjust_setting_for_product_renderer( $widget ); // For Products_Renderer. if ( ! isset( $GLOBALS['post'] ) ) { $GLOBALS['post'] = null; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited } $shortcode = Products_Widget::get_shortcode_object( $settings ); $parsed_query_args = $shortcode->parse_query_args(); unset( $parsed_query_args['fields'] ); $override_various_query_args = array_filter( $query_args, function( $key ) { return in_array( $key, [ 'posts_per_page', 'offset', 'paged' ], true ); }, ARRAY_FILTER_USE_KEY ); return wp_parse_args( $override_various_query_args, $parsed_query_args ); } private function adjust_setting_for_product_renderer( $widget ) { $settings = $widget->get_settings_for_display(); $query_name = $widget->get_query_name(); $unique_query_settings = array_filter( $settings, function( $key ) use ( $query_name ) { return 0 === strpos( $key, $query_name ); }, ARRAY_FILTER_USE_KEY ); $query_settings = []; foreach ( $unique_query_settings as $key => $value ) { $query_settings[ 'query' . str_replace( $query_name, '', $key ) ] = $value; } $settings = array_merge( $settings, $query_settings ); if ( isset( $settings['posts_per_page'] ) && isset( $settings['columns'] ) ) { $settings['rows'] = ceil( $settings['posts_per_page'] / $settings['columns'] ); } $settings['paginate'] = 'yes'; $settings['allow_order'] = 'no'; $settings['show_result_count'] = 'no'; $settings['query_fields'] = false; return $settings; } /** * @param $post_id * @return bool */ private function is_source_set_to_products( $post_id ) { return 'product' === get_post_meta( $post_id, '_elementor_source', true ); } /** * @param array $config * @return array */ private function add_woocommerce_widgets_to_recommended( array $config ) { foreach ( static::RECOMMENDED_POSTS_WIDGET_NAMES as $recommended_posts_widget_name ) { $config['panel']['widgets_settings'][ $recommended_posts_widget_name ] = [ 'categories' => [ 'recommended' ], 'show_in_panel' => true, ]; } return $config; } private function hide_woocommerce_widgets_in_loop_document( array $config ) { $config['panel']['widgets_settings']['woocommerce-product-images'] = [ 'show_in_panel' => false, ]; return $config; } private function populate_persistent_settings( array $config ) { $config['persistent_keys'] = array_key_exists( 'persistent_keys', $config ) ? array_merge( $config['persistent_keys'], self::WC_PERSISTENT_SITE_SETTINGS ) : self::WC_PERSISTENT_SITE_SETTINGS; return $config; } }