<?php
use Automattic\Jetpack\Constants;
if (!defined('ABSPATH')) {
exit;
}
abstract class WC_Widget extends WP_Widget
{
public $widget_cssclass;
public $widget_description;
public $widget_id;
public $widget_name;
public $settings;
public function __construct()
{
$widget_ops = array('classname' => $this->widget_cssclass, 'description' => $this->widget_description, 'customize_selective_refresh' => true, 'show_instance_in_rest' => true);
parent::__construct($this->widget_id, $this->widget_name, $widget_ops);
add_action('save_post', array($this, 'flush_widget_cache'));
add_action('deleted_post', array($this, 'flush_widget_cache'));
add_action('switch_theme', array($this, 'flush_widget_cache'));
}
public function get_cached_widget($args)
{
if (empty($args['widget_id'])) {
return false;
}
$cache = wp_cache_get($this->get_widget_id_for_cache($this->widget_id), 'widget');
if (!is_array($cache)) {
$cache = array();
}
if (isset($cache[$this->get_widget_id_for_cache($args['widget_id'])])) {
echo $cache[$this->get_widget_id_for_cache($args['widget_id'])];
return true;
}
return false;
}
public function cache_widget($args, $content)
{
if (empty($args['widget_id'])) {
return $content;
}
$cache = wp_cache_get($this->get_widget_id_for_cache($this->widget_id), 'widget');
if (!is_array($cache)) {
$cache = array();
}
$cache[$this->get_widget_id_for_cache($args['widget_id'])] = $content;
wp_cache_set($this->get_widget_id_for_cache($this->widget_id), $cache, 'widget');
return $content;
}
public function flush_widget_cache()
{
foreach (array('https', 'http') as $scheme) {
wp_cache_delete($this->get_widget_id_for_cache($this->widget_id, $scheme), 'widget');
}
}
protected function get_instance_title($instance)
{
if (isset($instance['title'])) {
return $instance['title'];
}
if (isset($this->settings, $this->settings['title'], $this->settings['title']['std'])) {
return $this->settings['title']['std'];
}
return '';
}
public function widget_start($args, $instance)
{
echo $args['before_widget'];
$title = apply_filters('widget_title', $this->get_instance_title($instance), $instance, $this->id_base);
if ($title) {
echo $args['before_title'] . $title . $args['after_title'];
}
}
public function widget_end($args)
{
echo $args['after_widget'];
}
public function update($new_instance, $old_instance)
{
$instance = $old_instance;
if (empty($this->settings)) {
return $instance;
}
foreach ($this->settings as $key => $setting) {
if (!isset($setting['type'])) {
continue;
}
switch ($setting['type']) {
case 'number':
$instance[$key] = absint($new_instance[$key]);
if (isset($setting['min']) && '' !== $setting['min']) {
$instance[$key] = max($instance[$key], $setting['min']);
}
if (isset($setting['max']) && '' !== $setting['max']) {
$instance[$key] = min($instance[$key], $setting['max']);
}
break;
case 'textarea':
$instance[$key] = wp_kses(trim(wp_unslash($new_instance[$key])), wp_kses_allowed_html('post'));
break;
case 'checkbox':
$instance[$key] = empty($new_instance[$key]) ? 0 : 1;
break;
default:
$instance[$key] = isset($new_instance[$key]) ? sanitize_text_field($new_instance[$key]) : $setting['std'];
break;
}
$instance[$key] = apply_filters('woocommerce_widget_settings_sanitize_option', $instance[$key], $new_instance, $key, $setting);
}
$this->flush_widget_cache();
return $instance;
}
public function form($instance)
{
if (empty($this->settings)) {
return;
}
foreach ($this->settings as $key => $setting) {
$class = isset($setting['class']) ? $setting['class'] : '';
$value = isset($instance[$key]) ? $instance[$key] : $setting['std'];
switch ($setting['type']) {
case 'text':
?>
<p>
<label for="<?php
echo esc_attr($this->get_field_id($key));
?>"><?php
echo wp_kses_post($setting['label']);
?></label><?php
?>
<input class="widefat <?php
echo esc_attr($class);
?>" id="<?php
echo esc_attr($this->get_field_id($key));
?>" name="<?php
echo esc_attr($this->get_field_name($key));
?>" type="text" value="<?php
echo esc_attr($value);
?>" />
</p>
<?php
break;
case 'number':
?>
<p>
<label for="<?php
echo esc_attr($this->get_field_id($key));
?>"><?php
echo $setting['label'];
?></label>
<input class="widefat <?php
echo esc_attr($class);
?>" id="<?php
echo esc_attr($this->get_field_id($key));
?>" name="<?php
echo esc_attr($this->get_field_name($key));
?>" type="number" step="<?php
echo esc_attr($setting['step']);
?>" min="<?php
echo esc_attr($setting['min']);
?>" max="<?php
echo esc_attr($setting['max']);
?>" value="<?php
echo esc_attr($value);
?>" />
</p>
<?php
break;
case 'select':
?>
<p>
<label for="<?php
echo esc_attr($this->get_field_id($key));
?>"><?php
echo $setting['label'];
?></label>
<select class="widefat <?php
echo esc_attr($class);
?>" id="<?php
echo esc_attr($this->get_field_id($key));
?>" name="<?php
echo esc_attr($this->get_field_name($key));
?>">
<?php
foreach ($setting['options'] as $option_key => $option_value) {
?>
<option value="<?php
echo esc_attr($option_key);
?>" <?php
selected($option_key, $value);
?>><?php
echo esc_html($option_value);
?></option>
<?php
}
?>
</select>
</p>
<?php
break;
case 'textarea':
?>
<p>
<label for="<?php
echo esc_attr($this->get_field_id($key));
?>"><?php
echo $setting['label'];
?></label>
<textarea class="widefat <?php
echo esc_attr($class);
?>" id="<?php
echo esc_attr($this->get_field_id($key));
?>" name="<?php
echo esc_attr($this->get_field_name($key));
?>" cols="20" rows="3"><?php
echo esc_textarea($value);
?></textarea>
<?php
if (isset($setting['desc'])) {
?>
<small><?php
echo esc_html($setting['desc']);
?></small>
<?php
}
?>
</p>
<?php
break;
case 'checkbox':
?>
<p>
<input class="checkbox <?php
echo esc_attr($class);
?>" id="<?php
echo esc_attr($this->get_field_id($key));
?>" name="<?php
echo esc_attr($this->get_field_name($key));
?>" type="checkbox" value="1" <?php
checked($value, 1);
?> />
<label for="<?php
echo esc_attr($this->get_field_id($key));
?>"><?php
echo $setting['label'];
?></label>
</p>
<?php
break;
default:
do_action('woocommerce_widget_field_' . $setting['type'], $key, $value, $setting, $instance);
break;
}
}
}
protected function get_current_page_url()
{
if (Constants::is_defined('SHOP_IS_ON_FRONT')) {
$link = home_url();
} elseif (is_shop()) {
$link = get_permalink(wc_get_page_id('shop'));
} elseif (is_product_category()) {
$link = get_term_link(get_query_var('product_cat'), 'product_cat');
} elseif (is_product_tag()) {
$link = get_term_link(get_query_var('product_tag'), 'product_tag');
} else {
$queried_object = get_queried_object();
$link = get_term_link($queried_object->slug, $queried_object->taxonomy);
}
if (isset($_GET['min_price'])) {
$link = add_query_arg('min_price', wc_clean(wp_unslash($_GET['min_price'])), $link);
}
if (isset($_GET['max_price'])) {
$link = add_query_arg('max_price', wc_clean(wp_unslash($_GET['max_price'])), $link);
}
if (isset($_GET['orderby'])) {
$link = add_query_arg('orderby', wc_clean(wp_unslash($_GET['orderby'])), $link);
}
if (get_search_query()) {
$link = add_query_arg('s', rawurlencode(htmlspecialchars_decode(get_search_query())), $link);
}
if (isset($_GET['post_type'])) {
$link = add_query_arg('post_type', wc_clean(wp_unslash($_GET['post_type'])), $link);
if (is_shop()) {
$link = remove_query_arg('page_id', $link);
}
}
if (isset($_GET['rating_filter'])) {
$link = add_query_arg('rating_filter', wc_clean(wp_unslash($_GET['rating_filter'])), $link);
}
if ($_chosen_attributes = WC_Query::get_layered_nav_chosen_attributes()) {
foreach ($_chosen_attributes as $name => $data) {
$filter_name = wc_attribute_taxonomy_slug($name);
if (!empty($data['terms'])) {
$link = add_query_arg('filter_' . $filter_name, implode(',', $data['terms']), $link);
}
if ('or' === $data['query_type']) {
$link = add_query_arg('query_type_' . $filter_name, 'or', $link);
}
}
}
return apply_filters('woocommerce_widget_get_current_page_url', $link, $this);
}
protected function get_widget_id_for_cache($widget_id, $scheme = '')
{
if ($scheme) {
$widget_id_for_cache = $widget_id . '-' . $scheme;
} else {
$widget_id_for_cache = $widget_id . '-' . (is_ssl() ? 'https' : 'http');
}
return apply_filters('woocommerce_cached_widget_id', $widget_id_for_cache);
}
}