0 && self::enabled(); } public static function boot() { if ( self::$booted ) { return; } self::$booted = true; add_action( 'wp_ajax_aieo_card_variations', array( __CLASS__, 'ajax_variations' ) ); add_action( 'wp_ajax_nopriv_aieo_card_variations', array( __CLASS__, 'ajax_variations' ) ); if ( ! self::enabled() ) { return; } add_filter( 'render_block_data', array( __CLASS__, 'enter_template' ), 10, 2 ); add_filter( 'render_block_woocommerce/product-template', array( __CLASS__, 'leave_template' ), 10, 2 ); add_filter( 'render_block_woocommerce/product-image', array( __CLASS__, 'after_picture' ), 20, 3 ); add_action( 'wp_enqueue_scripts', array( __CLASS__, 'enqueue' ) ); add_filter( 'rooster/performance/delay_keep', array( __CLASS__, 'keep_script' ) ); } public static function keep_script( $handles ) { $handles = (array) $handles; $handles[] = 'aieo-card'; return $handles; } public static function enter_template( $parsed, $source = array() ) { if ( isset( $parsed['blockName'] ) && 'woocommerce/product-template' === $parsed['blockName'] ) { self::$depth++; } return $parsed; } public static function leave_template( $html, $block ) { self::$depth = max( 0, self::$depth - 1 ); self::load(); $tags = new WP_HTML_Tag_Processor( (string) $html ); if ( ! $tags->next_tag( 'ul' ) ) { return $html; } $tags->add_class( 'rc-grid' ); if ( 'swatches' === get_option( 'aieo_card_under_picture', 'stars' ) ) { $tags->add_class( 'rc-grid--swatches-first' ); } $tags->set_attribute( 'data-rooster-ui', 'rooster-one/product_archive_card' ); $choose = self::categories_choose() && '' === self::page_category_options_in(); $store = $choose ? self::store_options_in() : ''; $far = self::far_cards( (string) $html ); $card = -1; while ( $tags->next_tag( array( 'tag_name' => 'li', 'class_name' => 'wc-block-product' ) ) ) { $tags->add_class( 'rc-card' ); if ( ! empty( $far[ ++$card ] ) ) { $tags->set_attribute( 'data-rc-far', '' ); } if ( $choose && preg_match( '/\bpost-(\d+)\b/', (string) $tags->get_attribute( 'class' ), $id ) ) { $open = self::product_options_in( (int) $id[1] ); if ( '' !== $open && $open !== $store ) { $tags->set_attribute( 'data-rc-open', $open ); } } } return $tags->get_updated_html(); } private static function far_cards( $html ) { $far = array(); $scan = new WP_HTML_Tag_Processor( $html ); $card = -1; $seen = true; while ( $scan->next_tag() ) { if ( 'LI' === $scan->get_tag() && $scan->has_class( 'wc-block-product' ) ) { $card++; $seen = false; } elseif ( ! $seen && 'IMG' === $scan->get_tag() ) { $seen = true; $far[ $card ] = 'lazy' === strtolower( (string) $scan->get_attribute( 'loading' ) ); } } return $far; } private static function store_options_in() { return 'side_cart' === get_option( 'aieo_card_options_in', 'list' ) ? 'side_cart' : 'list'; } private static function categories_choose() { $terms = get_option( 'aieo_card_options_in_terms', array() ); return ! empty( $terms ) && is_array( $terms ); } private static function category_options_in( $term_id ) { $terms = get_option( 'aieo_card_options_in_terms', array() ); if ( empty( $terms ) || ! is_array( $terms ) ) { return ''; } foreach ( array_merge( array( (int) $term_id ), get_ancestors( (int) $term_id, 'product_cat', 'taxonomy' ) ) as $id ) { if ( isset( $terms[ $id ] ) ) { return 'side_cart' === $terms[ $id ] ? 'side_cart' : 'list'; } } return ''; } private static function page_category_options_in() { if ( ! function_exists( 'is_product_category' ) || ! is_product_category() ) { return ''; } $term = get_queried_object(); return $term instanceof WP_Term ? self::category_options_in( $term->term_id ) : ''; } private static function product_options_in( $product_id ) { $terms = get_the_terms( $product_id, 'product_cat' ); if ( ! is_array( $terms ) ) { return ''; } $choices = array(); foreach ( $terms as $term ) { $choice = self::category_options_in( $term->term_id ); if ( '' !== $choice ) { $choices[ $choice ] = true; } } return 1 === count( $choices ) ? (string) key( $choices ) : ''; } public static function page_options_in() { $own = self::page_category_options_in(); return '' !== $own ? $own : self::store_options_in(); } public static function after_picture( $html, $block, $instance = null ) { if ( self::$depth <= 0 || false === strpos( (string) $html, 'data-is-descendent-of-query-loop="true"' ) ) { return $html; } $pid = ( $instance instanceof WP_Block && ! empty( $instance->context['postId'] ) ) ? (int) $instance->context['postId'] : 0; if ( $pid <= 0 || ! class_exists( 'AIEO_DMM_Swatches_Runtime' ) || ! function_exists( 'wc_get_product' ) ) { return $html; } $product = wc_get_product( $pid ); if ( ! $product instanceof WC_Product ) { return $html; } return $html . AIEO_DMM_Swatches_Runtime::instance()->render_card_row_html( $product, self::CAP ); } public static function ajax_variations() { $pid = isset( $_REQUEST['product_id'] ) ? absint( $_REQUEST['product_id'] ) : 0; $product = $pid > 0 && function_exists( 'wc_get_product' ) ? wc_get_product( $pid ) : null; if ( ! $product instanceof WC_Product || ! $product->is_type( 'variable' ) || 'publish' !== get_post_status( $pid ) || ! class_exists( 'AIEO_DMM_Swatches_Runtime' ) ) { wp_send_json_error( array( 'message' => __( 'Invalid product.', 'ai-eshop-optimizer' ) ), 404 ); } $key = 'aieo_card_rows_' . $pid . '_' . ( class_exists( 'WC_Cache_Helper' ) ? WC_Cache_Helper::get_transient_version( 'product' ) : '0' ) . '_' . determine_locale(); $data = get_transient( $key ); if ( ! is_array( $data ) || ! isset( $data['rows'] ) ) { $data = AIEO_DMM_Swatches_Runtime::instance()->card_list_rows( $product ); foreach ( $data['rows'] as &$row ) { $row['in_cart'] = 0; } unset( $row ); set_transient( $key, $data, HOUR_IN_SECONDS ); } if ( function_exists( 'WC' ) && WC()->cart && ! WC()->cart->is_empty() ) { $in_cart = array(); foreach ( WC()->cart->get_cart() as $item ) { $vid = isset( $item['variation_id'] ) ? (int) $item['variation_id'] : 0; if ( $vid > 0 ) { $in_cart[ $vid ] = ( $in_cart[ $vid ] ?? 0 ) + (int) $item['quantity']; } } foreach ( $data['rows'] as &$row ) { $row['in_cart'] = (int) ( $in_cart[ $row['id'] ] ?? 0 ); } unset( $row ); } $thumb = wp_get_attachment_image_src( (int) $product->get_image_id(), 'thumbnail' ); wp_send_json_success( array( 'id' => $pid, 'name' => html_entity_decode( (string) $product->get_name(), ENT_QUOTES, 'UTF-8' ), 'url' => (string) get_permalink( $pid ), 'thumb' => is_array( $thumb ) ? (string) $thumb[0] : '', 'rows' => $data['rows'], 'styles' => $data['styles'], 'nonce' => wp_create_nonce( 'aieo_swatches_frontend' ), ) ); } private static function script_config() { return array( 'addUrl' => class_exists( 'WC_AJAX' ) ? WC_AJAX::get_endpoint( 'add_to_cart' ) : '', 'ajaxUrl' => admin_url( 'admin-ajax.php' ), 'cartUrl' => function_exists( 'wc_get_cart_url' ) ? wc_get_cart_url() : '', 'openIn' => self::page_options_in(), 'rowLayout' => class_exists( 'AIEO_DMM_Swatches_Runtime' ) ? AIEO_DMM_Swatches_Runtime::instance()->row_layout() : null, 'price' => array( 'decimals' => function_exists( 'wc_get_price_decimals' ) ? wc_get_price_decimals() : 2, 'decimal' => function_exists( 'wc_get_price_decimal_separator' ) ? wc_get_price_decimal_separator() : ',', 'thousand' => function_exists( 'wc_get_price_thousand_separator' ) ? wc_get_price_thousand_separator() : '.', 'symbol' => function_exists( 'get_woocommerce_currency_symbol' ) ? html_entity_decode( get_woocommerce_currency_symbol(), ENT_QUOTES, 'UTF-8' ) : '', 'pos' => (string) get_option( 'woocommerce_currency_pos', 'right_space' ), ), 'i18n' => array( 'addText' => __( 'Add to cart', 'woocommerce' ), 'addSelected' => __( 'Add selected to cart', 'ai-eshop-optimizer' ), 'viewCart' => __( 'View cart', 'woocommerce' ), 'done' => __( 'Done', 'ai-eshop-optimizer' ), 'close' => __( 'Close', 'ai-eshop-optimizer' ), 'find' => __( 'Find an option', 'ai-eshop-optimizer' ), 'each' => __( '%s each', 'ai-eshop-optimizer' ), 'from' => __( 'from %s', 'ai-eshop-optimizer' ), 'option' => __( '%d option', 'ai-eshop-optimizer' ), 'options' => __( '%d options', 'ai-eshop-optimizer' ), 'item' => __( '%d item', 'ai-eshop-optimizer' ), 'items' => __( '%d items', 'ai-eshop-optimizer' ), 'inCart' => __( '%d in cart', 'ai-eshop-optimizer' ), 'outOfStock' => __( 'Out of stock', 'woocommerce' ), 'onlyLeft' => __( 'Only %d left', 'ai-eshop-optimizer' ), 'fewer' => __( 'Fewer', 'ai-eshop-optimizer' ), 'more' => __( 'More', 'ai-eshop-optimizer' ), 'tick' => __( 'Tick at least one option.', 'ai-eshop-optimizer' ), 'addedOne' => __( '1 item added to your cart', 'ai-eshop-optimizer' ), 'added' => __( '%d items added to your cart', 'ai-eshop-optimizer' ), 'addedSome' => __( 'Some of the items could not be added. Your cart shows what was added.', 'ai-eshop-optimizer' ), 'noMatch' => __( 'No option matches ā€œ%sā€', 'ai-eshop-optimizer' ), 'failed' => __( 'We could not reach the cart. Your selection is kept: try again.', 'ai-eshop-optimizer' ), ), ); } public static function enqueue() { $wants = function_exists( 'is_woocommerce' ) && is_woocommerce(); if ( ! $wants ) { $post = get_post(); $wants = $post instanceof WP_Post && ( has_block( 'woocommerce/product-collection', $post ) || has_block( 'woocommerce/product-template', $post ) ); } if ( $wants ) { self::load(); } } public static function load() { self::load_style(); if ( wp_script_is( 'aieo-card', 'enqueued' ) ) { return; } $root = dirname( __DIR__ ); $js = ( ! defined( 'SCRIPT_DEBUG' ) || ! SCRIPT_DEBUG ) && file_exists( $root . '/assets/js/aieo-card.min.js' ) ? 'assets/js/aieo-card.min.js' : 'assets/js/aieo-card.js'; wp_enqueue_script( 'aieo-card', plugins_url( $js, __DIR__ ), array(), (string) filemtime( $root . '/' . $js ), array( 'in_footer' => true, 'strategy' => 'async' ) ); wp_add_inline_script( 'aieo-card', 'window.aieoCardCfg=' . wp_json_encode( self::script_config() ) . ';', 'before' ); } public static function load_style() { if ( wp_style_is( 'aieo-card', 'enqueued' ) ) { return; } $root = dirname( __DIR__ ); $rel = ( ! defined( 'SCRIPT_DEBUG' ) || ! SCRIPT_DEBUG ) && file_exists( $root . '/assets/css/aieo-card.min.css' ) ? 'assets/css/aieo-card.min.css' : 'assets/css/aieo-card.css'; wp_enqueue_style( 'aieo-card', plugins_url( $rel, __DIR__ ), array(), (string) filemtime( $root . '/' . $rel ) ); } } endif;