<?php

defined('ABSPATH') || exit;
class WC_Cache_Helper
{
    private static $delete_transients = array();
    public static function init()
    {
        add_filter('nocache_headers', array(__CLASS__, 'additional_nocache_headers'), 10);
        add_action('shutdown', array(__CLASS__, 'delete_transients_on_shutdown'), 10);
        add_action('template_redirect', array(__CLASS__, 'geolocation_ajax_redirect'));
        add_action('wc_ajax_update_order_review', array(__CLASS__, 'update_geolocation_hash'), 5);
        add_action('admin_notices', array(__CLASS__, 'notices'));
        add_action('delete_version_transients', array(__CLASS__, 'delete_version_transients'), 10);
        add_action('wp', array(__CLASS__, 'prevent_caching'));
        add_action('clean_term_cache', array(__CLASS__, 'clean_term_cache'), 10, 2);
        add_action('edit_terms', array(__CLASS__, 'clean_term_cache'), 10, 2);
    }
    public static function additional_nocache_headers($headers)
    {
        $agent = isset($_SERVER['HTTP_USER_AGENT']) ? wp_unslash($_SERVER['HTTP_USER_AGENT']) : '';
        $set_cache = false;
        if (apply_filters('woocommerce_enable_nocache_headers', false)) {
            $set_cache = true;
        }
        if (false !== strpos($agent, 'googleweblight')) {
            $set_cache = true;
        }
        if (false !== strpos($agent, 'Chrome') && is_cart()) {
            $set_cache = true;
        }
        if ($set_cache) {
            $headers['Cache-Control'] = 'no-transform, no-cache, no-store, must-revalidate';
        }
        return $headers;
    }
    public static function queue_delete_transient($keys)
    {
        self::$delete_transients = array_unique(array_merge(is_array($keys) ? $keys : array($keys), self::$delete_transients));
    }
    public static function delete_transients_on_shutdown()
    {
        if (self::$delete_transients) {
            foreach (self::$delete_transients as $key) {
                delete_transient($key);
            }
            self::$delete_transients = array();
        }
    }
    public static function invalidate_attribute_count($attribute_keys)
    {
        if ($attribute_keys) {
            foreach ($attribute_keys as $attribute_key) {
                self::queue_delete_transient('wc_layered_nav_counts_' . $attribute_key);
            }
        }
    }
    public static function get_cache_prefix($group)
    {
        $prefix = wp_cache_get('wc_' . $group . '_cache_prefix', $group);
        if (false === $prefix) {
            $prefix = microtime();
            wp_cache_set('wc_' . $group . '_cache_prefix', $prefix, $group);
        }
        return 'wc_cache_' . $prefix . '_';
    }
    public static function incr_cache_prefix($group)
    {
        wc_deprecated_function('WC_Cache_Helper::incr_cache_prefix', '3.9.0', 'WC_Cache_Helper::invalidate_cache_group');
        self::invalidate_cache_group($group);
    }
    public static function invalidate_cache_group($group)
    {
        wp_cache_set('wc_' . $group . '_cache_prefix', microtime(), $group);
    }
    public static function geolocation_ajax_get_location_hash()
    {
        $customer = new WC_Customer(0, true);
        $location = array();
        $location['country'] = $customer->get_billing_country();
        $location['state'] = $customer->get_billing_state();
        $location['postcode'] = $customer->get_billing_postcode();
        $location['city'] = $customer->get_billing_city();
        return apply_filters('woocommerce_geolocation_ajax_get_location_hash', substr(md5(implode('', $location)), 0, 12), $location, $customer);
    }
    public static function prevent_caching()
    {
        if (!is_blog_installed()) {
            return;
        }
        $page_ids = array_filter(array(wc_get_page_id('cart'), wc_get_page_id('checkout'), wc_get_page_id('myaccount')));
        if (is_page($page_ids)) {
            self::set_nocache_constants();
            nocache_headers();
        }
    }
    public static function geolocation_ajax_redirect()
    {
        if ('geolocation_ajax' === get_option('woocommerce_default_customer_address') && !is_checkout() && !is_cart() && !is_account_page() && !is_ajax() && empty($_POST)) {
            $location_hash = self::geolocation_ajax_get_location_hash();
            $current_hash = isset($_GET['v']) ? wc_clean(wp_unslash($_GET['v'])) : '';
            if (empty($current_hash) || $current_hash !== $location_hash) {
                global $wp;
                $redirect_url = trailingslashit(home_url($wp->request));
                if (!empty($_SERVER['QUERY_STRING'])) {
                    $redirect_url = add_query_arg(wp_unslash($_SERVER['QUERY_STRING']), '', $redirect_url);
                }
                if (!get_option('permalink_structure')) {
                    $redirect_url = add_query_arg($wp->query_string, '', $redirect_url);
                }
                $redirect_url = add_query_arg('v', $location_hash, remove_query_arg('v', $redirect_url));
                wp_safe_redirect(esc_url_raw($redirect_url), 307);
                exit;
            }
        }
    }
    public static function update_geolocation_hash()
    {
        if ('geolocation_ajax' === get_option('woocommerce_default_customer_address')) {
            wc_setcookie('woocommerce_geo_hash', static::geolocation_ajax_get_location_hash(), time() + HOUR_IN_SECONDS);
        }
    }
    public static function get_transient_version($group, $refresh = false)
    {
        $transient_name = $group . '-transient-version';
        $transient_value = get_transient($transient_name);
        if (false === $transient_value || true === $refresh) {
            $transient_value = (string) time();
            set_transient($transient_name, $transient_value);
        }
        return $transient_value;
    }
    public static function set_nocache_constants($return = true)
    {
        wc_maybe_define_constant('DONOTCACHEPAGE', true);
        wc_maybe_define_constant('DONOTCACHEOBJECT', true);
        wc_maybe_define_constant('DONOTCACHEDB', true);
        return $return;
    }
    public static function notices()
    {
        if (!function_exists('w3tc_pgcache_flush') || !function_exists('w3_instance')) {
            return;
        }
        $config = w3_instance('W3_Config');
        $enabled = $config->get_integer('dbcache.enabled');
        $settings = array_map('trim', $config->get_array('dbcache.reject.sql'));
        if ($enabled && !in_array('_wc_session_', $settings, true)) {
            ?>
			<div class="error">
				<p>
				<?php 
            echo wp_kses_post(sprintf(__('In order for <strong>database caching</strong> to work with WooCommerce you must add %1$s to the "Ignored Query Strings" option in <a href="%2$s">W3 Total Cache settings</a>.', 'woocommerce'), '<code>_wc_session_</code>', esc_url(admin_url('admin.php?page=w3tc_dbcache'))));
            ?>
				</p>
			</div>
			<?php 
        }
    }
    public static function clean_term_cache($ids, $taxonomy)
    {
        if ('product_cat' === $taxonomy) {
            $ids = is_array($ids) ? $ids : array($ids);
            $clear_ids = array(0);
            foreach ($ids as $id) {
                $clear_ids[] = $id;
                $clear_ids = array_merge($clear_ids, get_ancestors($id, 'product_cat', 'taxonomy'));
            }
            $clear_ids = array_unique($clear_ids);
            foreach ($clear_ids as $id) {
                wp_cache_delete('product-category-hierarchy-' . $id, 'product_cat');
            }
        }
    }
    public static function delete_version_transients($version = '')
    {
        if (!wp_using_ext_object_cache() && !empty($version)) {
            global $wpdb;
            $limit = apply_filters('woocommerce_delete_version_transients_limit', 1000);
            if (!$limit) {
                return;
            }
            $affected = $wpdb->query($wpdb->prepare("DELETE FROM {$wpdb->options} WHERE option_name LIKE %s LIMIT %d;", '\\_transient\\_%' . $version, $limit));
            if ($affected === $limit) {
                wp_schedule_single_event(time() + 30, 'delete_version_transients', array($version));
            }
        }
    }
}
WC_Cache_Helper::init();