File: /home/zwafgyp/lacalita/wp-content/plugins/rey-core/inc/modules/variation-swatches/swatch-base.php
<?php
namespace ReyCore\Modules\VariationSwatches;
if (!defined('ABSPATH')) exit; // Exit if accessed directly
class SwatchBase
{
public $is_default = false;
public $has_preview = false;
protected $custom_image = false;
public $list_args = [];
public $attribute_settings = [];
private $__term_swatch_data = null;
function __construct(){
}
function get_id(){
return '';
}
function get_name(){
return '';
}
function get_item_generic_class(){
return 'rey-swatchList-item--regular';
}
function get_swatch_style( $term ){}
function get_attribute_data($term){
return [];
}
function add_terms_settings(){}
function get_attribute_settings_support(){
return [];
}
/**
* Estabilish the location for the swatches fields
*
* @return array
*/
function get_term_settings_location(){
$location = [];
if( ! (isset($_REQUEST['taxonomy']) && $tax = reycore__clean($_REQUEST['taxonomy']) ) ) {
return $location;
}
if( 0 !== strpos( $tax, 'pa_' ) ){
return $location;
}
foreach ( wc_get_attribute_taxonomies() as $attribute ) {
if( $tax !== wc_attribute_taxonomy_name( $attribute->attribute_name ) ){
continue;
}
if( $this->get_id() !== $attribute->attribute_type ){
continue;
}
$location[] = [
[
'param' => 'taxonomy',
'operator' => '==',
'value' => $tax,
]
];
}
return $location;
}
public function get_term_swatch_data($tax, $term_id = 0 ){
if( ! taxonomy_exists($tax) ){
return [];
}
if( ! isset($this->__term_swatch_data[$tax]) ){
$data = false;
if( Base::$settings['attr_data_cache'] ){
$data = get_transient( Base::get_attribute_transient_name( $tax ) );
}
if( false === $data ){
$data = [];
$terms = get_terms([
'taxonomy' => $tax,
'hide_empty' => false,
// can't because i need the objects
// 'fields' => 'tt_ids',
]);
foreach ($terms as $term) {
if( ! isset($term->term_id) ){
continue;
}
if( isset($data[ $term->term_id ]) ){
continue;
}
$data[ $term->term_id ] = $this->get_attribute_data($term);
}
if( Base::$settings['attr_data_cache'] ){
set_transient( Base::get_attribute_transient_name( $tax ), $data, WEEK_IN_SECONDS );
}
}
$this->__term_swatch_data[$tax] = $data;
}
else {
$data = $this->__term_swatch_data[$tax];
}
if( $term_id && isset($data[ $term_id ]) ){
return $data[ $term_id ];
}
return $data;
}
function get_term_swatch_data_by_term($term){
if( ! isset($term->taxonomy) ){
$term = Base::get_term($term);
if( ! isset($term->taxonomy) ){
return;
}
}
return $this->get_term_swatch_data($term->taxonomy, $term->term_id);
}
function get_content__text($term){}
function get_content__style($args){}
function get_tooltip_content__before($term){}
function get_tooltip_content__after($term){}
function get_clean_swatch_id(){
return str_replace( Base::TYPES_PREFIX, '', $this->get_id() );
}
function render_list( $args = [] ){
if( ! ($this->list_args = $args) ){
return;
}
// rename
$this->list_args['taxonomy'] = $this->list_args['attribute'];
$this->attribute_settings = Base::get_attributes_swatch_settings( $this->list_args['taxonomy'] );
$list_style = [];
// Only in Product page
if( ! \ReyCore\Modules\VariationSwatches\Frontend::is_catalog_mode() ){
$item_styles = apply_filters('reycore/variation_swatches/item_styles', [
'swatch_width' => '--item-width:%spx',
'swatch_height' => '--item-height:%spx',
'swatch_radius' => '--item-radius:%spx',
'swatch_padding' => '--item-padding:%spx',
'swatch_spacing' => '--item-spacing:%spx',
'swatch_font_size' => '--item-font-size:%spx',
]);
foreach ( $item_styles as $key => $style_css) {
if( ! in_array($key, $this->get_attribute_settings_support(), true) ){
continue;
}
if( ! (isset($this->attribute_settings[$key]) && $style_data = $this->attribute_settings[$key]) ){
continue;
}
$list_style[] = sprintf($style_css, $style_data);
}
}
$attr_tax = sanitize_title($this->list_args['taxonomy']);
$html_list_attributes['aria-label'] = esc_attr($this->list_args['attribute_data']['name']);
$html_list_attributes['data-attribute_name'] = 'attribute_' . $attr_tax;
$html_list_attributes['style'] = esc_attr(implode(';', $list_style));
$html_list_attributes['class'] = $this->get_list_html_classes();
// $html_list_attributes['data-placeholdered'] = '';
if( ! empty($this->attribute_settings['label_display']) ){
$html_list_attributes['data-tr-class'] = '--label-' . esc_attr($this->attribute_settings['label_display']);
$html_list_attributes['data-tr-attribute'] = $attr_tax;
}
$items_output = $this->render_item();
if( ! $items_output ){
return '';
}
$items_output .= $this->limit_link_output();
return sprintf('<div %s>%s</div>',
reycore__implode_html_attributes($html_list_attributes),
$items_output
);
}
function get_list_html_classes(){
$list_classes = [
'rey-swatchList'
];
$type = $this->get_clean_swatch_id();
$list_classes['type'] = '--type-' . esc_attr( $type );
$list_classes['tooltip_theme'] = sprintf('--%s-tooltips', Base::$settings['tooltip_theme']);
$list_classes['disabled_behaviour'] = '--disabled-' . esc_attr( get_theme_mod('pdp_swatches__disabled_behaviour', 'dim') );
$list_classes['deselection'] = '--deselection-' . esc_attr( get_theme_mod('pdp_swatches__deselection', 'clear') );
if( Base::$settings['image_uses_tag'] && 'image' === $type ){
$list_classes[] = '--image-tag';
}
return esc_attr(implode(' ', $list_classes));
}
function limit_link_output(){
if( ! (isset($this->list_args['limit']) && $limit = $this->list_args['limit']) ){
return;
}
return sprintf('<a href="%1$s" class="rey-swatchList-more" title="%3$s">%2$d+</a>',
get_permalink( $this->list_args['product']->get_id() ),
$this->list_args['limit_diff'],
sprintf( esc_html__('Click to see %s more', 'rey-core'), $this->list_args['limit_diff'] )
);
}
function default_item_classes(){
return [
'rey-swatchList-item',
'--type-' . esc_attr( $this->get_clean_swatch_id() ),
$this->get_item_generic_class()
];
}
function default_item_html_attributes($term){
// title
$title_attr_name = 'title';
if( isset($this->attribute_settings['swatch_tooltip']) && 'no' !== $this->attribute_settings['swatch_tooltip'] ){
$title_attr_name = 'data-title';
}
$html_attributes[$title_attr_name] = esc_attr($term->name);
$attr_tax = sanitize_title($this->list_args['taxonomy']);
$html_attributes['data-term-id'] = absint($term->term_id);
$html_attributes['data-term-slug'] = esc_attr($term->slug);
$html_attributes['data-attribute-name'] = $attr_tax;
$html_attributes['aria-label'] = esc_attr($term->name);
$html_attributes['role'] = 'radio';
$html_attributes['aria-checked'] = $this->list_args['selected'] === $term->slug ? 'true' : 'false';
return $html_attributes;
}
function render_item(){
$output = '';
$options = $this->list_args['options'];
$product = $this->list_args['product'];
$attribute = $this->list_args['attribute'];
if ( empty( $options ) && ! empty( $product ) && ! empty( $attribute ) ) {
$attributes = $product->get_variation_attributes();
$options = $attributes[ $attribute ];
}
if ( empty( $options ) ) {
return $output;
}
if ( ! $product ) {
return $output;
}
if ( ! taxonomy_exists( $attribute ) ) {
if( ! $this->list_args['custom_attribute'] ){
return $output;
}
}
if( $this->list_args['custom_attribute'] ){
foreach ($options as $key => $option) {
$terms[] = (object) [
'name' => $option,
'slug' => $option,
'term_id' => '',
'description' => '',
];
}
}
else {
// Get terms if this is a taxonomy - ordered. We need the names too.
$terms = wc_get_product_terms( $product->get_id(), $attribute, [
'fields' => 'all',
] );
}
foreach ( $terms as $i => $term ) {
if ( ! in_array( $term->slug, $options, true ) ) {
continue;
}
$style = $this->get_content__style([
'term' => $term,
'custom_image' => $this->get_item_custom_image($term),
'attribute' => $attribute,
]);
$classes = $this->default_item_classes();
$maybe_select = true;
if( ! Base::$settings['autoselect_catalog_variation'] && ! \ReyCore\WooCommerce\Pdp::is_single_true_product() ){
$maybe_select = false;
}
$classes[] = $this->list_args['selected'] === $term->slug && $maybe_select ? '--selected' : '';
if( Base::$settings['fallback_image_text'] && ! $style ){
$classes[] = '--no-style';
}
$html_attributes = $this->default_item_html_attributes($term);
$html_attributes['class'] = esc_attr(implode(' ', $classes));
$html_attributes['data-description'] = esc_html($term->description);
$item_output = sprintf('<div %s>%s</div>', reycore__implode_html_attributes($html_attributes), $this->get_item_content($term, $style) );
$output .= apply_filters('reycore/variation_swatches/render_item', $item_output, $term, $this, [
'is_last' => count($options) === ($i + 1),
'html_attributes' => $html_attributes
] );
}
return $output;
}
function get_item_custom_image($term){
$custom_image = false;
if( isset($this->attribute_settings['use_variation_img']) && 'no' !== $this->attribute_settings['use_variation_img'] ){
$custom_image = $this->get_variation_image_data($term);
}
return $custom_image;
}
function get_item_content($term, $style){
if( empty($term) ){
return;
}
if( ! isset($term->taxonomy) && isset($term->name) ){
$term_name = ! $style ? $term->name : '';
return sprintf('<span class="rey-swatchList-itemContent" style="%2$s">%1$s</span>', $term_name, $style );
}
$text = $this->get_content__text( $term );
if( Base::$settings['fallback_image_text'] && ! $style ){
if( ! $text && isset($term->name) ){
$text = $term->name;
}
}
// check if it's a valid URL and create an image tag
if( Base::$settings['image_uses_tag'] && filter_var( $style, FILTER_VALIDATE_URL ) ){
$text .= sprintf('<img src="%s" loading="lazy">', $style);
$style = ''; // reset style
}
$output = sprintf('<span class="rey-swatchList-itemContent" style="%1$s">%2$s</span>', $style, $text );
if( isset($this->attribute_settings['swatch_tooltip']) && 'no' !== $this->attribute_settings['swatch_tooltip'] ){
$output .= $this->render_tooltip($term);
}
return $output;
}
function render_tooltip($term){
if( empty($term) ){
return;
}
$content = $this->get_tooltip_content__before($term);
if( in_array($this->attribute_settings['swatch_tooltip'], ['yes', 'yes_both'], true) )
$content .= sprintf('<span class="__title">%s</span>', $term->name);
if( in_array($this->attribute_settings['swatch_tooltip'], ['yes_desc', 'yes_both'], true) && ($desc = $term->description) ){
$content .= sprintf('<span class="__desc">%s</span>', $desc);
}
$content .= $this->get_tooltip_content__after($term);
$content .= '<div class="__corner"></div>';
return sprintf('<div class="__tooltip"><div class="__holder">%s</div></div>', $content );
}
/**
* Gets a variation image based on arguments
*
* @param array $args
* @param object $term
* @return array
*/
function get_variation_image_data($term){
$data = [];
if( ! ($taxonomy = $term->taxonomy) ){
return $data;
}
$variations = $this->list_args['product']->get_available_variations();
// $product_image = $this->list_args['product']->get_image_id();
foreach ( $variations as $variation ) {
$attr_key = 'attribute_' . $taxonomy;
if ( ! isset( $variation['attributes'][ $attr_key ] ) ) {
continue;
}
if ( ! ( $attribute_name = $variation['attributes'][ $attr_key ] ) ) {
continue;
}
if ( $attribute_name !== $term->slug ) {
continue;
}
$image_size = Base::$settings['variations_image_size'];
if( ! isset($variation['image'][$image_size]) ){
// check for image ID in case URL is missing
if( isset($variation['image_id']) && ! empty($variation['image_id']) ){
$variation['image'][$image_size] = '';
}
// if not, just bail
else {
continue;
}
}
// fallback to default data if variation doesn't have an image
if( ! Base::$settings['variations_use_main_image'] ){
$variation_product = wc_get_product( $variation['variation_id'] );
if( ! $variation_product->get_image_id('edit') ){
continue;
}
}
$data = [
'id' => $variation['image_id'],
'url' => $variation['image'][$image_size],
];
}
return $data;
}
function get_variation_price($term){
$data = '';
if( ! ($taxonomy = $term->taxonomy) ){
return $data;
}
$variations = $this->list_args['product']->get_available_variations();
foreach ( $variations as $variation ) {
$attr_key = 'attribute_' . $taxonomy;
if ( ! isset( $variation['attributes'][ $attr_key ] ) ) {
continue;
}
if ( ! ( $attribute_name = $variation['attributes'][ $attr_key ] ) ) {
continue;
}
if ( $attribute_name !== $term->slug ) {
continue;
}
}
return $data;
}
}