init
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/**
|
||||
* Swatches product admin class.
|
||||
*
|
||||
* @package Flatsome\Extensions
|
||||
*/
|
||||
|
||||
namespace Flatsome\Extensions;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Class Swatches_Admin_Product
|
||||
*
|
||||
* @package Flatsome\Extensions
|
||||
*/
|
||||
class Swatches_Admin_Product {
|
||||
|
||||
/**
|
||||
* Swatches_Admin_Product constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action( 'woocommerce_product_option_terms', array( $this, 'product_option_terms' ), 10, 3 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add selector for extra attribute types.
|
||||
* html-product-attribute.php template
|
||||
*
|
||||
* @param object $attribute_taxonomy Taxonomy.
|
||||
* @param string|int $i Index.
|
||||
* @param object $attribute Attribute.
|
||||
*/
|
||||
public function product_option_terms( $attribute_taxonomy, $i, $attribute ) {
|
||||
if ( ! array_key_exists( $attribute_taxonomy->attribute_type, flatsome_swatches()->get_attribute_types() ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
global $thepostid;
|
||||
|
||||
$taxonomy_name = wc_attribute_taxonomy_name( $attribute_taxonomy->attribute_name );
|
||||
$product_id = isset( $_POST['post_id'] ) ? absint( $_POST['post_id'] ) : $thepostid; // phpcs:ignore WordPress.Security.NonceVerification
|
||||
?>
|
||||
|
||||
<select multiple="multiple" data-placeholder="<?php esc_attr_e( 'Select terms', 'woocommerce' ); ?>" class="multiselect attribute_values wc-enhanced-select" name="attribute_values[<?php echo esc_attr( $i ); ?>][]">
|
||||
<?php
|
||||
$args = array(
|
||||
'orderby' => ! empty( $attribute_taxonomy->attribute_orderby ) ? $attribute_taxonomy->attribute_orderby : 'name',
|
||||
'hide_empty' => 0,
|
||||
);
|
||||
$all_terms = get_terms( $taxonomy_name, apply_filters( 'woocommerce_product_attribute_terms', $args ) );
|
||||
if ( $all_terms ) {
|
||||
foreach ( $all_terms as $term ) {
|
||||
echo '<option value="' . esc_attr( $term->term_id ) . '" ' . selected( has_term( absint( $term->term_id ), $taxonomy_name, $product_id ), true, false ) . '>' . esc_html( apply_filters( 'woocommerce_product_attribute_term_name', $term->name, $term ) ) . '</option>';
|
||||
}
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<button class="button plus select_all_attributes"><?php esc_html_e( 'Select all', 'woocommerce' ); ?></button>
|
||||
<button class="button minus select_no_attributes"><?php esc_html_e( 'Select none', 'woocommerce' ); ?></button>
|
||||
<button class="button fr plus add_new_attribute" data-type="<?php echo esc_attr( $attribute_taxonomy->attribute_type ); ?>"><?php esc_html_e( 'Add new', 'woocommerce' ); ?></button>
|
||||
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
new Swatches_Admin_Product();
|
@@ -0,0 +1,391 @@
|
||||
<?php
|
||||
/**
|
||||
* Swatches admin class.
|
||||
*
|
||||
* @package Flatsome\Extensions
|
||||
*/
|
||||
|
||||
namespace Flatsome\Extensions;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Class Swatches_Admin
|
||||
*
|
||||
* @package Flatsome\Extensions
|
||||
*/
|
||||
class Swatches_Admin {
|
||||
|
||||
/**
|
||||
* The single instance of the class
|
||||
*
|
||||
* @var Swatches_Admin
|
||||
*/
|
||||
protected static $instance = null;
|
||||
|
||||
/**
|
||||
* Main instance
|
||||
*
|
||||
* @return Swatches_Admin
|
||||
*/
|
||||
public static function instance() {
|
||||
if ( is_null( self::$instance ) ) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Swatches_Admin constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action( 'admin_init', array( $this, 'includes' ) );
|
||||
add_action( 'admin_init', array( $this, 'init_attribute_hooks' ) );
|
||||
add_action( 'admin_print_scripts', array( $this, 'enqueue_scripts' ) );
|
||||
|
||||
// Add option fields.
|
||||
add_action( 'flatsome_product_attribute_term_fields', array( $this, 'attribute_term_field' ), 10, 3 );
|
||||
add_action( 'woocommerce_after_add_attribute_fields', array( $this, 'attribute_fields' ) );
|
||||
add_action( 'woocommerce_after_edit_attribute_fields', array( $this, 'attribute_fields' ) );
|
||||
|
||||
// Add attribute option fields.
|
||||
add_action( 'woocommerce_attribute_added', array( $this, 'add_attribute_options' ), 10, 2 );
|
||||
add_action( 'woocommerce_attribute_updated', array( $this, 'update_attribute_options' ), 10, 3 );
|
||||
add_action( 'woocommerce_attribute_updated', array( flatsome_swatches(), 'cache_clear' ), 10, 3 );
|
||||
add_action( 'woocommerce_attribute_deleted', array( $this, 'delete_attribute_option' ), 10 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Render attribute fields for add/edit screen.
|
||||
*/
|
||||
public function attribute_fields() {
|
||||
$id = isset( $_GET['edit'] ) ? absint( $_GET['edit'] ) : false; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
$options = $id ? get_option( "flatsome_product_attribute-{$id}" ) : '';
|
||||
$swatch_size = isset( $options['swatch_size'] ) ? $options['swatch_size'] : '';
|
||||
$swatch_shape = isset( $options['swatch_shape'] ) ? $options['swatch_shape'] : '';
|
||||
$variation_images = isset( $options['swatch_variation_images'] ) ? $options['swatch_variation_images'] : '';
|
||||
$table = doing_action( 'woocommerce_after_edit_attribute_fields' ); // Edit screen requires table markup.
|
||||
?>
|
||||
|
||||
<?php echo $table ? '<tr class="form-field"><th scope="row" valign="top">' : '<div class="form-field">'; ?>
|
||||
<label for="attribute_swatch_size"><?php esc_html_e( 'Swatch size', 'flatsome' ); ?></label>
|
||||
<?php if ( $table ) echo '</th><td>'; ?>
|
||||
<select name="attribute_swatch_size" id="attribute_swatch_size">
|
||||
<option value="x-small" <?php selected( $swatch_size, 'x-small' ); ?>><?php esc_html_e( 'X Small', 'flatsome' ); ?></option>
|
||||
<option value="small" <?php selected( $swatch_size, 'small' ); ?>><?php esc_html_e( 'Small', 'flatsome' ); ?></option>
|
||||
<option value="" <?php selected( $swatch_size, '' ); ?>><?php esc_html_e( 'Medium', 'flatsome' ); ?></option>
|
||||
<option value="large" <?php selected( $swatch_size, 'large' ); ?>><?php esc_html_e( 'Large', 'flatsome' ); ?></option>
|
||||
<option value="x-large" <?php selected( $swatch_size, 'x-large' ); ?>><?php esc_html_e( 'X Large', 'flatsome' ); ?></option>
|
||||
</select>
|
||||
<p class="description"><?php esc_html_e( 'Determines the size of the swatches.', 'flatsome' ); ?></p>
|
||||
<?php echo $table ? '</td></tr>' : '</div>'; ?>
|
||||
|
||||
<?php echo $table ? '<tr class="form-field"><th scope="row" valign="top">' : '<div class="form-field">'; ?>
|
||||
<label for="attribute_swatch_shape"><?php esc_html_e( 'Swatch shape', 'flatsome' ); ?></label>
|
||||
<?php if ( $table ) echo '</th><td>'; ?>
|
||||
<select name="attribute_swatch_shape" id="attribute_swatch_shape">
|
||||
<option value=""><?php esc_html_e( 'Square', 'flatsome' ); ?></option>
|
||||
<option value="rounded" <?php selected( $swatch_shape, 'rounded' ); ?>><?php esc_html_e( 'Rounded', 'flatsome' ); ?></option>
|
||||
<option value="circle" <?php selected( $swatch_shape, 'circle' ); ?>><?php esc_html_e( 'Circle', 'flatsome' ); ?></option>
|
||||
</select>
|
||||
<p class="description"><?php esc_html_e( 'Determines the shape of the swatches.', 'flatsome' ); ?></p>
|
||||
<?php echo $table ? '</td></tr>' : '</div>'; ?>
|
||||
|
||||
<?php echo $table ? '<tr class="form-field"><th scope="row" valign="top">' : '<div class="form-field">'; ?>
|
||||
<?php echo $table ? '<label for="attribute_swatch_variation_images">' . esc_html__( 'Use variation images?', 'flatsome' ) . '</label></th><td>' : '<label for="attribute_swatch_variation_images">'; ?>
|
||||
<input name="attribute_swatch_variation_images" id="attribute_swatch_variation_images" type="checkbox" value="1" <?php checked( $variation_images ); ?>><?php if ( ! $table ) echo esc_html__( 'Use variation images?', 'flatsome' ) . '</label>'; ?>
|
||||
<p class="description"><?php esc_html_e( 'Enable this if you want swatches for this attribute to be auto filled with variation images.', 'flatsome' ); ?></p>
|
||||
<?php echo $table ? '</td></tr>' : '</div>'; ?>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Include files we need in product admin.
|
||||
*/
|
||||
public function includes() {
|
||||
include_once dirname( __FILE__ ) . '/class-swatches-admin-product.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Add fields to attribute screen.
|
||||
* Add swatch preview column per attribute term.
|
||||
* Save new term meta.
|
||||
*/
|
||||
public function init_attribute_hooks() {
|
||||
$attribute_taxonomies = wc_get_attribute_taxonomies();
|
||||
|
||||
if ( empty( $attribute_taxonomies ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( $attribute_taxonomies as $tax ) {
|
||||
add_action( 'pa_' . $tax->attribute_name . '_add_form_fields', array( $this, 'add_attribute_term_fields' ) );
|
||||
add_action( 'pa_' . $tax->attribute_name . '_edit_form_fields', array( $this, 'edit_attribute_term_fields' ), 10, 2 );
|
||||
|
||||
add_filter( 'manage_edit-pa_' . $tax->attribute_name . '_columns', array( $this, 'add_attribute_columns' ) );
|
||||
add_filter( 'manage_pa_' . $tax->attribute_name . '_custom_column', array( $this, 'add_attribute_column_content' ), 10, 3 );
|
||||
}
|
||||
|
||||
add_action( 'created_term', array( $this, 'save_term_meta' ), 10, 3 );
|
||||
add_action( 'edit_term', array( $this, 'save_term_meta' ), 10, 3 );
|
||||
add_action( 'edit_term', array( flatsome_swatches(), 'cache_clear' ), 10, 3 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Load scripts in edit product attribute screen.
|
||||
*/
|
||||
public function enqueue_scripts() {
|
||||
$screen = get_current_screen();
|
||||
if ( $screen && strpos( $screen->id, 'edit-pa_' ) === false && strpos( $screen->id, 'product' ) === false ) {
|
||||
return;
|
||||
}
|
||||
|
||||
wp_enqueue_media();
|
||||
|
||||
wp_enqueue_style( 'flatsome-swatches-admin', get_template_directory_uri() . '/assets/css/extensions/flatsome-swatches-admin.css', array( 'wp-color-picker' ), flatsome_swatches()->version );
|
||||
wp_enqueue_script( 'flatsome-swatches-admin', get_template_directory_uri() . '/assets/js/extensions/flatsome-swatches-admin.js', array(
|
||||
'jquery',
|
||||
'wp-color-picker',
|
||||
'wp-util',
|
||||
), flatsome_swatches()->version, true );
|
||||
|
||||
wp_localize_script(
|
||||
'flatsome-swatches-admin',
|
||||
'flatsome_swatches',
|
||||
array(
|
||||
'placeholder' => WC()->plugin_url() . '/assets/images/placeholder.png',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create hook to add fields to add attribute term screen.
|
||||
*
|
||||
* @param string $taxonomy Taxonomy.
|
||||
*/
|
||||
public function add_attribute_term_fields( $taxonomy ) {
|
||||
$attr = flatsome_swatches()->get_attribute( $taxonomy );
|
||||
|
||||
do_action( 'flatsome_product_attribute_term_fields', $attr->attribute_type, '', 'add' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Create hook to fields to edit attribute term screen.
|
||||
*
|
||||
* @param object $term Term.
|
||||
* @param string $taxonomy Taxonomy.
|
||||
*/
|
||||
public function edit_attribute_term_fields( $term, $taxonomy ) {
|
||||
$attr = flatsome_swatches()->get_attribute( $taxonomy );
|
||||
$value = get_term_meta( $term->term_id, $attr->attribute_type, true );
|
||||
|
||||
do_action( 'flatsome_product_attribute_term_fields', $attr->attribute_type, $value, 'edit' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Print HTML of custom field on attribute term add/edit screens.
|
||||
*
|
||||
* @param string $type Attribute type.
|
||||
* @param string $value Field value.
|
||||
* @param string $form The form kind.
|
||||
*/
|
||||
public function attribute_term_field( $type, $value, $form ) {
|
||||
// Return if this is a default attribute type.
|
||||
if ( in_array( $type, array( 'select', 'text' ), true ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$name = $type;
|
||||
|
||||
// phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
printf( '<%s class="form-field term-%s-wrap">%s<label for="term-%s">%s</label>%s',
|
||||
'edit' == $form ? 'tr' : 'div',
|
||||
esc_attr( $type ),
|
||||
'edit' == $form ? '<th>' : '',
|
||||
esc_attr( $type ),
|
||||
esc_html( flatsome_swatches()->get_attribute_types()[ $type ] ),
|
||||
'edit' == $form ? '</th><td>' : ''
|
||||
);
|
||||
// phpcs:enable WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
|
||||
switch ( $type ) {
|
||||
case 'ux_image':
|
||||
$image = $value ? wp_get_attachment_image_src( $value ) : '';
|
||||
$image = $image ? $image[0] : WC()->plugin_url() . '/assets/images/placeholder.png';
|
||||
?>
|
||||
<div class="ux-swatches-term-image-thumbnail" style="margin: 8px 0;">
|
||||
<img src="<?php echo esc_url( $image ); ?>" width="60px" height="60px" alt=""/>
|
||||
</div>
|
||||
<div style="line-height:35px;">
|
||||
<input type="hidden" class="ux-swatches-term-image" name="<?php echo esc_attr( $name ); ?>" value="<?php echo esc_attr( $value ); ?>" />
|
||||
<button type="button" class="ux-swatches-upload-image-button button"><?php esc_html_e( 'Select image', 'flatsome' ); ?></button>
|
||||
<button type="button" class="ux-swatches-remove-image-button button <?php echo $value ? '' : 'hidden'; ?>"><?php esc_html_e( 'Remove', 'flatsome' ); ?></button>
|
||||
</div>
|
||||
<p>The swatch image.</p>
|
||||
<?php
|
||||
break;
|
||||
case 'ux_color':
|
||||
$color = flatsome_swatches()->parse_ux_color_term_meta( $value );
|
||||
$value = $color['color'];
|
||||
$value_2 = '';
|
||||
$name .= '[]';
|
||||
|
||||
if ( $color['color_2'] ) $value_2 = $color['color_2'];
|
||||
?>
|
||||
<input type="text" id="term-<?php echo esc_attr( $type ); ?>" class="ux-color-field" name="<?php echo esc_attr( $name ); ?>" value="<?php echo esc_attr( $value ); ?>" />
|
||||
<span class="ux-swatches-add-color button" data-content="<?php echo $value_2 ? '+' : '-'; ?>"><?php echo $value_2 ? '-' : '+'; ?></span><br>
|
||||
<input type="text" id="term-<?php echo esc_attr( $type ); ?>_2" class="ux-swatches-bicolor-picker ux-color-field" name="<?php echo esc_attr( $name ); ?>" value="<?php echo esc_attr( $value_2 ); ?>"/>
|
||||
<p>The swatch color.</p>
|
||||
<?php
|
||||
break;
|
||||
case 'ux_label':
|
||||
?>
|
||||
<input type="text" id="term-<?php echo esc_attr( $type ); ?>" name="<?php echo esc_attr( $name ); ?>" value="<?php echo esc_attr( $value ); ?>" />
|
||||
<p>The swatch text.</p>
|
||||
<?php
|
||||
break;
|
||||
}
|
||||
|
||||
echo 'edit' == $form ? '</td></tr>' : '</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Save term meta.
|
||||
*
|
||||
* @param int $term_id Term ID.
|
||||
* @param int $tt_id Term taxonomy ID.
|
||||
* @param string $taxonomy Taxonomy slug.
|
||||
*/
|
||||
public function save_term_meta( $term_id, $tt_id, $taxonomy ) {
|
||||
foreach ( flatsome_swatches()->get_attribute_types() as $type => $label ) {
|
||||
if ( isset( $_POST[ $type ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$value = wp_unslash( $_POST[ $type ] ); // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
if ( is_array( $value ) ) {
|
||||
$array_values = array_filter( $value );
|
||||
if ( empty( $array_values ) ) {
|
||||
$value = '';
|
||||
} else {
|
||||
$value = implode( ',', $array_values );
|
||||
}
|
||||
}
|
||||
|
||||
update_term_meta( $term_id, $type, sanitize_text_field( $value ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attribute added.
|
||||
*
|
||||
* @param int $id Added attribute ID.
|
||||
* @param array $data Attribute data.
|
||||
*/
|
||||
public function add_attribute_options( $id, $data ) {
|
||||
// phpcs:disable WordPress.Security.NonceVerification
|
||||
$values = array(
|
||||
'swatch_size' => isset( $_POST['attribute_swatch_size'] ) ? sanitize_text_field( wp_unslash( $_POST['attribute_swatch_size'] ) ) : '',
|
||||
'swatch_shape' => isset( $_POST['attribute_swatch_shape'] ) ? sanitize_text_field( wp_unslash( $_POST['attribute_swatch_shape'] ) ) : '',
|
||||
'swatch_variation_images' => isset( $_POST['attribute_swatch_variation_images'] ) ? isset( $_POST['attribute_swatch_variation_images'] ) : '',
|
||||
);
|
||||
// phpcs:enable WordPress.Security.NonceVerification
|
||||
|
||||
add_option( "flatsome_product_attribute-{$id}", $values );
|
||||
}
|
||||
|
||||
/**
|
||||
* Attribute updated.
|
||||
*
|
||||
* @param int $id Added attribute ID.
|
||||
* @param array $data Attribute data.
|
||||
* @param string $old_slug Attribute old name.
|
||||
*/
|
||||
public function update_attribute_options( $id, $data, $old_slug ) {
|
||||
// phpcs:disable WordPress.Security.NonceVerification
|
||||
$values = array(
|
||||
'swatch_size' => isset( $_POST['attribute_swatch_size'] ) ? sanitize_text_field( wp_unslash( $_POST['attribute_swatch_size'] ) ) : '',
|
||||
'swatch_shape' => isset( $_POST['attribute_swatch_shape'] ) ? sanitize_text_field( wp_unslash( $_POST['attribute_swatch_shape'] ) ) : '',
|
||||
'swatch_variation_images' => isset( $_POST['attribute_swatch_variation_images'] ) ? isset( $_POST['attribute_swatch_variation_images'] ) : '',
|
||||
);
|
||||
// phpcs:enable WordPress.Security.NonceVerification
|
||||
|
||||
update_option( "flatsome_product_attribute-{$id}", $values );
|
||||
}
|
||||
|
||||
/**
|
||||
* Attribute deleted.
|
||||
*
|
||||
* @param int $id Added attribute ID.
|
||||
*/
|
||||
public function delete_attribute_option( $id ) {
|
||||
delete_option( "flatsome_product_attribute-{$id}" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add thumbnail column to column list
|
||||
*
|
||||
* @param array $columns Columns.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function add_attribute_columns( $columns ) {
|
||||
if ( empty( $columns ) ) {
|
||||
return $columns;
|
||||
}
|
||||
|
||||
$new_columns = array();
|
||||
$new_columns['cb'] = $columns['cb'];
|
||||
$new_columns['ux_swatch_preview'] = __( 'Value', 'flatsome' );
|
||||
|
||||
unset( $columns['cb'] );
|
||||
|
||||
return array_merge( $new_columns, $columns );
|
||||
}
|
||||
|
||||
/**
|
||||
* Render thumbnail HTML depend on attribute type
|
||||
*
|
||||
* @param string $content Current content.
|
||||
* @param string $column Column name.
|
||||
* @param string|int $term_id Term ID.
|
||||
*/
|
||||
public function add_attribute_column_content( $content, $column, $term_id ) {
|
||||
if ( 'ux_swatch_preview' === $column ) {
|
||||
$classes = array( 'ux-swatch-preview' );
|
||||
$attr = flatsome_swatches()->get_attribute( $_REQUEST['taxonomy'] ); // phpcs:ignore
|
||||
$value = get_term_meta( $term_id, $attr->attribute_type, true );
|
||||
|
||||
switch ( $attr->attribute_type ) {
|
||||
case 'ux_color':
|
||||
$color_classes = array( 'ux-swatch__color' );
|
||||
$color = flatsome_swatches()->parse_ux_color_term_meta( $value );
|
||||
$classes[] = 'ux-swatch--color';
|
||||
$color_classes[] = $color['class'];
|
||||
printf( '<div class="%s"><span class="%s" style="%s"></span></div>',
|
||||
esc_attr( implode( ' ', $classes ) ),
|
||||
esc_attr( implode( ' ', $color_classes ) ),
|
||||
$color['style'] // phpcs:ignore WordPress.Security.EscapeOutput
|
||||
);
|
||||
break;
|
||||
|
||||
case 'ux_image':
|
||||
$image = $value ? wp_get_attachment_image_src( $value ) : '';
|
||||
$image = $image ? $image[0] : WC()->plugin_url() . '/assets/images/placeholder.png';
|
||||
$classes[] = 'ux-swatch--image';
|
||||
printf( '<div class="%s"><img class="ux-swatch__img" src="%s" width="30px" height="30px" alt=""></div>',
|
||||
esc_attr( implode( ' ', $classes ) ),
|
||||
esc_url( $image )
|
||||
);
|
||||
break;
|
||||
|
||||
case 'ux_label':
|
||||
$classes[] = 'ux-swatch--label';
|
||||
printf( '<div class="%s"><span class="ux-swatch__text">%s</span></div>',
|
||||
esc_attr( implode( ' ', $classes ) ),
|
||||
esc_html( $value )
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,762 @@
|
||||
<?php
|
||||
/**
|
||||
* Swatches frontend class.
|
||||
*
|
||||
* @package Flatsome\Extensions
|
||||
*/
|
||||
|
||||
namespace Flatsome\Extensions;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Class Swatches_Frontend
|
||||
*
|
||||
* @package Flatsome\Extensions
|
||||
*/
|
||||
class Swatches_Frontend {
|
||||
|
||||
/**
|
||||
* The single instance of the class
|
||||
*
|
||||
* @var Swatches_Frontend
|
||||
*/
|
||||
protected static $instance = null;
|
||||
|
||||
/**
|
||||
* Main instance
|
||||
*
|
||||
* @return Swatches_Frontend
|
||||
*/
|
||||
public static function instance() {
|
||||
if ( is_null( self::$instance ) ) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Swatches_Frontend constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
|
||||
|
||||
add_action( 'wp_head', array( $this, 'add_css' ), 110 );
|
||||
|
||||
add_filter( 'woocommerce_dropdown_variation_attribute_options_html', array( $this, 'get_swatch_html' ), 100, 2 );
|
||||
add_filter( 'flatsome_swatch_html', array( $this, 'swatch_html' ), 5, 4 );
|
||||
|
||||
// Add swatches in loop.
|
||||
add_action( 'woocommerce_before_shop_loop_item_title', array( $this, 'box_swatch_list' ) );
|
||||
|
||||
// Layered nav.
|
||||
add_filter( 'woocommerce_layered_nav_term_html', array( $this, 'layered_nav_term_html' ), 10, 4 );
|
||||
|
||||
// Handle cache.
|
||||
add_action( 'save_post', array( $this, 'cache_clear_save_post' ) );
|
||||
add_action( 'woocommerce_before_product_object_save', array( $this, 'cache_clear_product_object_save' ) );
|
||||
add_filter( 'pre_set_theme_mod_swatches', array( $this, 'cache_clear_all' ), 10, 2 );
|
||||
add_filter( 'pre_set_theme_mod_swatches_box_attribute', array( $this, 'cache_clear_all' ), 10, 2 );
|
||||
add_filter( 'pre_update_option_woocommerce_thumbnail_image_width', array( $this, 'cache_clear_all' ), 10, 2 );
|
||||
add_filter( 'pre_update_option_woocommerce_thumbnail_cropping', array( $this, 'cache_clear_all' ), 10, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue scripts and stylesheets
|
||||
*/
|
||||
public function enqueue_scripts() {
|
||||
wp_enqueue_style( 'flatsome-swatches-frontend', get_template_directory_uri() . '/assets/css/extensions/flatsome-swatches-frontend.css', array(), flatsome_swatches()->version );
|
||||
wp_style_add_data( 'flatsome-swatches-frontend', 'rtl', 'replace' );
|
||||
|
||||
wp_enqueue_script( 'flatsome-swatches-frontend', get_template_directory_uri() . '/assets/js/extensions/flatsome-swatches-frontend.js', array(
|
||||
'jquery',
|
||||
'flatsome-js',
|
||||
), flatsome_swatches()->version, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add extension CSS.
|
||||
*/
|
||||
public function add_css() {
|
||||
ob_start();
|
||||
?>
|
||||
<?php if ( get_theme_mod( 'swatches_layout' ) === 'stacked' ) : ?>
|
||||
.variations th,
|
||||
.variations td {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.variations .label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.variations .label label {
|
||||
margin: .5em 0;
|
||||
}
|
||||
|
||||
.ux-swatch-selected-value {
|
||||
font-weight: normal;
|
||||
font-size: .9em;
|
||||
}
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( get_theme_mod( 'swatches_color_selected', \Flatsome_Default::COLOR_SECONDARY ) !== \Flatsome_Default::COLOR_SECONDARY ) : ?>
|
||||
.variations_form .ux-swatch.selected {
|
||||
box-shadow: 0 0 0 0.1rem <?php echo get_theme_mod( 'swatches_color_selected' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>;
|
||||
}
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( get_theme_mod( 'swatches_box_color_selected', \Flatsome_Default::COLOR_SECONDARY ) !== \Flatsome_Default::COLOR_SECONDARY ) : ?>
|
||||
.ux-swatches-in-loop .ux-swatch.selected {
|
||||
box-shadow: 0 0 0 0.1rem <?php echo get_theme_mod( 'swatches_box_color_selected' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>;
|
||||
}
|
||||
<?php endif; ?>
|
||||
|
||||
<?php
|
||||
$output = ob_get_clean();
|
||||
|
||||
if ( ! $output ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$css = '<style id="flatsome-swatches-css" type="text/css">';
|
||||
$css .= $output;
|
||||
$css .= '</style>';
|
||||
|
||||
echo flatsome_minify_css( $css ); // phpcs:ignore WordPress.Security.EscapeOutput
|
||||
}
|
||||
|
||||
/**
|
||||
* The swatches HTML for an attribute.
|
||||
*
|
||||
* @param string $html The dropdown variation attribute options html.
|
||||
* @param array $args Args.
|
||||
*
|
||||
* @return string
|
||||
* @uses swatch_html()
|
||||
*/
|
||||
public function get_swatch_html( $html, $args ) {
|
||||
$swatch_types = flatsome_swatches()->get_attribute_types();
|
||||
$attr = flatsome_swatches()->get_attribute( $args['attribute'] );
|
||||
|
||||
// Abort if this is normal attribute.
|
||||
if ( empty( $attr ) || ! array_key_exists( $attr->attribute_type, $swatch_types ) ) {
|
||||
return $html;
|
||||
}
|
||||
|
||||
$swatches = '';
|
||||
$options = $args['options'];
|
||||
$product = $args['product'];
|
||||
$attribute = $args['attribute'];
|
||||
$classes = array( 'ux-swatches', "ux-swatches-attribute-{$attr->attribute_type}" );
|
||||
$selector_classes = array( 'variation-selector', "variation-select-{$attr->attribute_type}" );
|
||||
$args['tooltip'] = get_theme_mod( 'swatches_tooltip', 1 );
|
||||
|
||||
$attr_options = flatsome_swatches()->get_attribute_option_by_name( $args['attribute'] );
|
||||
$available_variations = $product->get_available_variations();
|
||||
$args['swatches'] = $this->get_swatches( $attribute, $options, $available_variations, $this->use_variation_images( $attr_options ) );
|
||||
$args['swatches']['use_variation_image'] = $this->use_variation_images( $attr_options );
|
||||
|
||||
if ( isset( $attr_options['swatch_size'] ) && ! empty( $attr_options['swatch_size'] ) ) {
|
||||
$classes[] = 'ux-swatches--' . $attr_options['swatch_size'];
|
||||
}
|
||||
|
||||
if ( isset( $attr_options['swatch_shape'] ) && ! empty( $attr_options['swatch_shape'] ) ) {
|
||||
$classes[] = 'ux-swatches--' . $attr_options['swatch_shape'];
|
||||
}
|
||||
|
||||
if ( empty( $options ) && ! empty( $product ) && ! empty( $attribute ) ) {
|
||||
$attributes = $product->get_variation_attributes();
|
||||
$options = $attributes[ $attribute ];
|
||||
}
|
||||
|
||||
if ( array_key_exists( $attr->attribute_type, $swatch_types ) ) {
|
||||
if ( ! empty( $options ) && $product && taxonomy_exists( $attribute ) ) {
|
||||
$terms = wc_get_product_terms( $product->get_id(), $attribute, array( 'fields' => 'all' ) );
|
||||
|
||||
foreach ( $terms as $term ) {
|
||||
if ( ! in_array( $term->slug, $options, true ) ) {
|
||||
continue;
|
||||
}
|
||||
$swatches .= apply_filters( 'flatsome_swatch_html', '', $term, $attr->attribute_type, $args );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $swatches ) ) {
|
||||
$selector_classes[] = 'hidden';
|
||||
$swatches = '<div class="' . esc_attr( implode( ' ', $classes ) ) . '" data-attribute_name="attribute_' . esc_attr( $attribute ) . '">' . $swatches . '</div>';
|
||||
$html = '<div class="' . esc_attr( implode( ' ', $selector_classes ) ) . '">' . $html . '</div>' . $swatches;
|
||||
}
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Single swatch HTML.
|
||||
*
|
||||
* @param string $html HTML.
|
||||
* @param \WP_Term $term WP Term object.
|
||||
* @param string $type Attribute type.
|
||||
* @param array $args Args.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function swatch_html( $html, $term, $type, $args ) {
|
||||
$selected = sanitize_title( $args['selected'] ) == $term->slug ? 'selected' : '';
|
||||
$name = esc_html( apply_filters( 'woocommerce_variation_option_name', $term->name ) );
|
||||
$img_size = apply_filters( 'flatsome_swatch_image_size', 'woocommerce_gallery_thumbnail', $term );
|
||||
$classes = array( 'ux-swatch' );
|
||||
$thumb = '';
|
||||
$tooltip = '';
|
||||
|
||||
if ( ! empty( $args['tooltip'] ) ) {
|
||||
$classes[] = 'tooltip';
|
||||
$tooltip = $term->description ? $term->description : $name;
|
||||
}
|
||||
|
||||
// Gather variation image if one is available.
|
||||
if ( $args['swatches']['use_variation_image'] ) {
|
||||
$options_flipped = array_flip( $args['options'] );
|
||||
$key = $options_flipped[ $term->slug ];
|
||||
if ( isset( $args['swatches'][ $key ]['variation_id'] ) && $args['swatches'][ $key ]['variation_id'] ) {
|
||||
$thumb_id = get_post_thumbnail_id( $args['swatches'][ $key ]['variation_id'] );
|
||||
|
||||
if ( $thumb_id ) {
|
||||
$thumb = wp_get_attachment_image( $thumb_id, $img_size, false, array(
|
||||
'class' => "ux-swatch__img attachment-$img_size size-$img_size",
|
||||
'alt' => $name,
|
||||
) );
|
||||
$type = 'variation-image';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch ( $type ) {
|
||||
case 'ux_color':
|
||||
$color_classes = array( 'ux-swatch__color' );
|
||||
$value = get_term_meta( $term->term_id, 'ux_color', true );
|
||||
$color = flatsome_swatches()->parse_ux_color_term_meta( $value );
|
||||
|
||||
if ( $color['class'] ) $color_classes[] = $color['class'];
|
||||
|
||||
$html = sprintf( '<div class="%s ux-swatch--color swatch-%s %s" data-value="%s" data-name="%s" title="%s"><span class="%s" style="%s"></span><span class="ux-swatch__text">%s</span></div>',
|
||||
implode( ' ', $classes ),
|
||||
esc_attr( $term->slug ),
|
||||
$selected,
|
||||
esc_attr( $term->slug ),
|
||||
$name,
|
||||
esc_attr( $tooltip ),
|
||||
implode( ' ', $color_classes ),
|
||||
$color['style'],
|
||||
$name
|
||||
);
|
||||
break;
|
||||
|
||||
case 'ux_image':
|
||||
$image_id = get_term_meta( $term->term_id, 'ux_image', true );
|
||||
$image = '';
|
||||
if ( $image_id ) {
|
||||
$image = wp_get_attachment_image( $image_id, $img_size, false, array(
|
||||
'class' => "ux-swatch__img attachment-$img_size size-$img_size",
|
||||
'alt' => $name,
|
||||
) );
|
||||
}
|
||||
|
||||
$html = sprintf( '<div class="%s ux-swatch--image %s" data-value="%s" data-name="%s" title="%s">%s<span class="ux-swatch__text">%s</span></div>',
|
||||
implode( ' ', $classes ),
|
||||
$selected,
|
||||
esc_attr( $term->slug ),
|
||||
$name,
|
||||
esc_attr( $tooltip ),
|
||||
$image ? $image : wc_placeholder_img( $img_size ),
|
||||
$name
|
||||
);
|
||||
break;
|
||||
|
||||
case 'variation-image':
|
||||
$html = sprintf(
|
||||
'<div class="%s ux-swatch--image %s" data-value="%s" data-name="%s" title="%s">%s<span class="ux-swatch__text">%s</span></div>',
|
||||
implode( ' ', $classes ),
|
||||
$selected,
|
||||
esc_attr( $term->slug ),
|
||||
$name,
|
||||
esc_attr( $tooltip ),
|
||||
$thumb ? $thumb : wc_placeholder_img( $img_size ),
|
||||
$name
|
||||
);
|
||||
break;
|
||||
|
||||
case 'ux_label':
|
||||
$label = get_term_meta( $term->term_id, 'ux_label', true );
|
||||
$label = $label ? $label : $name;
|
||||
$html = sprintf(
|
||||
'<div class="%s ux-swatch--label %s" data-value="%s" data-name="%s" title="%s"><span class="ux-swatch__text">%s</span></div>',
|
||||
implode( ' ', $classes ),
|
||||
$selected,
|
||||
esc_attr( $term->slug ),
|
||||
$name,
|
||||
esc_attr( $tooltip ),
|
||||
esc_html( $label )
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of types and values for each attribute.
|
||||
*
|
||||
* @param array $attributes Attributes.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_variation_attributes_types( $attributes ) {
|
||||
global $wc_product_attributes;
|
||||
$types = array();
|
||||
$defined_attr = flatsome_swatches()->get_attribute_types();
|
||||
|
||||
if ( ! empty( $attributes ) ) {
|
||||
foreach ( $attributes as $name => $options ) {
|
||||
$current = isset( $wc_product_attributes[ $name ] ) ? $wc_product_attributes[ $name ] : false;
|
||||
|
||||
if ( $current && array_key_exists( $current->attribute_type, $defined_attr ) ) {
|
||||
$types[ $name ] = $current->attribute_type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a list of swatches on product boxes.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function box_swatch_list() {
|
||||
global $product;
|
||||
|
||||
$attribute = apply_filters( 'flatsome_swatches_box_attribute', $this->get_swatches_box_attribute(), $product );
|
||||
|
||||
if ( ! $attribute ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$attribute_name = $attribute->slug;
|
||||
|
||||
if ( ! $attribute_name || empty( $attribute_name ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$id = $product->get_id();
|
||||
|
||||
if ( empty( $id ) || ! $product->is_type( 'variable' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$attr_options = flatsome_swatches()->get_attribute_option_by_name( $attribute_name );
|
||||
$cache_enabled = apply_filters( 'flatsome_swatches_cache_enabled', true );
|
||||
$transient = 'flatsome_swatches_cache_' . $id;
|
||||
$classes = array( 'ux-swatches', 'ux-swatches-in-loop' );
|
||||
|
||||
if ( $cache_enabled ) {
|
||||
$available_variations = get_transient( $transient );
|
||||
} else {
|
||||
$available_variations = array();
|
||||
}
|
||||
|
||||
if ( ! $available_variations ) {
|
||||
/** @var $product \WC_Product_Variable */ // phpcs:ignore Generic.Commenting.DocComment.MissingShort
|
||||
$available_variations = $product->get_available_variations();
|
||||
if ( $cache_enabled ) {
|
||||
set_transient( $transient, $available_variations, apply_filters( 'flatsome_swatches_cache_time', WEEK_IN_SECONDS ) );
|
||||
}
|
||||
}
|
||||
|
||||
if ( empty( $available_variations ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$swatches_to_show = $this->get_option_variations( $attribute_name, $available_variations );
|
||||
|
||||
if ( empty( $swatches_to_show ) ) {
|
||||
return;
|
||||
}
|
||||
$html = '';
|
||||
|
||||
if ( get_theme_mod( 'swatches_box_shape' ) ) {
|
||||
$classes[] = 'ux-swatches--' . get_theme_mod( 'swatches_box_shape' );
|
||||
}
|
||||
if ( get_theme_mod( 'swatches_box_size' ) ) $classes[] = 'ux-swatches--' . get_theme_mod( 'swatches_box_size' );
|
||||
|
||||
// Start ux-swatches.
|
||||
$html .= '<div class="' . implode( ' ', $classes ) . '">';
|
||||
|
||||
// Order.
|
||||
$terms = wc_get_product_terms( $product->get_id(), $attribute_name, array( 'fields' => 'slugs' ) );
|
||||
$swatches_to_show_tmp = $swatches_to_show;
|
||||
$swatches_to_show = array();
|
||||
foreach ( $terms as $id => $slug ) {
|
||||
if ( ! isset( $swatches_to_show_tmp[ $slug ] ) ) {
|
||||
continue;
|
||||
}
|
||||
$swatches_to_show[ $slug ] = $swatches_to_show_tmp[ $slug ];
|
||||
}
|
||||
|
||||
$index = 0;
|
||||
|
||||
$swatch_count = count( $swatches_to_show );
|
||||
$swatch_limit = (int) get_theme_mod( 'swatches_box_limit', 5 );
|
||||
$swatch_layout = get_theme_mod( 'swatches_box_layout' );
|
||||
|
||||
foreach ( $swatches_to_show as $key => $swatch ) {
|
||||
$swatch_classes = array( 'ux-swatch' );
|
||||
$color_classes = array( 'ux-swatch__color' );
|
||||
$term = get_term_by( 'slug', $key, $attribute_name );
|
||||
$name = esc_html( apply_filters( 'woocommerce_variation_option_name', $term->name ) );
|
||||
$img_size = apply_filters( 'flatsome_swatch_image_size', 'woocommerce_gallery_thumbnail', $term );
|
||||
$data = array();
|
||||
$type_tmp = $attribute->type;
|
||||
$swatch_inner_html = '';
|
||||
|
||||
if ( $this->use_variation_images( $attr_options ) && isset( $swatch['image_src'] ) ) {
|
||||
$thumb_id = get_post_thumbnail_id( $swatch['variation_id'] );
|
||||
|
||||
if ( $thumb_id ) {
|
||||
$type_tmp = 'variation-image';
|
||||
$swatch_classes[] = 'ux-swatch--image';
|
||||
$swatch_inner_html = wp_get_attachment_image( $thumb_id, $img_size, false, array(
|
||||
'class' => "ux-swatch__img attachment-$img_size size-$img_size",
|
||||
'alt' => $name,
|
||||
) );
|
||||
}
|
||||
}
|
||||
|
||||
switch ( $type_tmp ) {
|
||||
case 'ux_color':
|
||||
$color = flatsome_swatches()->parse_ux_color_term_meta( $swatch['ux_color'] );
|
||||
|
||||
if ( $color['class'] ) $color_classes[] = $color['class'];
|
||||
|
||||
$swatch_classes[] = 'ux-swatch--color';
|
||||
$swatch_inner_html = '<span class="' . implode( ' ', $color_classes ) . '" style="' . $color['style'] . '"></span>';
|
||||
break;
|
||||
case 'ux_image':
|
||||
$swatch_classes[] = 'ux-swatch--image';
|
||||
$swatch_inner_html = wp_get_attachment_image( $swatch['ux_image'], $img_size, false, array(
|
||||
'class' => "ux-swatch__img attachment-$img_size size-$img_size",
|
||||
'alt' => $name,
|
||||
) );
|
||||
break;
|
||||
case 'ux_label':
|
||||
$swatch_classes[] = 'ux-swatch--label';
|
||||
break;
|
||||
}
|
||||
|
||||
if ( isset( $swatch['image_src'] ) ) {
|
||||
$data['data-image-src'] = $swatch['image_src'];
|
||||
$data['data-image-srcset'] = $swatch['image_srcset'];
|
||||
$data['data-image-sizes'] = $swatch['image_sizes'];
|
||||
|
||||
if ( ! $swatch['is_in_stock'] ) {
|
||||
$swatch_classes[] = 'out-of-stock';
|
||||
}
|
||||
}
|
||||
|
||||
$data['data-attribute_name'] = 'attribute_' . $attribute_name;
|
||||
$data['data-value'] = $term->slug;
|
||||
|
||||
if ( $swatch_layout === 'limit' && $swatch_count > $swatch_limit ) {
|
||||
if ( $index >= $swatch_limit ) {
|
||||
$swatch_classes[] = 'hidden';
|
||||
}
|
||||
if ( $index === $swatch_limit ) {
|
||||
$html .= '<span class="ux-swatches__limiter">+' . ( $swatch_count - $swatch_limit ) . '</span>';
|
||||
}
|
||||
}
|
||||
|
||||
$html .= '<div class="' . esc_attr( implode( ' ', $swatch_classes ) ) . '" ' . flatsome_html_atts( $data ) . '>' . $swatch_inner_html . '<span class="ux-swatch__text">' . $name . '</span></div>';
|
||||
|
||||
$index ++;
|
||||
}
|
||||
|
||||
$html .= '</div>';
|
||||
|
||||
echo $html; // phpcs:ignore WordPress.Security.EscapeOutput
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribute to show in loops by user preference.
|
||||
*
|
||||
* @return \stdClass|null The attribute object.
|
||||
*/
|
||||
private function get_swatches_box_attribute() {
|
||||
if ( ! get_theme_mod( 'swatches_box_attribute' ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$attr = wc_get_attribute( get_theme_mod( 'swatches_box_attribute' ) );
|
||||
if ( $attr ) {
|
||||
return $attr;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get custom variation option data.
|
||||
*
|
||||
* @param string $attribute_name Attribute name.
|
||||
* @param array $available_variations The available variation.
|
||||
* @param mixed $option Whether or not to get only one variation by attribute option value.
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
private function get_option_variations( $attribute_name, $available_variations, $option = false ) {
|
||||
$swatches_to_show = array();
|
||||
|
||||
foreach ( $available_variations as $key => $variation ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
|
||||
$option_variation = array();
|
||||
$attr_key = 'attribute_' . $attribute_name;
|
||||
if ( ! isset( $variation['attributes'][ $attr_key ] ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$val = $variation['attributes'][ $attr_key ];
|
||||
|
||||
if ( ! empty( $variation['image']['src'] ) ) {
|
||||
$option_variation = array(
|
||||
'variation_id' => $variation['variation_id'],
|
||||
'is_in_stock' => $variation['is_in_stock'],
|
||||
'image_src' => $variation['image']['thumb_src'],
|
||||
'image_srcset' => wp_get_attachment_image_srcset( $variation['image_id'], 'woocommerce_thumbnail' ),
|
||||
'image_sizes' => wp_get_attachment_image_sizes( $variation['image_id'], 'woocommerce_thumbnail' ),
|
||||
);
|
||||
}
|
||||
|
||||
// Get only one variation by attribute option value.
|
||||
if ( $option ) {
|
||||
if ( $val != $option ) {
|
||||
continue;
|
||||
} else {
|
||||
return $option_variation;
|
||||
}
|
||||
} else {
|
||||
// Or get all variations with swatches to show by attribute name.
|
||||
$swatch = $this->get_swatch( $attribute_name, $val );
|
||||
|
||||
// If key already exist don't replace existing with sequential match.
|
||||
if ( ! array_key_exists( $val, $swatches_to_show ) ) {
|
||||
$swatches_to_show[ $val ] = array_merge( $swatch, $option_variation );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $swatches_to_show;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get single swatch values.
|
||||
*
|
||||
* @param string $attr_name Attribute name.
|
||||
* @param string|int $value Search for this term value.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_swatch( $attr_name, $value ) {
|
||||
$swatches = array();
|
||||
$color = '';
|
||||
$image = '';
|
||||
$label = '';
|
||||
|
||||
$term = get_term_by( 'slug', $value, $attr_name );
|
||||
if ( is_object( $term ) ) {
|
||||
$color = get_term_meta( $term->term_id, 'ux_color', true );
|
||||
$image = get_term_meta( $term->term_id, 'ux_image', true );
|
||||
$label = get_term_meta( $term->term_id, 'ux_label', true );
|
||||
}
|
||||
|
||||
if ( $color != '' ) {
|
||||
$swatches['ux_color'] = $color;
|
||||
}
|
||||
|
||||
if ( $image != '' ) {
|
||||
$swatches['ux_image'] = $image;
|
||||
}
|
||||
|
||||
if ( $label != '' ) {
|
||||
$swatches['ux_label'] = $label;
|
||||
}
|
||||
|
||||
return $swatches;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get swatches.
|
||||
*
|
||||
* @param string $attr_name Attribute name.
|
||||
* @param array $options Attribute options.
|
||||
* @param array $available_variations Available variations.
|
||||
* @param bool $use_variation_images Whether or not to search and collect the variation image. Default false.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_swatches( $attr_name, $options, $available_variations, $use_variation_images = false ) {
|
||||
$swatches = array();
|
||||
|
||||
foreach ( $options as $key => $value ) {
|
||||
$swatch = $this->get_swatch( $attr_name, $value );
|
||||
|
||||
if ( ! empty( $swatch ) ) {
|
||||
if ( $available_variations && $use_variation_images ) {
|
||||
$variation = $this->get_option_variations( $attr_name, $available_variations, $value );
|
||||
if ( $variation ) {
|
||||
$swatch = array_merge( $swatch, $variation );
|
||||
}
|
||||
}
|
||||
$swatches[ $key ] = $swatch;
|
||||
}
|
||||
|
||||
if ( empty( $swatch ) && $available_variations && $use_variation_images ) {
|
||||
$variation = $this->get_option_variations( $attr_name, $available_variations, $value );
|
||||
if ( $variation ) {
|
||||
$swatch = array_merge( $swatch, $variation );
|
||||
$swatches[ $key ] = $swatch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $swatches;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if given attribute options wants to display variation images.
|
||||
*
|
||||
* @param array $options The attribute options array.
|
||||
*
|
||||
* @return bool Whether or not to us variation images.
|
||||
*/
|
||||
private function use_variation_images( $options ) {
|
||||
if ( ! $options ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( isset( $options['swatch_variation_images'] ) && $options['swatch_variation_images'] ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render swatch value in layered nav.
|
||||
*
|
||||
* @param string $term_html Term HTML.
|
||||
* @param object $term Term.
|
||||
* @param string $link Link.
|
||||
* @param string|int $count Count.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function layered_nav_term_html( $term_html, $term, $link, $count ) {
|
||||
$swatch_types = flatsome_swatches()->get_attribute_types();
|
||||
$attr = flatsome_swatches()->get_attribute( $term->taxonomy );
|
||||
|
||||
// Abort if this is normal attribute.
|
||||
if ( empty( $attr ) || ! array_key_exists( $attr->attribute_type, $swatch_types ) ) {
|
||||
return $term_html;
|
||||
}
|
||||
|
||||
$classes = array( 'ux-swatch-widget-layered-nav-list__graphic' );
|
||||
$img_size = apply_filters( 'flatsome_swatch_image_size', 'woocommerce_gallery_thumbnail', $term );
|
||||
|
||||
if ( get_theme_mod( 'swatches_box_shape' ) ) {
|
||||
$classes[] = 'ux-swatches--' . get_theme_mod( 'swatches_box_shape' );
|
||||
}
|
||||
|
||||
switch ( $attr->attribute_type ) {
|
||||
case 'ux_image':
|
||||
$image_id = get_term_meta( $term->term_id, 'ux_image', true );
|
||||
$image = '';
|
||||
$classes[] = 'ux-swatch--image';
|
||||
|
||||
if ( $image_id ) {
|
||||
$image = wp_get_attachment_image( $image_id, $img_size, false, array(
|
||||
'class' => "ux-swatch__img attachment-$img_size size-$img_size",
|
||||
'alt' => $term->name,
|
||||
) );
|
||||
}
|
||||
|
||||
$swatch = sprintf( '<div class="' . implode( ' ', $classes ) . '">%s</div>',
|
||||
$image ? $image : wc_placeholder_img( 'woocommerce_gallery_thumbnail' )
|
||||
);
|
||||
break;
|
||||
case 'ux_color':
|
||||
$color_classes = array( 'ux-swatch__color' );
|
||||
$value = get_term_meta( $term->term_id, 'ux_color', true );
|
||||
$color = flatsome_swatches()->parse_ux_color_term_meta( $value );
|
||||
$classes[] = 'ux-swatch--color';
|
||||
|
||||
if ( $color['class'] ) $color_classes[] = $color['class'];
|
||||
|
||||
$swatch = sprintf( '<div class="' . implode( ' ', $classes ) . '"><span class="%s" style="%s"></span></div>',
|
||||
implode( ' ', $color_classes ),
|
||||
$color['style']
|
||||
);
|
||||
break;
|
||||
default:
|
||||
return $term_html;
|
||||
}
|
||||
|
||||
return $swatch . $term_html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear cache on save post by ID.
|
||||
*
|
||||
* @param int $post_id Post ID.
|
||||
*/
|
||||
public function cache_clear_save_post( $post_id ) {
|
||||
if ( ! apply_filters( 'flatsome_swatches_cache_enabled', true ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$transient = 'flatsome_swatches_cache_' . $post_id;
|
||||
|
||||
delete_transient( $transient );
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear cache on product object save by ID.
|
||||
*
|
||||
* @param \WC_Product $product Product object.
|
||||
*/
|
||||
public function cache_clear_product_object_save( $product ) {
|
||||
if ( ! apply_filters( 'flatsome_swatches_cache_enabled', true ) ) {
|
||||
return;
|
||||
}
|
||||
$post_id = $product->get_id();
|
||||
$transient = 'flatsome_swatches_cache_' . $post_id;
|
||||
delete_transient( $transient );
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all cache.
|
||||
*
|
||||
* @param string $new_value The new value of the theme modification.
|
||||
* @param string $old_value The current value of the theme modification.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function cache_clear_all( $new_value, $old_value ) {
|
||||
if ( $new_value !== $old_value ) {
|
||||
flatsome_swatches()->cache_clear();
|
||||
}
|
||||
|
||||
return $new_value;
|
||||
}
|
||||
}
|
@@ -0,0 +1,227 @@
|
||||
<?php
|
||||
/**
|
||||
* Swatches main class.
|
||||
*
|
||||
* @package Flatsome\Extensions
|
||||
*/
|
||||
|
||||
namespace Flatsome\Extensions;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Class Swatches
|
||||
*
|
||||
* @package Flatsome\Extensions
|
||||
*/
|
||||
final class Swatches {
|
||||
/**
|
||||
* The single instance of the class.
|
||||
*
|
||||
* @var Swatches
|
||||
*/
|
||||
protected static $instance = null;
|
||||
|
||||
/**
|
||||
* Custom attribute types.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $types;
|
||||
|
||||
/**
|
||||
* Holds extension version.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $version;
|
||||
|
||||
/**
|
||||
* Swatches constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->types = array(
|
||||
'ux_color' => esc_html__( 'UX Color', 'flatsome' ),
|
||||
'ux_image' => esc_html__( 'UX Image', 'flatsome' ),
|
||||
'ux_label' => esc_html__( 'UX Label', 'flatsome' ),
|
||||
);
|
||||
|
||||
$theme = wp_get_theme( get_template() );
|
||||
$this->version = $theme->get( 'Version' );
|
||||
|
||||
$this->includes();
|
||||
|
||||
add_action( 'init', array( $this, 'init' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Include core files.
|
||||
*/
|
||||
public function includes() {
|
||||
if ( is_admin() ) {
|
||||
require_once dirname( __FILE__ ) . '/class-swatches-admin.php';
|
||||
}
|
||||
|
||||
require_once dirname( __FILE__ ) . '/class-swatches-frontend.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize.
|
||||
*/
|
||||
public function init() {
|
||||
add_filter( 'product_attributes_type_selector', array( $this, 'add_attribute_types' ) );
|
||||
|
||||
if ( is_admin() ) {
|
||||
$this->admin();
|
||||
}
|
||||
|
||||
if ( ! is_admin() || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
|
||||
$this->frontend();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add extra custom attribute types.
|
||||
*
|
||||
* @param array $types The default types.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function add_attribute_types( $types ) {
|
||||
$types = array_merge( $types, $this->types );
|
||||
|
||||
return $types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get custom attribute types.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_attribute_types() {
|
||||
return $this->types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get product attribute option data by ID.
|
||||
*
|
||||
* @param string|int $id The ID.
|
||||
*
|
||||
* @return false|mixed
|
||||
*/
|
||||
public function get_attribute_option( $id ) {
|
||||
return get_option( "flatsome_product_attribute-{$id}" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get product attribute option data by name.
|
||||
*
|
||||
* @param string $attribute The attribute name.
|
||||
*
|
||||
* @return false|mixed
|
||||
*/
|
||||
public function get_attribute_option_by_name( $attribute ) {
|
||||
$id = wc_attribute_taxonomy_id_by_name( $attribute );
|
||||
|
||||
return get_option( "flatsome_product_attribute-{$id}" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get attribute's properties.
|
||||
*
|
||||
* @param string $taxonomy Taxonomy.
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function get_attribute( $taxonomy ) {
|
||||
global $wpdb;
|
||||
|
||||
$attr = substr( $taxonomy, 3 );
|
||||
$attr = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}woocommerce_attribute_taxonomies WHERE attribute_name = %s;", $attr ) );
|
||||
|
||||
return $attr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the term value specifically for ux_color. Checks and
|
||||
* returns parsed data for single and dual color value(s).
|
||||
*
|
||||
* @param string $value The term meta value.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function parse_ux_color_term_meta( $value ) {
|
||||
$data = array(
|
||||
'color' => '',
|
||||
'color_2' => '',
|
||||
'class' => '',
|
||||
'style' => '',
|
||||
);
|
||||
|
||||
$colors = explode( ',', $value );
|
||||
|
||||
$data['color'] = $colors[0];
|
||||
|
||||
if ( count( $colors ) > 1 ) {
|
||||
$data['color_2'] = $colors[1];
|
||||
$data['style'] = "--swatch-color: $colors[0]; --swatch-color-secondary: $colors[1];";
|
||||
$data['class'] = 'ux-swatch__color--dual-color';
|
||||
} else {
|
||||
$data['style'] = "--swatch-color: $colors[0]";
|
||||
$data['class'] = 'ux-swatch__color--single-color';
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all cache.
|
||||
*/
|
||||
public function cache_clear() {
|
||||
global $wpdb;
|
||||
|
||||
$wpdb->query( "DELETE FROM {$wpdb->options} WHERE `option_name` LIKE ('%\_transient\_flatsome\_swatches%');" );
|
||||
$wpdb->query( "DELETE FROM {$wpdb->options} WHERE `option_name` LIKE ('%\_transient\_timeout\_flatsome\_swatches%');" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Main instance.
|
||||
*
|
||||
* @return Swatches
|
||||
*/
|
||||
public static function instance() {
|
||||
if ( is_null( self::$instance ) ) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instance of admin.
|
||||
*
|
||||
* @return Swatches_Admin
|
||||
*/
|
||||
public function admin() {
|
||||
return Swatches_Admin::instance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Instance of frontend.
|
||||
*
|
||||
* @return Swatches_Frontend
|
||||
*/
|
||||
public function frontend() {
|
||||
return Swatches_Frontend::instance();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Main instance.
|
||||
*
|
||||
* @return Swatches
|
||||
*/
|
||||
function flatsome_swatches() {
|
||||
return Swatches::instance();
|
||||
}
|
||||
|
@@ -0,0 +1,13 @@
|
||||
<?php // @codingStandardsIgnoreLine
|
||||
|
||||
|
||||
namespace Flatsome\Extensions;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
|
||||
global $extensions_url;
|
||||
require $extensions_url . '/flatsome-swatches/includes/class-swatches.php';
|
||||
|
||||
flatsome_swatches();
|
||||
|
Reference in New Issue
Block a user