_name = $plugin_name; $this->is_loop = false; $this->define_hooks(); } /** * Defined shortcode and hooks */ function define_hooks() { switch ( tinv_get_option( 'add_to_wishlist', 'position' ) ) { case 'before': add_action( 'tinvwl_before_add_to_cart_button', 'tinvwl_view_addto_html' ); add_action( 'tinvwl_single_product_summary', 'tinvwl_view_addto_htmlout' ); add_action( 'woocommerce_before_add_to_cart_button', 'tinvwl_view_addto_html', 9 ); add_action( 'woocommerce_single_product_summary', 'tinvwl_view_addto_htmlout', 29 ); add_action( 'catalog_visibility_before_alternate_add_to_cart_button', 'tinvwl_view_addto_html' ); break; case 'after': add_action( 'tinvwl_after_add_to_cart_button', 'tinvwl_view_addto_html' ); add_action( 'tinvwl_single_product_summary', 'tinvwl_view_addto_htmlout' ); add_action( 'woocommerce_after_add_to_cart_button', 'tinvwl_view_addto_html', 20 ); add_action( 'woocommerce_single_product_summary', 'tinvwl_view_addto_htmlout', 31 ); add_action( 'catalog_visibility_after_alternate_add_to_cart_button', 'tinvwl_view_addto_html' ); break; case 'thumbnails': add_action( 'tinvwl_after_thumbnails', 'tinvwl_view_addto_html' ); add_action( 'woocommerce_product_thumbnails', 'tinvwl_view_addto_html', 21 ); break; case 'summary': add_action( 'tinvwl_after_summary', 'tinvwl_view_addto_html' ); add_action( 'woocommerce_after_single_product_summary', 'tinvwl_view_addto_html', 11 ); break; } if ( tinv_get_option( 'add_to_wishlist_catalog', 'show_in_loop' ) ) { switch ( tinv_get_option( 'add_to_wishlist_catalog', 'position' ) ) { case 'before': add_action( 'tinvwl_after_shop_loop_item', 'tinvwl_view_addto_htmlloop' ); add_action( 'woocommerce_after_shop_loop_item', 'tinvwl_view_addto_htmlloop', 8 ); add_action( 'uael_woo_products_add_to_cart_before', 'tinvwl_view_addto_htmlloop' ); break; case 'above_thumb': add_action( 'tinvwl_above_thumb_loop_item', 'tinvwl_view_addto_htmlloop' ); add_action( 'woocommerce_before_shop_loop_item', 'tinvwl_view_addto_htmlloop', 9 ); add_action( 'uael_woo_products_before_summary_wrap', 'tinvwl_view_addto_htmlloop' ); break; case 'shortcode': break; case 'after': default: // Compatibility with previous versions. add_action( 'tinvwl_after_shop_loop_item', 'tinvwl_view_addto_htmlloop' ); add_action( 'woocommerce_after_shop_loop_item', 'tinvwl_view_addto_htmlloop', 20 ); add_action( 'uael_woo_products_add_to_cart_after', 'tinvwl_view_addto_htmlloop' ); break; } } // WooCommerce Blocks add_filter( 'woocommerce_blocks_product_grid_item_html', array( $this, 'htmloutput_block' ), 9, 3 ); add_filter( 'woocommerce_product_get_description', array( $this, 'woocommerce_blocks_all_products' ), 10, 2 ); add_action( 'init', array( $this, 'woocommerce_blocks' ) ); add_action( 'wp_loaded', array( $this, 'add_to_wishlist' ), 0 ); if ( is_user_logged_in() && apply_filters( 'tinvwl_allow_data_cookies', true ) ) { add_action( 'init', array( $this, 'set_wishlists_data_cookies' ) ); } } /** * Set cookies to sync session data across devices * * @return void */ function set_wishlists_data_cookies() { $class = TInvWL_Public_WishlistCounter::instance(); $counter = $class->get_counter(); wc_setcookie( 'tinvwl_wishlists_data_counter', $counter ); if ( tinv_get_option( 'general', 'product_stats' ) ) { global $wpdb; $table = sprintf( '%s%s', $wpdb->prefix, 'tinvwl_items' ); $table_lists = sprintf( '%s%s', $wpdb->prefix, 'tinvwl_lists' ); $table_stats = sprintf( '%s%s', $wpdb->prefix, 'tinvwl_analytics' ); $stats_count = 0; $stats_sql = "SELECT SUM(`count`) as `stats_count` FROM (SELECT COUNT(`B`.`ID`) AS `count` FROM `{$table_stats}` AS `A` LEFT JOIN `{$table}` AS `C` ON `C`.`wishlist_id` = `A`.`wishlist_id` AND `C`.`product_id` = `A`.`product_id` AND `C`.`variation_id` = `A`.`variation_id` LEFT JOIN `{$table_lists}` AS `B` ON `C`.`wishlist_id` = `B`.`ID` LEFT JOIN `{$table_lists}` AS `G` ON `C`.`wishlist_id` = `G`.`ID` AND `G`.`author` = 0 WHERE `A`.`product_id` > 0 GROUP BY `A`.`product_id`, `A`.`variation_id` HAVING `count` > 0 LIMIT 0, 9999999) AS `A`"; $stats_results = $wpdb->get_results( $stats_sql, ARRAY_A ); if ( ! empty( $stats_results ) ) { foreach ( $stats_results as $product_stats ) { $stats_count = $product_stats['stats_count']; } } if ( $stats_count ) { wc_setcookie( 'tinvwl_wishlists_data_stats', $stats_count ); } } } /** * Action add product to wishlist * * @return boolean */ function add_to_wishlist() { if ( is_null( filter_input( INPUT_POST, 'tinv_wishlist_id' ) ) ) { return false; } else { remove_action( 'init', 'woocommerce_add_to_cart_action' ); remove_action( 'wp_loaded', 'WC_Form_Handler::add_to_cart_action', 20 ); } ob_start(); $post = filter_input_array( INPUT_POST, array( 'tinv_wishlist_id' => FILTER_VALIDATE_INT, 'tinv_wishlist_name' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, 'product_id' => FILTER_VALIDATE_INT, 'product_variation' => FILTER_VALIDATE_INT, 'product_type' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, 'product_action' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, 'redirect' => FILTER_SANITIZE_URL, ) ); $post['original_product_id'] = $post['product_id']; $wlp = null; $wishlist = null; $data = array( 'msg' => array() ); if ( is_user_logged_in() ) { $wl = new TInvWL_Wishlist( $this->_name ); $wishlist = $wl->add_user_default(); $wishlist = apply_filters( 'tinvwl_addtowishlist_wishlist', $wishlist ); if ( empty( $wishlist ) ) { $data['status'] = false; $data = apply_filters( 'tinvwl_addtowishlist_return_ajax', $data, $post ); ob_clean(); wp_send_json( $data ); } $wlp = new TInvWL_Product( $wishlist, $this->_name ); } elseif ( tinv_get_option( 'general', 'require_login' ) ) { $data['status'] = false; $data['icon'] = 'icon_big_times'; if ( tinv_get_option( 'general', 'redirect_require_login' ) ) { $data['msg'] = array(); $data['force_redirect'] = apply_filters( 'tinvwl_addtowishlist_login_page', add_query_arg( 'tinvwl_redirect', rawurlencode( $post['redirect'] ), wc_get_page_permalink( 'myaccount' ) ), $post ); } else { $data['msg'][] = __( 'Please, login to add products to Wishlist', 'ti-woocommerce-wishlist' ); $data['dialog_custom_url'] = apply_filters( 'tinvwl_addtowishlist_login_page', add_query_arg( 'tinvwl_redirect', rawurlencode( $post['redirect'] ), wc_get_page_permalink( 'myaccount' ) ), $post ); $data['dialog_custom_html'] = '' . esc_html( __( 'Login', 'ti-woocommerce-wishlist' ) ); } $data['msg'] = array_unique( $data['msg'] ); $data['msg'] = implode( '
', $data['msg'] ); if ( ! empty( $data['msg'] ) ) { $data['msg'] = tinv_wishlist_template_html( 'ti-addedtowishlist-dialogbox.php', apply_filters( 'tinvwl_addtowishlist_dialog_box', $data, $post ) ); } $data = apply_filters( 'tinvwl_addtowishlist_return_ajax', $data, $post ); ob_clean(); wp_send_json( $data ); } else { $wl = new TInvWL_Wishlist( $this->_name ); $wishlist = $wl->add_sharekey_default(); $wlp = new TInvWL_Product( $wishlist ); } $status = true; if ( empty( $post['product_id'] ) || apply_filters( 'tinvwl_addtowishlist_not_allowed', false, $post ) ) { $status = false; $data['msg'][] = __( 'Something went wrong', 'ti-woocommerce-wishlist' ); } else { $post['product_type'] = apply_filters( 'tinvwl_addtowishlist_modify_type', $post['product_type'], $post ); $post = apply_filters( 'tinvwl_addtowishlist_prepare', $post ); $form = apply_filters( 'tinvwl_addtowishlist_prepare_form', filter_input( INPUT_POST, 'form', FILTER_DEFAULT, FILTER_FORCE_ARRAY ), $_POST, $_FILES ); if ( empty( $form ) ) { $form = array(); } wp_recursive_ksort( $form ); switch ( $post['product_type'] ) { case 'group': case 'grouped' : $product = $wlp->product_data( $post['product_id'] ); if ( empty( $product ) ) { $status = false; } else { $variations = $product->get_children(); foreach ( $variations as $variation_id ) { $quantity = 1; $allowed_adding = ! count( $wlp->get_wishlist( array( 'product_id' => $post['product_id'], 'variation_id' => $variation_id, 'external' => false, ) ) ); if ( tinv_get_option( 'general', 'simple_flow' ) && 'remove' === $post['product_action'] ) { if ( $wlp->remove_product_from_wl( 0, $post['product_id'], $variation_id, apply_filters( 'tinvwl_addtowishlist_add_form', $form ) ) ) { $data['msg'][] = apply_filters( 'tinvwl_removed_from_wishlist_text', tinv_get_option( 'general', 'text_removed_from' ) ); $data['removed'] = true; $status = false; } } elseif ( ! $allowed_adding ) { $data['msg'][] = apply_filters( 'tinvwl_already_in_wishlist_text', tinv_get_option( 'general', 'text_already_in' ) ); $status = false; } elseif ( $wlp->add_product( apply_filters( 'tinvwl_addtowishlist_add', array( 'product_id' => $post['product_id'], 'variation_id' => $variation_id, 'quantity' => $quantity, ) ) ) ) { $data['msg'][] = apply_filters( 'tinvwl_added_to_wishlist_text', tinv_get_option( 'general', 'text_added_to' ) ); } else { $status = false; } } } break; case 'variable' : case 'variation' : case 'variable-subscription' : if ( $post['product_variation'] ) { $variation_id = $post['product_variation']; } else { $variation_id = absint( array_key_exists( 'variation_id', $form ) ? filter_var( $form['variation_id'], FILTER_VALIDATE_INT ) : 0 ); } $post['original_product_id'] = $variation_id; $quantity = 1; $allowed_adding = ! count( $wlp->get_wishlist( array( 'product_id' => $post['product_id'], 'variation_id' => $variation_id, 'meta' => apply_filters( 'tinvwl_addtowishlist_add_form', $form ), 'external' => false, ) ) ); if ( tinv_get_option( 'general', 'simple_flow' ) && 'remove' === $post['product_action'] ) { if ( $wlp->remove_product_from_wl( 0, $post['product_id'], $variation_id, apply_filters( 'tinvwl_addtowishlist_add_form', $form ) ) ) { $data['msg'][] = apply_filters( 'tinvwl_removed_from_wishlist_text', tinv_get_option( 'general', 'text_removed_from' ) ); $data['removed'] = true; $status = false; } } elseif ( ! $allowed_adding ) { $data['msg'][] = apply_filters( 'tinvwl_already_in_wishlist_text', tinv_get_option( 'general', 'text_already_in' ) ); $status = false; } elseif ( $wlp->add_product( apply_filters( 'tinvwl_addtowishlist_add', array( 'product_id' => $post['product_id'], 'quantity' => $quantity, 'variation_id' => $variation_id, ) ), apply_filters( 'tinvwl_addtowishlist_add_form', $form ) ) ) { $data['msg'][] = apply_filters( 'tinvwl_added_to_wishlist_text', tinv_get_option( 'general', 'text_added_to' ) ); } else { $status = false; } break; case 'simple' : default: $quantity = 1; $allowed_adding = ! count( $wlp->get_wishlist( array( 'product_id' => $post['product_id'], 'meta' => apply_filters( 'tinvwl_addtowishlist_add_form', $form ), 'external' => false, ) ) ); if ( tinv_get_option( 'general', 'simple_flow' ) && 'remove' === $post['product_action'] ) { if ( $wlp->remove_product_from_wl( 0, $post['product_id'], 0, apply_filters( 'tinvwl_addtowishlist_add_form', $form ) ) ) { $data['msg'][] = apply_filters( 'tinvwl_removed_from_wishlist_text', tinv_get_option( 'general', 'text_removed_from' ) ); $data['removed'] = true; $status = false; } } elseif ( ! $allowed_adding ) { $data['msg'][] = apply_filters( 'tinvwl_already_in_wishlist_text', tinv_get_option( 'general', 'text_already_in' ) ); $status = false; } elseif ( $wlp->add_product( apply_filters( 'tinvwl_addtowishlist_add', array( 'product_id' => $post['product_id'], 'quantity' => $quantity, ) ), apply_filters( 'tinvwl_addtowishlist_add_form', $form ) ) ) { $data['msg'][] = apply_filters( 'tinvwl_added_to_wishlist_text', tinv_get_option( 'general', 'text_added_to' ) ); } else { $status = false; } break; } // End switch(). } // End if(). $data['status'] = $status; $data['wishlist_url'] = tinv_url_wishlist_default(); if ( ! empty( $wishlist ) ) { $data['wishlist_url'] = tinv_url_wishlist( $wishlist['ID'] ); } if ( $status && tinv_get_option( 'general', 'redirect' ) && tinv_get_option( 'page', 'wishlist' ) && tinv_get_option( 'general', 'show_notice' ) ) { $data['redirect'] = apply_filters( 'tinvwl_addtowishlist_redirect', $data['wishlist_url'] ); } if ( empty( $form ) ) { $form = array(); } $data['icon'] = $data['status'] ? 'icon_big_heart_check' : 'icon_big_times'; $data['msg'] = array_unique( $data['msg'] ); $data['msg'] = implode( '
', $data['msg'] ); $product = $original_product = wc_get_product( $post['product_id'] ); if ( $post['original_product_id'] && $post['product_id'] !== $post['original_product_id'] ) { $original_product = wc_get_product( $post['original_product_id'] ); } if ( ! empty( $data['msg'] ) ) { if ( $original_product ) { $data['msg'] = tinvwl_message_placeholders( $data['msg'], $original_product, $wishlist ); } $data['msg'] = apply_filters( 'tinvwl_addtowishlist_message_after', $data['msg'], $data, $post, $form, $product ); $data['wishlist'] = $wishlist; $data['msg'] = tinv_wishlist_template_html( 'ti-addedtowishlist-dialogbox.php', apply_filters( 'tinvwl_addtowishlist_dialog_box', $data, $post ) ); } if ( ! tinv_get_option( 'general', 'show_notice' ) && array_key_exists( 'msg', $data ) ) { unset( $data['msg'] ); if ( ! $status && ! tinv_get_option( 'general', 'simple_flow' ) ) { $data['force_redirect'] = $data['wishlist_url']; } } if ( tinv_get_option( 'general', 'simple_flow' ) ) { $data['make_remove'] = $data['status']; } $share_key = false; if ( ! is_user_logged_in() ) { $share_key = $wishlist['share_key']; } $data['action'] = 'add_to_wishlist'; $data['wishlists_data'] = $this->get_wishlists_data( $share_key ); $data = apply_filters( 'tinvwl_addtowishlist_return_ajax', $data, $post, $form, $product ); ob_clean(); wp_send_json( $data ); } /** * @param $share_key * * @return array */ function get_wishlists_data( $share_key ) { global $wpdb; $table = sprintf( '%s%s', $wpdb->prefix, 'tinvwl_items' ); $table_lists = sprintf( '%s%s', $wpdb->prefix, 'tinvwl_lists' ); $table_stats = sprintf( '%s%s', $wpdb->prefix, 'tinvwl_analytics' ); $table_translations = sprintf( '%s%s', $wpdb->prefix, 'icl_translations' ); $table_languages = sprintf( '%s%s', $wpdb->prefix, 'icl_languages' ); $lang = filter_input( INPUT_POST, 'lang', FILTER_SANITIZE_FULL_SPECIAL_CHARS ); $lang_default = filter_input( INPUT_POST, 'lang_default', FILTER_SANITIZE_FULL_SPECIAL_CHARS ); $stats = filter_input( INPUT_POST, 'stats', FILTER_SANITIZE_FULL_SPECIAL_CHARS ); $data = $products = $wishlists = $results = $analytics = array(); if ( is_user_logged_in() ) { $data['author'] = get_current_user_id(); } if ( ( isset( $data['author'] ) && $data['author'] ) || $share_key ) { $default = array( 'count' => 99999, 'field' => null, 'offset' => 0, 'order' => 'DESC', 'order_by' => 'date', 'external' => true, 'sql' => '', ); foreach ( $default as $_k => $_v ) { if ( array_key_exists( $_k, $data ) ) { $default[ $_k ] = $data[ $_k ]; unset( $data[ $_k ] ); } } $default['offset'] = absint( $default['offset'] ); $default['count'] = absint( $default['count'] ); if ( $lang ) { $default['field'] = $table . '.ID, t.element_id AS product_id, t2.element_id AS variation_id, ' . $table . '.formdata,' . $table . '.author,' . $table . '.date,' . $table . '.quantity,' . $table . '.price,' . $table . '.in_stock,'; } else { $default['field'] = $table . '.*, '; } $default['field'] .= $table_lists . '.ID as wishlist_id, ' . $table_lists . '.status as wishlist_status, ' . $table_lists . '.title as wishlist_title, ' . $table_lists . '.share_key as wishlist_share_key'; $sql = "SELECT {$default[ 'field' ]} FROM `{$table}` INNER JOIN `{$table_lists}` ON `{$table}`.`wishlist_id` = `{$table_lists}`.`ID` AND `{$table_lists}`.`type` = 'default'"; if ( $share_key ) { $sql .= " AND `{$table_lists}`.`share_key` = '{$share_key}'"; } if ( $lang ) { if ( $lang_default ) { $languages = sprintf( "'%s'", implode( "', '", array( $lang, $lang_default ) ) ); } else { $languages = "'" . $lang . "'"; } $sql .= "LEFT JOIN {$table_translations} tr ON {$table}.product_id = tr.element_id AND tr.element_type = 'post_product' LEFT JOIN {$table_translations} tr2 ON {$table}.variation_id != 0 AND {$table}.variation_id = tr2.element_id AND tr2.element_type = 'post_product_variation' LEFT JOIN {$table_translations} t ON tr.trid = t.trid AND t.element_type = 'post_product' AND t.language_code IN ({$languages}) LEFT JOIN {$table_translations} t2 ON {$table}.variation_id != 0 AND tr2.trid = t2.trid AND t2.element_type = 'post_product_variation' AND t2.language_code IN ({$languages}) JOIN {$table_languages} l ON ( t.language_code = l.code OR t2.language_code = l.code ) AND l.active = 1"; } $where = '1'; if ( ! empty( $data ) && is_array( $data ) ) { if ( array_key_exists( 'meta', $data ) ) { $product_id = $variation_id = 0; if ( array_key_exists( 'product_id', $data ) ) { $product_id = $data['product_id']; } if ( array_key_exists( 'variation_id', $data ) ) { $variation_id = $data['variation_id']; } $data['formdata'] = ''; unset( $data['meta'] ); } foreach ( $data as $f => $v ) { $s = is_array( $v ) ? ' IN ' : '='; if ( is_array( $v ) ) { foreach ( $v as $_f => $_v ) { $v[ $_f ] = $wpdb->prepare( '%s', $_v ); } $v = implode( ',', $v ); $v = "($v)"; } else { $v = $wpdb->prepare( '%s', $v ); } $data[ $f ] = sprintf( $table . '.' . '`%s`%s%s', $f, $s, $v ); } $where = implode( ' AND ', $data ); $sql .= ' WHERE ' . $where; } $sql .= sprintf( ' GROUP BY `%s`.ID ORDER BY `%s` %s LIMIT %d,%d;', $table, $default['order_by'], $default['order'], $default['offset'], $default['count'] ); if ( ! empty( $default['sql'] ) ) { $replacer = $replace = array(); $replace[0] = '{table}'; $replacer[0] = $table; $replace[1] = '{where}'; $replacer[1] = $where; foreach ( $default as $key => $value ) { $i = count( $replace ); $replace[ $i ] = '{' . $key . '}'; $replacer[ $i ] = $value; } $sql = str_replace( $replace, $replacer, $default['sql'] ); } $results = $wpdb->get_results( $sql, ARRAY_A ); if ( ! empty( $results ) ) { foreach ( $results as $product ) { $wishlists[ $product['wishlist_id'] ] = array( 'ID' => (int) $product['wishlist_id'], 'title' => $product['wishlist_title'], 'status' => $product['wishlist_status'], 'share_key' => $product['wishlist_share_key'], ); } foreach ( $wishlists as $wishlist ) { foreach ( $results as $product ) { if ( (int) $wishlist['ID'] !== (int) $product['wishlist_id'] ) { continue; } if ( array_key_exists( $product['product_id'], $products ) ) { $products[ $product['product_id'] ][ $wishlist['ID'] ]['in'][] = (int) $product['variation_id']; } else { $products[ $product['product_id'] ][ $wishlist['ID'] ] = $wishlist; $products[ $product['product_id'] ][ $wishlist['ID'] ]['in'][] = (int) $product['variation_id']; } } } } } if ( $stats ) { $stats_count = 0; $analytics = array(); $stats_sql = "SELECT `A`.`product_id`, `A`.`variation_id`, COUNT(`B`.`ID`) AS `count` FROM `{$table_stats}` AS `A` LEFT JOIN `{$table}` AS `C` ON `C`.`wishlist_id` = `A`.`wishlist_id` AND `C`.`product_id` = `A`.`product_id` AND `C`.`variation_id` = `A`.`variation_id` LEFT JOIN `{$table_lists}` AS `B` ON `C`.`wishlist_id` = `B`.`ID` LEFT JOIN `{$table_lists}` AS `G` ON `C`.`wishlist_id` = `G`.`ID` AND `G`.`author` = 0 WHERE `A`.`product_id` > 0 GROUP BY `A`.`product_id`, `A`.`variation_id` HAVING `count` > 0 LIMIT 0, 9999999"; $stats_results = $wpdb->get_results( $stats_sql, ARRAY_A ); if ( ! empty( $stats_results ) ) { foreach ( $stats_results as $product_stats ) { $analytics[ $product_stats['product_id'] ][ $product_stats['variation_id'] ] = $product_stats['count']; $stats_count = $stats_count + $product_stats['count']; } } } $count = is_array( $results ) ? count( $results ) : 0; $response = array( 'products' => $products, 'counter' => $count, ); if ( $lang ) { $response['lang'] = $lang; } if ( $lang_default ) { $response['lang_default'] = $lang_default; } if ( $stats ) { $response['stats'] = $analytics; $response['stats_count'] = $stats_count; } return $response; } /** * Get user wishlist * * @return array */ function user_wishlists() { if ( ! empty( $this->user_wishlist ) ) { return $this->user_wishlist; } $wl = new TInvWL_Wishlist( $this->_name ); if ( is_user_logged_in() ) { $wishlists = $wl->get_by_user_default(); } else { $wishlists = $wl->get_by_sharekey_default(); } $wishlists = array_filter( $wishlists ); if ( ! empty( $wishlists ) ) { $_wishlists = array(); foreach ( $wishlists as $key => $wishlist ) { if ( is_array( $wishlist ) && array_key_exists( 'ID', $wishlist ) ) { $_wishlists[ $key ] = array( 'ID' => $wishlist['ID'], 'title' => $wishlist['title'], 'url' => tinv_url_wishlist_by_key( $wishlist['share_key'] ), ); } } $wishlists = $_wishlists; } $this->user_wishlist = $wishlists; return $wishlists; } /** * Check exists product in user wishlists * * @param object $product Product object. * @param object $wlp Product class, used for local products. * * @return array */ function user_wishlist( $product, $wlp = null ) { $product = apply_filters( 'tinvwl_addtowishlist_check_product', $product ); $this->wishlist = array(); $vproduct = in_array( $product->get_type(), array( 'variable', 'variation', 'variable-subscription', ) ); $wlp = new TInvWL_Product(); $wishlists = $this->user_wishlists(); $ids = array(); foreach ( $wishlists as $key => $wishlist ) { $ids[] = $wishlist['ID']; } $ids = array_filter( $ids ); if ( empty( $ids ) ) { return $wishlists; } if ( ! $this->all_products ) { $this->all_products = $wlp->get( array( 'wishlist_id' => $ids, 'external' => false, 'count' => 9999999, ) ); } $products = array(); foreach ( $this->all_products as $_product ) { if ( $_product['product_id'] === $product->is_type( 'variation' ) ? $product->get_parent_id() : $product->get_id() ) { $products[] = $_product; } } $in = array(); if ( ! empty( $products ) ) { foreach ( $products as $product ) { $in[ $product['wishlist_id'] ][] = $product['variation_id']; } foreach ( $in as $wishlist_id => $products ) { sort( $in[ $wishlist_id ], SORT_NUMERIC ); if ( empty( $in[ $wishlist_id ] ) && ( $this->is_loop || ! $vproduct ) ) { $in[ $wishlist_id ] = true; } } } foreach ( $wishlists as $key => $wishlist ) { $wishlists[ $key ]['in'] = array_key_exists( $wishlist['ID'], $in ) ? $in[ $wishlist['ID'] ] : false; } $wishlists = apply_filters( 'tinvwl_addtowishlist_preparewishlists', $wishlists, $product ); $this->wishlist = $wishlists; return $wishlists; } /** * Create add button in loop * * @global object $product */ function htmloutput_loop() { global $product; if ( $product ) { if ( apply_filters( 'tinvwl_allow_addtowishlist_shop_loop_item', true, $product ) ) { // @codingStandardsIgnoreLine WordPress.PHP.StrictInArray.MissingTrueStrict $this->is_loop = true; $this->htmloutput(); $this->is_loop = false; } } } /** * Create add button if simple product out stock * * @global object $product */ function htmloutput_out() { global $product; if ( $product ) { $allow = false; if ( 'simple' === $product->get_type() ) { $allow = ( ( ! $product->is_purchasable() && '' == $product->get_price() ) || ( $product->is_purchasable() && ! $product->is_in_stock() ) ); } if ( in_array( $product->get_type(), array( 'variable', 'variable-subscription' ) ) ) { $get_variations = count( $product->get_children() ) <= apply_filters( 'woocommerce_ajax_variation_threshold', 30, $product ); $available_variations = $get_variations ? $product->get_available_variations() : false; $allow = ( empty( $available_variations ) && false !== $available_variations ); } if ( apply_filters( 'tinvwl_allow_addtowishlist_single_product_summary', $allow, $product ) ) { $this->htmloutput(); } } } /** * Output page * * @param array $attr Array parameter for shortcode. * @param boolean $is_shortcode Shortcode or action. * * @return boolean * @global object $product * */ function htmloutput( $attr = array(), $is_shortcode = false ) { $attr = apply_filters( 'tinvwl_addtowishlist_out_prepare_attr', $attr ); //is shortcode $this->variation_id = null; if ( $is_shortcode ) { $position = 'shortcode'; $product_id = ! empty( $attr['product_id'] ) ? absint( $attr['product_id'] ) : ( ( $this->product instanceof WC_Product ) ? $this->product->get_id() : null ); $variation_id = ! empty( $attr['variation_id'] ) ? absint( $attr['variation_id'] ) : null; if ( 'product_variation' == get_post_type( $product_id ) ) { // WPCS: loose comparison ok. $variation_id = $product_id; $product_id = wp_get_post_parent_id( $variation_id ); } $product_data = ( $product_id !== ( ( $this->product instanceof WC_Product ) ? $this->product->get_id() : null ) ) ? wc_get_product( $variation_id ? $variation_id : $product_id ) : $this->product; if ( $product_data instanceof WC_Product && 'trash' !== get_post( $product_data->get_id() )->post_status ) { $this->product = apply_filters( 'tinvwl_addtowishlist_out_prepare_product', $product_data ); } else { return false; } } else { global $product, $post; $_product = $product; if ( empty( $product ) && ! empty( $post ) && 'product' === $post->post_type ) { $_product = wc_get_product( $post->ID ); } $this->product = apply_filters( 'tinvwl_addtowishlist_out_prepare_product', $_product ); $position = $this->is_loop ? tinv_get_option( 'add_to_wishlist_catalog', 'position' ) : tinv_get_option( 'add_to_wishlist', 'position' ); } if ( empty( $this->product ) || ! ( $this->product instanceof WC_Product ) || ! apply_filters( 'tinvwl_allow_addtowishlist_single_product', true, $this->product ) ) { return false; } if ( isset( $variation_id ) ) { $this->variation_id = $variation_id; } if ( $this->is_loop && in_array( $this->product->get_type(), array( 'variable', 'variable-subscription', ) ) ) { $this->variation_ids = array(); if ( ! tinv_get_option( 'general', 'simple_flow' ) ) { foreach ( $this->product->get_children() as $oid ) { $this->variation_ids[] = apply_filters( 'wpml_object_id', $oid, 'product', true ); } } $this->variation_ids[] = 0; $this->variation_ids = apply_filters( 'tinvwl_wishlist_addtowishlist_button_variation_ids', $this->variation_ids, $this ); if ( ! isset( $this->variation_id ) ) { $this->variation_id = 0; $match_attributes = array(); foreach ( $this->product->get_default_attributes() as $attribute_name => $value ) { $match_attributes[ 'attribute_' . sanitize_title( $attribute_name ) ] = $value; } if ( $match_attributes ) { add_action( 'tinvwl_wishlist_addtowishlist_button', array( $this, 'default_variation_loop' ), 10, 2 ); $data_store = WC_Data_Store::load( 'product' ); $this->variation_id = $data_store->find_matching_product_variation( $this->product, $match_attributes ); } } } add_action( 'tinvwl_wishlist_addtowishlist_button', array( $this, 'button' ) ); $action_class = current_action() ? ' tinvwl-' . current_action() : ' tinvwl-no-action'; $data = array( 'class_postion' => sprintf( 'tinvwl-%s-add-to-cart', $position ) . ( $this->is_loop ? ' tinvwl-loop-button-wrapper' : '' ) . $action_class, 'product' => $this->product, 'variation_id' => ( $this->is_loop && in_array( ( $this->product->get_type() ), array( 'variable', 'variable-subscription', ) ) ) ? $this->variation_id : ( $this->product->is_type( 'variation' ) ? $this->product->get_id() : 0 ), 'button_icon' => tinv_get_option( 'add_to_wishlist' . ( $this->is_loop ? '_catalog' : '' ), 'icon' ), 'add_to_wishlist' => apply_filters( 'tinvwl_added_to_wishlist_text_loop', tinv_get_option( 'add_to_wishlist' . ( $this->is_loop ? '_catalog' : '' ), 'text' ) ), 'browse_in_wishlist' => apply_filters( 'tinvwl_view_wishlist_text', tinv_get_option( 'general', 'text_browse' ) ), 'product_in_wishlist' => apply_filters( 'tinvwl_already_in_wishlist_text', tinv_get_option( 'general', 'text_already_in' ) ), 'product_to_wishlist' => apply_filters( 'tinvwl_added_to_wishlist_text', tinv_get_option( 'general', 'text_added_to' ) ), 'loop' => $this->is_loop, ); tinv_wishlist_template( 'ti-addtowishlist.php', $data ); } /** * Create button * * @param boolean $echo Return or output. */ function button( $echo = true ) { $content = apply_filters( 'tinvwl_wishlist_button_before', '' ); $button_text = apply_filters( 'tinvwl_added_to_wishlist_text_loop', tinv_get_option( 'add_to_wishlist' . ( $this->is_loop ? '_catalog' : '' ), 'text' ) ); $text = ( tinv_get_option( 'add_to_wishlist' . ( $this->is_loop ? '_catalog' : '' ), 'show_text' ) ) ? $button_text : ''; $icon = tinv_get_option( 'add_to_wishlist' . ( $this->is_loop ? '_catalog' : '' ), 'icon' ); $icon_color = tinv_get_option( 'add_to_wishlist' . ( $this->is_loop ? '_catalog' : '' ), 'icon_style' ); $icon_class = ''; $action = 'addto'; if ( empty( $text ) ) { $icon_class = ' no-txt'; } else { $content .= '
'; if ( tinv_get_option( 'general', 'simple_flow' ) ) { $text = sprintf( '%s%s', $text, apply_filters( 'tinvwl_remove_from_wishlist_text' . ( $this->is_loop ? '_loop' : '' ), tinv_get_option( 'add_to_wishlist' . ( $this->is_loop ? '_catalog' : '' ), 'text_remove' ) ) ); } else { $already_on = tinv_get_option( 'add_to_wishlist' . ( $this->is_loop ? '_catalog' : '' ), 'already_on' ) ? sprintf( '%s', apply_filters( 'tinvwl_already_on_wishlist_text' . ( $this->is_loop ? '_loop' : '' ), tinv_get_option( 'add_to_wishlist' . ( $this->is_loop ? '_catalog' : '' ), 'text_already_on' ) ) ) : ''; $text = sprintf( '%s' . $already_on, $text ); } } if ( ! empty( $icon ) ) { $icon_upload = tinv_get_option( 'add_to_wishlist' . ( $this->is_loop ? '_catalog' : '' ), 'icon_upload' ); $icon_upload_added = tinv_get_option( 'add_to_wishlist' . ( $this->is_loop ? '_catalog' : '' ), 'icon_upload_added' ); if ( 'custom' === $icon && ! empty( $icon_upload ) ) { $text = sprintf( '%s %s', esc_url( $icon_upload ), esc_attr( apply_filters( 'tinvwl_add_to_wishlist_text_loop', tinv_get_option( 'add_to_wishlist' . ( $this->is_loop ? '_catalog' : '' ), 'text' ) ) ), $text ); if ( ! empty( $icon_upload_added ) ) { $text = sprintf( '%s %s', esc_url( $icon_upload_added ), esc_attr( apply_filters( 'tinvwl_added_to_wishlist_text_loop', tinv_get_option( 'add_to_wishlist' . ( $this->is_loop ? '_catalog' : '' ), 'text_already_on' ) ) ), $text ); } } $icon = 'tinvwl-icon-' . $icon; if ( 'custom' !== $icon && $icon_color ) { $icon .= ' icon-' . $icon_color; } } $icon .= $icon_class; $icon .= tinv_get_option( 'add_to_wishlist' . ( $this->is_loop ? '_catalog' : '' ), 'already_on' ) ? ' tinvwl-product-already-on-wishlist' : ''; $icon .= ' ' . tinv_get_option( 'add_to_wishlist' . ( $this->is_loop ? '_catalog' : '' ), 'class' ); $icon .= ' tinvwl-position-' . tinv_get_option( 'add_to_wishlist' . ( $this->is_loop ? '_catalog' : '' ), 'position' ); $icon .= ( tinv_get_option( 'add_to_wishlist' . ( $this->is_loop ? '_catalog' : '' ), 'show_preloader' ) ) ? ' ftinvwl-animated' : ''; $icon .= $this->is_loop ? ' tinvwl-loop' : ''; $product_variation = apply_filters( 'wpml_object_id', ( ( $this->is_loop && in_array( $this->product->get_type(), array( 'variable', 'variable-subscription', ) ) ) ? $this->variation_id : ( $this->product->is_type( 'variation' ) ? $this->product->get_id() : 0 ) ), 'product', true ); $content .= sprintf( '%s', esc_attr( sanitize_title( $button_text ) ), $button_text, $icon, apply_filters( 'wpml_object_id', ( $this->product->is_type( 'variation' ) ? $this->product->get_parent_id() : $this->product->get_id() ), 'product', true ), ( $product_variation ) ?: 0, json_encode( ( $this->is_loop && in_array( $this->product->get_type(), array( 'variable', 'variable-subscription', ) ) ) ? $this->variation_ids : ( $this->product->is_type( 'variation' ) ? array( $this->product->get_id() ) : array() ) ), $this->product->get_type(), $text ); $content .= apply_filters( 'tinvwl_wishlist_button_after', '' ); if ( ! empty( $text ) ) { $content .= '
'; } echo apply_filters( 'tinvwl_wishlist_button', $content, $this->wishlist, $this->product, $this->is_loop, $icon, $action, $text ); // WPCS: xss ok. } /** * Shortcode basic function * * @param array $atts Array parameter from shortcode. * * @return string * @global object $product * */ function shortcode( $atts = array() ) { global $product; $default = array( 'product_id' => 0, 'variation_id' => 0, 'loop' => 'no', ); if ( $product && is_a( $product, 'WC_Product' ) ) { $default['product_id'] = $product->is_type( 'variation' ) ? $product->get_parent_id() : $product->get_id(); $default['variation_id'] = $product->is_type( 'variation' ) ? $product->get_id() : 0; } $atts = shortcode_atts( $default, $atts ); ob_start(); if ( 'yes' === $atts['loop'] ) { $this->is_loop = true; $this->htmloutput( $atts, true ); $this->is_loop = false; } else { $this->htmloutput( $atts, true ); } return ob_get_clean(); } /** * Registers the WooCommerce blocks. */ function woocommerce_blocks() { /** * Registers the custom product label block. */ register_block_type( 'tinvwl/add-to-wishlist', [ 'render_callback' => array( $this, 'woocommerce_blocks_render' ), ] ); } /** * Renders the WooCommerce blocks. * * @param array $attributes The block attributes. * * @return string The rendered output. */ function woocommerce_blocks_render( $attributes ) { global $product; ob_start(); echo do_shortcode( '[ti_wishlists_addtowishlist loop=yes]' ); $output = ob_get_clean(); return $output; } /** * Add button to WC Blocks * * @filter woocommerce_blocks_product_grid_item_html */ function htmloutput_block( $html, $data, $product_object ) { global $product; $position = tinv_get_option( 'add_to_wishlist_catalog', 'position' ); if ( ! in_array( $position, array( 'before', 'after', 'above_thumb' ) ) ) { return $html; } $product = $product_object; ob_start(); tinvwl_view_addto_htmlloop(); $add_to_wishlist = ob_get_clean(); if ( ! $add_to_wishlist ) { return $html; } $add_to_wishlist_document = new Document(); $add_to_wishlist_document->load( $add_to_wishlist, false, Document::TYPE_HTML, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD ); $add_to_wishlist_element = $add_to_wishlist_document->toElement(); $product = ''; $document = new Document(); $document->load( $html, false, Document::TYPE_HTML, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD ); if ( 'above_thumb' === $position && $document->find( '.wc-block-grid__product-link' ) ) { $document->find( '.wc-block-grid__product-link' )[0]->insertSiblingBefore( $add_to_wishlist_element->getNode() ); } if ( 'before' === $position && $document->find( '.wc-block-grid__product-add-to-cart' ) ) { $document->find( '.wc-block-grid__product-add-to-cart' )[0]->insertSiblingBefore( $add_to_wishlist_element->getNode() ); } if ( 'after' === $position && $document->find( '.wc-block-grid__product-add-to-cart' ) ) { $document->find( '.wc-block-grid__product-add-to-cart' )[0]->insertSiblingAfter( $add_to_wishlist_element->getNode() ); } return $document->html(); } /** * Add button to WC Block All Products * */ function woocommerce_blocks_all_products( $description, $product_object ) { global $product; // This is basically the store_api init, but as that calls no action, we need to replicate the logic of its protected function // here for the time being. IOK 2020-09-02 if ( empty( $_SERVER['REQUEST_URI'] ) ) { return $description; } if ( ! did_action( 'rest_api_init' ) ) { return $description; } $request_uri = esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ); if ( preg_match( '/wc\/store(\/v\d)?\/products/', $request_uri ) !== 1 ) { return $description; } $product = $product_object; ob_start(); echo do_shortcode( '[ti_wishlists_addtowishlist loop=yes]' ); $add_to_wishlist = ob_get_clean(); $product = ''; return $description . $add_to_wishlist; } /** * Outputs hidden input fields for default variation attributes. * * @param WC_Product $product The product. * @param bool $loop Optional. Whether to enable the loop. Default is false. */ function default_variation_loop( $product, $loop ) { if ( $loop && in_array( $product->get_type(), array( 'variable', 'variable-subscription', ) ) ) { $match_attributes = []; foreach ( $product->get_default_attributes() as $attribute_name => $value ) { $match_attributes[ 'attribute_' . sanitize_title( $attribute_name ) ] = $value; } foreach ( $match_attributes as $name => $value ) { ?>