File: /var/www/chameleon/wp-content/plugins/variation-swatches-woo/inc/swatches.php
<?php
/**
* Swatches.
*
* @package variation-swatches-woo
* @since 1.0.0
*/
namespace CFVSW\Inc;
use CFVSW\Inc\Traits\Get_Instance;
use CFVSW\Inc\Helper;
use CFVSW\Compatibility\Astra;
use CFVSW\Compatibility\Cartflows_Pro;
use WC_AJAX;
/**
* Admin menu
*
* @since 1.0.0
*/
class Swatches {
use Get_Instance;
/**
* Instance of Helper class
*
* @var Helper
* @since 1.0.0
*/
private $helper;
/**
* Stores global and store settings
*
* @var array
* @since 1.0.0
*/
private $settings = [];
/**
* Post meta variation swatches type.
*
* @var boolean
* @since 1.0.2
*/
private $product_option_type = false;
/**
* Postmeta variation attributes swatches value product lavel.
*
* @var array
* @since 1.0.2
*/
private $product_option_swatches = [];
/**
* Constructor
*
* @since 1.0.0
*/
public function __construct() {
$this->helper = new Helper();
$this->settings[ CFVSW_GLOBAL ] = $this->helper->get_option( CFVSW_GLOBAL );
$this->settings[ CFVSW_SHOP ] = $this->helper->get_option( CFVSW_SHOP );
$this->settings[ CFVSW_STYLE ] = $this->helper->get_option( CFVSW_STYLE );
if ( class_exists( 'Cartflows_Pro_Loader' ) ) {
new Cartflows_Pro();
}
add_filter( 'woocommerce_ajax_variation_threshold', [ $this, 'cfvsw_ajax_variation_threshold' ], 100, 2 );
add_action( 'template_redirect', [ $this, 'shortcode_functionality' ], 10 );
if (
$this->settings[ CFVSW_GLOBAL ]['enable_swatches'] || $this->settings[ CFVSW_GLOBAL ]['enable_swatches_shop']
) {
add_filter( 'woocommerce_dropdown_variation_attribute_options_html', [ $this, 'variation_attribute_custom_html' ], 999, 2 );
add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_scripts' ] );
$position = $this->get_swatches_position();
add_action( $position['action'], [ $this, 'variation_attribute_html_shop_page' ], $position['priority'] );
add_filter( 'body_class', [ $this, 'label_position_class' ], 10, 2 );
add_filter( 'woocommerce_loop_add_to_cart_args', [ $this, 'shop_page_add_to_cart_args' ], 10, 2 );
}
add_action( 'wp_ajax_cfvsw_ajax_add_to_cart', [ $this, 'cfvsw_ajax_add_to_cart' ] );
add_action( 'wp_ajax_nopriv_cfvsw_ajax_add_to_cart', [ $this, 'cfvsw_ajax_add_to_cart' ] );
add_filter( 'woocommerce_layered_nav_term_html', [ $this, 'filters_html' ], 10, 4 );
}
/**
* Add variation in product shortcode functionality.
*
* @return void
* @since 1.0.4
*/
public function shortcode_functionality() {
$add_filter = false;
$woocommerce_shortcodes = [ 'products', 'featured_products', 'sale_products', 'best_selling_products', 'recent_products', 'product_attribute', 'top_rated_products', 'product_category' ];
foreach ( $woocommerce_shortcodes as $value ) {
if ( wc_post_content_has_shortcode( $value ) ) {
$add_filter = true;
break;
}
}
if ( $add_filter ) {
add_filter( 'cfvsw_requires_shop_settings', '__return_true' );
} elseif ( wc_post_content_has_shortcode( 'product_page' ) ) {
add_filter( 'cfvsw_requires_global_settings', '__return_true' );
}
}
/**
* Get swatches postmeta options.
*
* @param integer $product_id Product id.
* @param array $args_attribute Attribute arguments.
* @param boolean $attribute_id Attribute id.
* @return void
* @since 1.0.2
*/
public function get_product_swatches( $product_id, $args_attribute, $attribute_id ) {
// Clean variables.
if ( $this->product_option_type ) {
$this->product_option_type = false;
$this->product_option_swatches = [];
}
$product_meta_slug = $attribute_id ? CFVSW_PRODUCT_ATTR . '_' . $args_attribute : CFVSW_PRODUCT_ATTR . '_' . $this->helper->create_slug( $args_attribute );
$get_meta_options = get_post_meta( $product_id, $product_meta_slug, true );
if ( empty( $get_meta_options['type'] ) ) {
return;
}
$this->product_option_type = $get_meta_options['type'];
unset( $get_meta_options['type'] );
if ( count( $get_meta_options ) > 0 ) {
if ( 'image' === $this->product_option_type ) {
foreach ( $get_meta_options as $key => $value ) {
if ( empty( $value[ $this->product_option_type ] ) ) {
continue;
}
$image_id = intval( $value[ $this->product_option_type ] );
$get_image_url = $image_id ? wp_get_attachment_url( $image_id ) : false;
if ( ! $get_image_url ) {
continue;
}
$this->product_option_swatches[ $key ] = $get_image_url;
}
} else {
foreach ( $get_meta_options as $key => $value ) {
if ( empty( $value[ $this->product_option_type ] ) ) {
continue;
}
$custom_product_meta = $value[ $this->product_option_type ];
$this->product_option_swatches[ $key ] = $custom_product_meta;
}
}
}
}
/**
* Get attribute term color.
*
* @param integer $attr_id Attribute id.
* @param string $slug Term slug.
* @param string $args Attribute options.
* @param string $for It should be color or image.
* @return array
* @since 1.0.2
*/
public function get_attr_term_color_image( $attr_id, $slug, $args, $for ) {
$default_value = 'color' === $for ? '#fff' : CFVSW_URL . '/admin/assets/img/wc-placeholder.png';
$term_name = $slug;
if ( $attr_id ) {
$term = get_term_by( 'slug', $slug, $args['attribute'] );
if ( $this->product_option_type ) {
$get_value = ! empty( $this->product_option_swatches[ $term->term_id ] ) ? $this->product_option_swatches[ $term->term_id ] : $default_value;
} else {
$meta_name = 'color' === $for ? 'cfvsw_color' : 'cfvsw_image';
$get_value = get_term_meta( $term->term_id, $meta_name, true );
}
$term_name = $term->name;
} else {
$get_value_by_slug = $this->helper->create_slug( $slug );
$get_value = ! empty( $this->product_option_swatches[ $get_value_by_slug ] ) ? $this->product_option_swatches[ $get_value_by_slug ] : $default_value;
}
$return = [
'term_name' => $term_name,
$for => $get_value,
];
return $return;
}
/**
* Get attribute term label.
*
* @param integer $attr_id Attribute id.
* @param string $slug Term slug.
* @param string $args Attribute options.
* @return string
* @since 1.0.2
*/
public function get_attr_term_label( $attr_id, $slug, $args ) {
$term = get_term_by( 'slug', $slug, $args['attribute'] );
$name = ! empty( $term->name ) ? $term->name : $slug;
if ( $attr_id && $this->product_option_type ) {
$name = ! empty( $this->product_option_swatches[ $term->term_id ] ) ? $this->product_option_swatches[ $term->term_id ] : $name;
} elseif ( $this->product_option_type ) {
$get_label_slug = $this->helper->create_slug( $slug );
$name = ! empty( $this->product_option_swatches[ $get_label_slug ] ) ? $this->product_option_swatches[ $get_label_slug ] : $name;
}
return $name;
}
/**
* Return variation product attributes.
*
* @param string $select_html Default attribute template.
* @param array $args Attributes settings options.
* @return string
* @since 1.0.0
*/
public function variation_attribute_custom_html( $select_html, $args ) {
global $product;
$settings = [];
$container_class = '';
if ( ! $this->is_required_page() ) {
return $select_html;
}
if ( $this->requires_shop_settings() ) {
if ( ! $this->settings[ CFVSW_GLOBAL ]['enable_swatches_shop'] ) {
return $select_html;
}
$settings = $this->settings[ CFVSW_SHOP ]['override_global'] ? $this->settings[ CFVSW_SHOP ] : array_merge( $this->settings[ CFVSW_SHOP ], $this->settings[ CFVSW_GLOBAL ] );
$settings['auto_convert'] = true;
if ( ! isset( $settings['tooltip'] ) ) {
$settings['tooltip'] = $this->settings[ CFVSW_GLOBAL ]['tooltip'];
}
$container_class = 'cfvsw-shop-container';
}
if ( $this->requires_global_settings() ) {
if ( ! $this->settings[ CFVSW_GLOBAL ]['enable_swatches'] ) {
return $select_html;
}
$settings = $this->settings[ CFVSW_GLOBAL ];
$container_class = 'cfvsw-product-container';
}
if ( empty( $settings ) ) {
return $select_html;
}
// Retrieve the product from the filter if not available then use the Global Product.
$product = ! empty( $args['product'] ) && is_a( $args['product'], 'WC_Product_Variable' ) ? $args['product'] : $product;
$attribute = $product->get_attributes();
$attr_id = isset( $attribute[ strtolower( $args['attribute'] ) ] ) ? $attribute[ strtolower( $args['attribute'] ) ]->get_id() : 0;
$shape = get_option( "cfvsw_product_attribute_shape-$attr_id", 'default' );
$size = absint( get_option( "cfvsw_product_attribute_size-$attr_id", '' ) );
$height = absint( get_option( "cfvsw_product_attribute_height-$attr_id", '' ) );
$width = absint( get_option( "cfvsw_product_attribute_width-$attr_id", '' ) );
$min_width = ! empty( $settings['min_width'] ) ? $settings['min_width'] . 'px' : '24px';
$min_height = ! empty( $settings['min_height'] ) ? $settings['min_height'] . 'px' : '24px';
$border_radius = $settings['border_radius'] . 'px';
switch ( $shape ) {
case 'circle':
$min_width = $size ? $size . 'px' : '24px';
$min_height = $size ? $size . 'px' : '24px';
$border_radius = '100%';
break;
case 'square':
$min_width = $size ? $size . 'px' : '24px';
$min_height = $size ? $size . 'px' : '24px';
$border_radius = '0px';
break;
case 'rounded':
$min_width = $size ? $size . 'px' : '24px';
$min_height = $size ? $size . 'px' : '24px';
$border_radius = '3px';
break;
case 'custom':
$min_width = $width ? $width . 'px' : '24px';
$min_height = $height ? $height . 'px' : '24px';
$border_radius = '0px';
break;
default:
break;
}
$product_id = ! empty( $args['product'] ) ? intval( $args['product']->get_id() ) : false;
if ( $product_id ) {
$this->get_product_swatches( $product_id, $args['attribute'], $attr_id );
}
$type = $this->product_option_type ? $this->product_option_type : $this->helper->get_attr_type_by_name( $args['attribute'] );
$limit = isset( $settings['limit'] ) ? intval( $settings['limit'] ) : 0;
$attr_options_mix = $this->get_attr_option_by_sorting( $product_id, $args['attribute'], $limit, $args['options'] );
$attr_options = $attr_options_mix['options'];
$more = $attr_options_mix['more'];
$get_attribute_name = wc_variation_attribute_name( $args['attribute'] );
$common_style = 'min-width:' . $min_width . ';';
$common_style .= 'min-height:' . $min_height . ';';
$common_style .= 'border-radius:' . $border_radius . ';';
switch ( $type ) {
case 'color':
$html = "<div class='cfvsw-swatches-container " . esc_attr( $container_class ) . "' swatches-attr='" . esc_attr( $get_attribute_name ) . "'>";
foreach ( $attr_options as $slug ) {
$get_term_data = $this->get_attr_term_color_image( $attr_id, $slug, $args, 'color' );
$term_name = $get_term_data['term_name'];
$color = $get_term_data['color'];
$tooltip = $settings['tooltip'] ? $term_name : '';
$style = $common_style;
$inner_style = 'background-color:' . $color . ';';
$html .= "<div class='cfvsw-swatches-option ' data-slug='" . esc_attr( $slug ) . "' data-title='" . esc_attr( $term_name ) . "' data-tooltip='" . esc_attr( $tooltip ) . "' style=" . esc_attr( $style ) . '><div class="cfvsw-swatch-inner" style="' . esc_attr( $inner_style ) . '"></div></div>';
}
$html .= $more ? '<span class="cfvsw-more-link" style="line-height:' . esc_attr( $min_height ) . '">' . $more . '</span' : '';
$html .= '</div>';
break;
case 'image':
$html = "<div class='cfvsw-swatches-container " . esc_attr( $container_class ) . "' swatches-attr='" . esc_attr( $get_attribute_name ) . "'>";
foreach ( $attr_options as $slug ) {
$get_term_data = $this->get_attr_term_color_image( $attr_id, $slug, $args, 'image' );
$term_name = $get_term_data['term_name'];
$image = $get_term_data['image'];
$tooltip = $settings['tooltip'] ? $term_name : '';
$style = $common_style;
$inner_style = "background-image:url('" . esc_url( $image ) . "');background-size:cover;";
$html .= "<div class='cfvsw-swatches-option cfvsw-image-option' data-slug='" . esc_attr( $slug ) . "' data-title='" . esc_attr( $term_name ) . "' data-tooltip='" . esc_attr( $tooltip ) . "' style=" . esc_attr( $style ) . '>';
$html .= '<div class="cfvsw-swatch-inner" style="' . $inner_style . '"></div></div>';
}
$html .= $more ? '<span class="cfvsw-more-link" style="line-height:' . esc_attr( $min_height ) . '">' . $more . '</span' : '';
$html .= '</div>';
break;
default:
if ( 'label' !== $type && ! $settings['auto_convert'] ) {
break;
}
$html = "<div class='cfvsw-swatches-container " . esc_attr( $container_class ) . "' swatches-attr='" . esc_attr( $get_attribute_name ) . "'>";
foreach ( $attr_options as $slug ) {
$style = $common_style;
$name = $this->get_attr_term_label( $attr_id, $slug, $args );
$html .= "<div class='cfvsw-swatches-option cfvsw-label-option' data-slug='" . esc_attr( $slug ) . "' data-title='" . esc_attr( $name ) . "' style=" . esc_attr( $style ) . '><div class="cfvsw-swatch-inner">' . esc_html( $name ) . '</div></div>';
}
$html .= $more ? '<span class="cfvsw-more-link" style="line-height:' . esc_attr( $min_height ) . '">' . $more . '</span' : '';
$html .= '</div>';
break;
}
if ( ! empty( $html ) ) {
return '<div class="cfvsw-hidden-select">' . $select_html . '</div>' . $html;
}
return $select_html;
}
/**
* Get attribute options.
*
* @param integer $product_id Current product id.
* @param string $attribute Attribute slug.
* @param integer $limit Show swatches limit.
* @param integer $options For custom attribute options.
* @return array
* @since 1.0.2
*/
public function get_attr_option_by_sorting( $product_id, $attribute, $limit, $options ) {
$attr_terms = wc_get_product_terms( $product_id, $attribute, [ 'fields' => 'all' ] );
if ( ! empty( $attr_terms ) ) {
$attr_terms = array_map(
function ( $value ) {
return $value->slug;
},
$attr_terms
);
$attr_terms = array_intersect( $attr_terms, $options );
} else {
$attr_terms = $options;
}
if ( $limit > 0 && $limit < count( $attr_terms ) ) {
$permalink = get_permalink( $product_id );
/* translators: %1$1s, %3$3s: Html Tag, %2$2s: Extra attribute count */
$more = sprintf( __( '%1$1s %2$2s More %3$3s', 'variation-swatches-woo' ), '<a href="' . esc_url( $permalink ) . '">', ( count( $attr_terms ) - $limit ), '</a>' );
return [
'options' => array_splice( $attr_terms, 0, $limit ),
'more' => $more,
];
}
return [
'options' => $attr_terms,
'more' => '',
];
}
/**
* Add catalog attribute funationality on shop page.
*
* @param array $settings Product settings.
* @param int $product_id Product id.
* @param array $attributes Product attributes.
* @return array
* @since 1.0.3
*/
public function catalog_show_attr_shop_page( $settings, $product_id, $attributes ) {
// Get global level attr.
$get_global_saved_attr = ! empty( $settings['special_attr_choose'] ) ? sanitize_text_field( $settings['special_attr_choose'] ) : '';
// Verify global attr exist or not.
if ( '' !== $get_global_saved_attr ) {
if ( ! taxonomy_is_product_attribute( $get_global_saved_attr ) ) {
$get_global_saved_attr = '';
}
}
// Get product level attr.
$get_product_saved_attr = get_post_meta( $product_id, sanitize_text_field( CFVSW_PRODUCT_ATTR . '_catalog_attr' ), true );
// Compare and show attr.
$show_attr_name = ! empty( $get_product_saved_attr ) && ! empty( $attributes[ $get_product_saved_attr ] ) ? $get_product_saved_attr : $get_global_saved_attr;
// Show first attr.
if ( empty( $show_attr_name ) ) {
$show_attr_name = array_key_first( $attributes );
}
return ! empty( $attributes[ $show_attr_name ] ) ? [ $show_attr_name => $attributes[ $show_attr_name ] ] : false;
}
/**
* Generates variation attributes for shop page
*
* @return void
* @since 1.0.0
*/
public function variation_attribute_html_shop_page() {
global $product;
if ( ! $this->settings[ CFVSW_GLOBAL ]['enable_swatches_shop'] ) {
return;
}
if ( ! $this->requires_shop_settings() ) {
return;
}
// Return of product is not found.
if ( empty( $product ) ) {
return;
}
if ( ! $product->is_type( 'variable' ) ) {
return;
}
if ( ! $product->get_available_variations() ) {
return;
}
$product_id = $product->get_id();
$settings = $this->settings[ CFVSW_SHOP ];
// Get Available variations?
$get_variations = count( $product->get_children() ) <= apply_filters( 'woocommerce_ajax_variation_threshold', 30, $product );
$available_variations = $get_variations ? $product->get_available_variations() : false;
$attributes = $product->get_variation_attributes();
// Catlog mode functionality.
$count_attr_for_catalog = '';
if ( ! empty( $settings['special_attr_archive'] ) ) {
$count_attr_for_catalog = count( $attributes ) > 1 ? 'data-cfvsw-catalog=1' : '';
$attributes = $this->catalog_show_attr_shop_page( $settings, $product_id, $attributes );
if ( empty( $attributes ) ) {
return;
}
}
$attribute_keys = array_keys( $attributes );
$variations_json = apply_filters( 'cfvsw_available_variations', wp_json_encode( $available_variations ) );
?>
<div class="cfvsw_variations_form variations_form cfvsw_shop_align_<?php echo esc_attr( $settings['alignment'] ); ?>" data-product_variations="<?php echo esc_attr( $variations_json ); ?>" data-product_id="<?php echo absint( $product_id ); ?>" <?php echo esc_attr( $count_attr_for_catalog ); ?>>
<?php if ( empty( $available_variations ) && false !== $available_variations ) { ?>
<p class="stock out-of-stock"><?php echo esc_html( apply_filters( 'woocommerce_out_of_stock_message', __( 'This product is currently out of stock and unavailable.', 'variation-swatches-woo' ) ) ); ?></p>
<?php } else { ?>
<table class="cfvsw-shop-variations variations" cellspacing="0">
<tbody>
<?php foreach ( $attributes as $attribute_name => $options ) { ?>
<tr>
<?php if ( $settings['label'] ) { ?>
<td class="label woocommerce-loop-product__title"><label for="<?php echo esc_attr( sanitize_title( $attribute_name ) ); ?>">
<?php echo esc_html( wc_attribute_label( $attribute_name ) ); ?>
</label>
</td>
<?php } ?>
</tr>
<tr>
<td class="value">
<?php
wc_dropdown_variation_attribute_options(
array(
'options' => $options,
'attribute' => $attribute_name,
'product' => $product,
)
);
echo end( $attribute_keys ) === $attribute_name ? wp_kses_post( apply_filters( 'woocommerce_reset_variations_link', '<a class="reset_variations" href="#">' . esc_html__( 'Clear', 'variation-swatches-woo' ) . '</a>' ) ) : '';
?>
</td>
</tr>
<?php } ?>
</tbody>
</table>
<?php } ?>
</div>
<?php
}
/**
* Enqueue scripts and style for frontend
*
* @return void
* @since 1.0.0
*/
public function enqueue_scripts() {
if ( ! $this->is_required_page() ) {
return;
}
wp_register_style( 'cfvsw_swatches_product', CFVSW_URL . 'assets/css/swatches.css', [ 'dashicons' ], CFVSW_VER );
wp_enqueue_style( 'cfvsw_swatches_product' );
$this->inline_css();
wp_register_script( 'cfvsw_swatches_product', CFVSW_URL . 'assets/js/swatches.js', [ 'jquery', 'wc-add-to-cart-variation' ], CFVSW_VER, true );
wp_enqueue_script( 'cfvsw_swatches_product' );
wp_localize_script(
'cfvsw_swatches_product',
'cfvsw_swatches_settings',
[
'ajax_url' => admin_url( 'admin-ajax.php' ),
'admin_url' => admin_url( 'admin.php' ),
'remove_attr_class' => $this->get_remove_attr_class(),
'html_design' => $this->settings[ CFVSW_GLOBAL ]['html_design'],
'unavailable_text' => __( 'Selected variant is unavailable.', 'variation-swatches-woo' ),
'ajax_add_to_cart_nonce' => wp_create_nonce( 'cfvsw_ajax_add_to_cart' ),
'tooltip_image' => $this->settings[ CFVSW_STYLE ]['tooltip_image'],
'disable_out_of_stock' => $this->settings[ CFVSW_GLOBAL ]['disable_out_of_stock'],
]
);
}
/**
* Adds inline css
*
* @return void
* @since 1.0.0
*/
public function inline_css() {
$style = $this->settings[ CFVSW_STYLE ];
$settings = array();
if ( $this->requires_shop_settings() ) {
$settings = $this->settings[ CFVSW_SHOP ]['override_global'] ? $this->settings[ CFVSW_SHOP ] : array_merge( $this->settings[ CFVSW_SHOP ], $this->settings[ CFVSW_GLOBAL ] );
}
if ( $this->requires_global_settings() ) {
$settings = $this->settings[ CFVSW_GLOBAL ];
}
$custom_css = '';
if ( ! empty( $style['tooltip_background'] ) && ! empty( $style['tooltip_font_color'] ) ) {
$custom_css .= '.cfvsw-tooltip{background:' . $style['tooltip_background'] . ';color:' . $style['tooltip_font_color'] . ';}';
$custom_css .= ' .cfvsw-tooltip:before{background:' . $style['tooltip_background'] . ';}';
}
$custom_css .= ':root {';
$custom_css .= ! empty( $settings['font_size'] ) ? "--cfvsw-swatches-font-size: {$settings['font_size']}px;" : '';
$custom_css .= ! empty( $style['border_color'] ) ? "--cfvsw-swatches-border-color: {$style['border_color']};" : '';
$custom_css .= ! empty( $style['border_color'] ) ? "--cfvsw-swatches-border-color-hover: {$style['border_color']}80;" : '';
$custom_css .= ! empty( $settings['border_width'] ) ? "--cfvsw-swatches-border-width: {$settings['border_width']}px;" : '';
$custom_css .= ! empty( $style['label_font_size'] ) ? "--cfvsw-swatches-label-font-size: {$style['label_font_size']}px;" : '';
$custom_css .= ! empty( $style['tooltip_font_size'] ) ? "--cfvsw-swatches-tooltip-font-size: {$style['tooltip_font_size']}px;" : '';
$custom_css .= '}';
if ( ! empty( $custom_css ) ) {
wp_add_inline_style( 'cfvsw_swatches_product', $custom_css );
}
}
/**
* Class for disable attribute type
*
* @return string
* @since 1.0.0
*/
public function get_remove_attr_class() {
$disable_class = '';
$settings = [];
if ( $this->requires_shop_settings() ) {
$settings = $this->settings[ CFVSW_SHOP ]['override_global'] ? $this->settings[ CFVSW_SHOP ] : $this->settings[ CFVSW_GLOBAL ];
}
if ( $this->requires_global_settings() ) {
$settings = $this->settings[ CFVSW_GLOBAL ];
}
// If the disable type is not set or empty in any case, then simply hide the attributes.
if ( empty( $settings['disable_attr_type'] ) ) {
$disable_class = 'cfvsw-swatches-hide';
return $disable_class;
}
switch ( $settings['disable_attr_type'] ) {
case 'blurCross':
$disable_class = 'cfvsw-swatches-blur-cross';
break;
default:
$disable_class = 'cfvsw-swatches-' . $settings['disable_attr_type'];
break;
}
return $disable_class;
}
/**
* Returns the position of swatches on shop page
*
* @return array
* @since 1.0.0
*/
public function get_swatches_position() {
$this->check_theme_compatibility();
$position = apply_filters(
'cfvsw_swatches_shop_page_position',
[
'before_title' => [
'action' => 'woocommerce_shop_loop_item_title',
'priority' => 0,
],
'after_title' => [
'action' => 'woocommerce_shop_loop_item_title',
'priority' => 9999,
],
'before_price' => [
'action' => 'woocommerce_after_shop_loop_item_title',
'priority' => 9,
],
'after_price' => [
'action' => 'woocommerce_after_shop_loop_item_title',
'priority' => 11,
],
]
);
$key = ! empty( $this->settings[ CFVSW_SHOP ]['position'] ) ? $this->settings[ CFVSW_SHOP ]['position'] : 'before_title';
return ! empty( $position[ $key ] ) ? $position[ $key ] : $position['before_title'];
}
/**
* Enqueues compatibility files only if particular theme is active
*
* @return void
* @since 1.0.0
*/
public function check_theme_compatibility() {
$current_theme = wp_get_theme();
if ( ! empty( $current_theme->template ) && 'astra' === $current_theme->template ) {
$astra = new Astra();
$astra->get_shop_positions();
}
}
/**
* Adds class to WooCommerce wrapper
*
* @param array $classes existing classes.
* @return array
* @since 1.0.0
*/
public function label_position_class( $classes ) {
if ( ! $this->requires_global_settings() ) {
return $classes;
}
$settings = $this->settings[ CFVSW_GLOBAL ];
if ( $settings['enable_swatches'] && isset( $settings['html_design'] ) ) {
$classes[] = 'cfvsw-label-' . esc_html( strtolower( $settings['html_design'] ) );
$classes[] = 'cfvsw-product-page';
return $classes;
}
return $classes;
}
/**
* Arguments for shop page add to cart button
*
* @param array $args array of button arguments.
* @param object $product curreent product object.
* @return array
* @since 1.0.0
*/
public function shop_page_add_to_cart_args( $args, $product ) {
if ( $product->is_type( 'variable' ) ) {
$args['class'] .= ' cfvsw_ajax_add_to_cart';
$args['attributes']['data-add_to_cart_text'] = esc_html__( 'Add to Cart', 'variation-swatches-woo' );
$args['attributes']['data-select_options_text'] = apply_filters( 'woocommerce_product_add_to_cart_text', $product->add_to_cart_text(), $product );
}
return $args;
}
/**
* Add to cart functionality for shop page
*
* @return mixed
* @since 1.0.0
*/
public function cfvsw_ajax_add_to_cart() {
check_ajax_referer( 'cfvsw_ajax_add_to_cart', 'security' );
if ( empty( $_POST['product_id'] ) ) {
return;
}
$product_id = apply_filters( 'woocommerce_add_to_cart_product_id', absint( $_POST['product_id'] ) );
$product_title = get_the_title( $product_id );
$quantity = ! empty( $_POST['quantity'] ) ? wc_stock_amount( absint( $_POST['quantity'] ) ) : 1;
$product_status = get_post_status( $product_id );
$variation_id = ! empty( $_POST['variation_id'] ) ? absint( $_POST['variation_id'] ) : 0;
$variation = ! empty( $_POST['variation'] ) ? array_map( 'sanitize_text_field', $_POST['variation'] ) : array();
$passed_validation = apply_filters( 'woocommerce_add_to_cart_validation', true, $product_id, $quantity, $variation_id, $variation );
$cart_page_url = wc_get_cart_url();
if ( $passed_validation && false !== WC()->cart->add_to_cart( $product_id, $quantity, $variation_id, $variation ) && 'publish' === $product_status ) {
do_action( 'woocommerce_ajax_added_to_cart', $product_id );
if ( 'yes' === get_option( 'woocommerce_cart_redirect_after_add' ) ) {
wc_add_to_cart_message( array( $product_id => $quantity ), true );
} else {
$added_to_cart_notice = sprintf(
/* translators: %s: Product title */
esc_html__( '"%1$s" has been added to your cart. %2$s', 'variation-swatches-woo' ),
esc_html( $product_title ),
'<a href="' . esc_url( $cart_page_url ) . '">' . esc_html__( 'View Cart', 'variation-swatches-woo' ) . '</a>'
);
wc_add_notice( $added_to_cart_notice );
}
WC_AJAX::get_refreshed_fragments();
} else {
// If there was an error adding to the cart, redirect to the product page to show any errors.
$data = array(
'error' => true,
'product_url' => apply_filters( 'woocommerce_cart_redirect_after_error', get_permalink( $product_id ), $product_id ),
);
wp_send_json( $data );
}
}
/**
* This function returns true if current page is compatible for variation swatches
*
* @return bool
* @since 1.0.0
*/
public function is_required_page() {
return apply_filters(
'cfvsw_is_required_page',
$this->requires_global_settings() || $this->requires_shop_settings()
);
}
/**
* This function returns true if current page is product type page
*
* @return bool
* @since 1.0.0
*/
public function requires_global_settings() {
return apply_filters(
'cfvsw_requires_global_settings',
is_product()
);
}
/**
* This function returns true if current page is shop / archieve type page
*
* @return bool
* @since 1.0.0
*/
public function requires_shop_settings() {
return apply_filters(
'cfvsw_requires_shop_settings',
is_shop() || is_product_category() || is_product_taxonomy()
);
}
/**
* Generates swatches html for filters
*
* @param string $term_html default html.
* @param object $term current term object.
* @param string $link filter link.
* @param integer $count total product associated with term count.
* @return string
* @since 1.0.0
*/
public function filters_html( $term_html, $term, $link, $count ) {
if ( empty( $this->settings[ CFVSW_STYLE ]['filters'] ) ) {
return $term_html;
}
$type = $this->helper->get_attr_type_by_name( $term->taxonomy );
$settings = [];
$container_class = '';
if ( ! $this->is_required_page() ) {
return $term_html;
}
if ( $this->requires_shop_settings() ) {
if ( ! $this->settings[ CFVSW_GLOBAL ]['enable_swatches_shop'] ) {
return $term_html;
}
$settings = $this->settings[ CFVSW_SHOP ]['override_global'] ? $this->settings[ CFVSW_SHOP ] : array_merge( $this->settings[ CFVSW_SHOP ], $this->settings[ CFVSW_GLOBAL ] );
if ( ! isset( $settings['tooltip'] ) ) {
$settings['tooltip'] = $this->settings[ CFVSW_GLOBAL ]['tooltip'];
}
$settings['auto_convert'] = true;
}
if ( $this->requires_global_settings() ) {
if ( ! $this->settings[ CFVSW_GLOBAL ]['enable_swatches'] ) {
return $term_html;
}
$settings = $this->settings[ CFVSW_GLOBAL ];
}
if ( empty( $settings ) ) {
return $term_html;
}
$attr_id = $term->term_id;
$shape = get_option( "cfvsw_product_attribute_shape-$attr_id", 'default' );
$size = absint( get_option( "cfvsw_product_attribute_size-$attr_id", '' ) );
$height = absint( get_option( "cfvsw_product_attribute_height-$attr_id", '' ) );
$width = absint( get_option( "cfvsw_product_attribute_width-$attr_id", '' ) );
$min_width = ! empty( $settings['min_width'] ) ? $settings['min_width'] . 'px' : '24px';
$min_height = ! empty( $settings['min_height'] ) ? $settings['min_height'] . 'px' : '24px';
$border_radius = ! empty( $settings['border_radius'] ) ? $settings['border_radius'] . 'px' : '0';
switch ( $shape ) {
case 'circle':
$min_width = $size ? $size . 'px' : '24px';
$min_height = $size ? $size . 'px' : '24px';
$border_radius = '100%';
break;
case 'square':
$min_width = $size ? $size . 'px' : '24px';
$min_height = $size ? $size . 'px' : '24px';
$border_radius = '0px';
break;
case 'rounded':
$min_width = $size ? $size . 'px' : '24px';
$min_height = $size ? $size . 'px' : '24px';
$border_radius = '3px';
break;
case 'custom':
$min_width = $width ? $width . 'px' : '24px';
$min_height = $height ? $height . 'px' : '24px';
$border_radius = '0px';
break;
default:
break;
}
$type = $this->helper->get_attr_type_by_name( $term->taxonomy );
switch ( $type ) {
case 'color':
$html = "<div class='cfvsw-swatches-container " . esc_attr( $container_class ) . "'>";
$color = get_term_meta( $term->term_id, 'cfvsw_color', true );
$tooltip = $settings['tooltip'] ? $term->name : '';
$style = '';
$style .= 'min-width:' . $min_width . ';';
$style .= 'min-height:' . $min_height . ';';
$style .= 'border-radius:' . $border_radius . ';';
$style .= 'background-color:' . $color . ';';
$html .= "<div class='cfvsw-swatches-option' data-slug='" . esc_attr( $term->slug ) . "' data-title='" . esc_attr( $term->name ) . "' data-tooltip='" . esc_attr( $tooltip ) . "' style=" . esc_attr( $style ) . '></div>';
$html .= '</div>';
break;
case 'image':
$html = "<div class='cfvsw-swatches-container " . esc_attr( $container_class ) . "'>";
$image = get_term_meta( $term->term_id, 'cfvsw_image', true );
$tooltip = $settings['tooltip'] ? $term->name : '';
$style = '';
$style .= 'min-width:' . $min_width . ';';
$style .= 'min-height:' . $min_height . ';';
$style .= 'border-radius:' . $border_radius . ';';
$style .= "background-image:url('" . $image . "');background-size:cover;";
$html .= "<div class='cfvsw-swatches-option cfvsw-image-option' data-slug='" . esc_attr( $term->slug ) . "' data-title='" . esc_attr( $term->name ) . "' data-tooltip='" . esc_attr( $tooltip ) . "' style=" . esc_attr( $style ) . '>';
$html .= '</div>';
$html .= '</div>';
break;
default:
if ( 'label' !== $type && ! $settings['auto_convert'] ) {
break;
}
$html = "<div class='cfvsw-swatches-container " . esc_attr( $container_class ) . "'>";
$style = '';
$style .= 'min-width:' . $min_width . ';';
$style .= 'min-height:' . $min_height . ';';
$style .= 'border-radius:' . $border_radius . ';';
$name = ! empty( $term->name ) ? $term->name : $term->slug;
$html .= "<div class='cfvsw-swatches-option cfvsw-label-option' data-slug='" . esc_attr( $term->slug ) . "' data-title='" . esc_attr( $name ) . "' style=" . esc_attr( $style ) . '>' . esc_html( $name ) . '</div>';
$html .= '</div>';
break;
}
if ( ! empty( $html ) ) {
return '<a ref="nofollow" style="border-radius:' . esc_attr( $border_radius ) . '" href=' . esc_url( $link ) . '>' . $html . '</a>';
}
return $term_html;
}
/**
* Rewrite woocommerce threshold.
*
* @since 1.0.4
* @return int
*/
public function cfvsw_ajax_variation_threshold() {
return 200;
}
}