saved_cart = get_user_meta( $user->ID, '_woocommerce_persistent_cart_' . get_current_blog_id(), true ); if ( ! $saved_cart ) { return; } $cart = WC()->session->cart; if ( empty( $cart ) || ! is_array( $cart ) || 0 === count( $cart ) ) { WC()->session->cart = $saved_cart['cart']; } } if ( ! function_exists( 'woocommerce_product_subcategories' ) ) { /** * This is a legacy function which used to check if we needed to display subcats and then output them. It was called by templates. * * From 3.3 onwards this is all handled via hooks and the woocommerce_maybe_show_product_subcategories function. * * Since some templates have not updated compatibility, to avoid showing incorrect categories this function has been deprecated and will * return nothing. Replace usage with woocommerce_output_product_categories to render the category list manually. * * This is a legacy function which also checks if things should display. * Themes no longer need to call these functions. It's all done via hooks. * * @deprecated 3.3.1 @todo Add a notice in a future version. * @param array $args Arguments. * @return null|boolean */ function woocommerce_product_subcategories( $args = array() ) { $defaults = array( 'before' => '', 'after' => '', 'force_display' => false, ); $args = wp_parse_args( $args, $defaults ); if ( $args['force_display'] ) { // We can still render if display is forced. woocommerce_output_product_categories( array( 'before' => $args['before'], 'after' => $args['after'], 'parent_id' => is_product_category() ? get_queried_object_id() : 0, ) ); return true; } else { // Output nothing. woocommerce_maybe_show_product_subcategories will handle the output of cats. $display_type = woocommerce_get_loop_display_mode(); if ( 'subcategories' === $display_type ) { // This removes pagination and products from display for themes not using wc_get_loop_prop in their product loops. @todo Remove in future major version. global $wp_query; if ( $wp_query->is_main_query() ) { $wp_query->post_count = 0; $wp_query->max_num_pages = 0; } } return 'subcategories' === $display_type || 'both' === $display_type; } } } /** * Products RSS Feed. * * @deprecated 2.6 * @return void */ function wc_products_rss_feed() { wc_deprecated_function( 'wc_products_rss_feed', '2.6' ); } if ( ! function_exists( 'woocommerce_reset_loop' ) ) { /** * Reset the loop's index and columns when we're done outputting a product loop. * * @deprecated 3.3 * @return void */ function woocommerce_reset_loop() { wc_reset_loop(); } } if ( ! function_exists( 'woocommerce_product_reviews_tab' ) ) { /** * Output the reviews tab content. * * @deprecated 2.4.0 Unused. * @return void */ function woocommerce_product_reviews_tab() { wc_deprecated_function( 'woocommerce_product_reviews_tab', '2.4' ); } } /** * Get the URL to the WooCommerce Legacy REST API. * * Note that as of WooCommerce 9.0 the WooCommerce Legacy REST API has been moved to a dedicated extension, * and the implementation of its root endpoint in WooCommerce core is now just a stub that will always return an error. * See the setup_legacy_api_stub method in includes/class-woocommerce.php and: * https://developer.woocommerce.com/2023/10/03/the-legacy-rest-api-will-move-to-a-dedicated-extension-in-woocommerce-9-0/ * * @deprecated 9.0.0 The Legacy REST API has been removed from WooCommerce core. * * @since 2.1 * @param string $path an endpoint to include in the URL. * @return string the URL. */ function get_woocommerce_api_url( $path ) { $url = get_home_url( null, 'wc-api/v3/', is_ssl() ? 'https' : 'http' ); if ( ! empty( $path ) && is_string( $path ) ) { $url .= ltrim( $path, '/' ); } return $url; } /** * Legacy REST API detection. * * This option used to be used to detect if the Legacy REST API was enabled, but the functionality was moved into a separate extension and deprecated. * The extension itself toggles this option between `yes` and `no` depending on whether the extension is active or not, but since this is the only * way to enable or disable the legacy API now, all we actually need to do is detect if the extension is active. * * @return string 'yes' or 'no'. */ add_filter( 'pre_option_woocommerce_api_enabled', function() { return WC()->legacy_rest_api_is_available() ? 'yes' : 'no'; } ); tion throw_on_error( $result ): void { if ( is_wp_error( $result ) ) { wp_send_json_error( [ 'message' => esc_html( $result->get_error_message() ), 'extra_data' => $result->get_error_data(), ] ); } } /** * @return void */ public function add_wc_scripts(): void { wp_enqueue_script( 'elementor-ai-unify-product-images', $this->get_js_assets_url( 'ai-unify-product-images' ), [ 'jquery', 'elementor-v2-ui', 'elementor-v2-icons', 'wp-components', 'elementor-common', ], ELEMENTOR_VERSION, true ); wp_localize_script( 'elementor-ai-unify-product-images', 'UnifyProductImagesConfig', [ 'get_product_images_url' => admin_url( 'admin-ajax.php' ), 'set_product_images_url' => admin_url( 'admin-ajax.php' ), 'nonce' => wp_create_nonce( 'elementor-ai-unify-product-images_nonce' ), 'placeholder' => ELEMENTOR_ASSETS_URL . 'images/app/ai/product-image-unification-example.gif?' . ELEMENTOR_VERSION, 'is_get_started' => User::get_introduction_meta( 'ai_get_started' ), 'connect_url' => $this->get_ai_connect_url(), ] ); add_filter( 'bulk_actions-edit-product', function ( $data ) { return $this->add_products_bulk_action( $data ); }); wp_set_script_translations( 'elementor-ai-unify-product-images', 'elementor' ); } /** * @param $product * @param int|null $image_to_remove * @param int|null $image_to_add * @return void */ private function update_product_gallery( $product, ?int $image_to_remove, ?int $image_to_add ): void { $gallery_image_ids = $product->get_gallery_image_ids(); $index = array_search( $image_to_remove, $gallery_image_ids, true ); if ( false !== $index ) { unset( $gallery_image_ids[ $index ] ); } if ( ! in_array( $image_to_add, $gallery_image_ids, true ) ) { $gallery_image_ids[] = $image_to_add; } $product->set_gallery_image_ids( $gallery_image_ids ); $product->save(); } }