if (!function_exists('pure_get_option')) { function pure_get_option($key, $default = null) { $options = get_option('pure_theme_options', []); return isset($options[$key]) ? $options[$key] : $default; } } if (!function_exists('pure_get_dark_mode')) { function pure_get_dark_mode() { $user_pref = isset($_COOKIE['pure_dark_mode']) ? sanitize_text_field($_COOKIE['pure_dark_mode']) : ''; if (in_array($user_pref, ['dark', 'light'], true)) { return $user_pref; } $os_pref = pure_get_option('dark_mode', 'auto'); if ($os_pref === 'dark') { return 'dark'; } if ($os_pref === 'light') { return 'light'; } return 'light'; } } if (!function_exists('pure_get_sidebar_layout')) { function pure_get_sidebar_layout() { global $post; if (is_404() || is_page_template('templates/full-width.php')) { return 'no-sidebar'; } if (is_singular() && isset($post->ID)) { $meta = get_post_meta($post->ID, '_pure_sidebar_layout', true); if ($meta && $meta !== 'default') { return $meta; } } if (function_exists('is_shop') && (is_shop() || is_product_category() || is_product_tag())) { return pure_get_option('shop_sidebar_layout', 'left-sidebar'); } if (function_exists('is_product') && is_product()) { return pure_get_option('product_sidebar_layout', 'no-sidebar'); } if (is_singular('post')) { return pure_get_option('blog_sidebar_layout', 'right-sidebar'); } if (is_page()) { return pure_get_option('page_sidebar_layout', 'no-sidebar'); } return pure_get_option('default_sidebar_layout', 'right-sidebar'); } } if (!function_exists('pure_is_vendor_store')) { function pure_is_vendor_store() { if (!function_exists('dokan_is_store_page') && !function_exists('wcfm_is_store_page') && !function_exists('is_multivendorx_store_page')) { return false; } if (function_exists('dokan_is_store_page') && dokan_is_store_page()) { return true; } if (function_exists('wcfm_is_store_page') && wcfm_is_store_page()) { return true; } if (function_exists('is_multivendorx_store_page') && is_multivendorx_store_page()) { return true; } return false; } } if (!function_exists('pure_get_vendor_id')) { function pure_get_vendor_id() { if (function_exists('dokan_is_store_page') && dokan_is_store_page()) { $store_user = dokan()->vendor->get(get_query_var('author')); return $store_user ? $store_user->get_id() : 0; } if (function_exists('wcfm_is_store_page') && wcfm_is_store_page()) { $store_user = get_query_var('author_name') ? get_user_by('slug', get_query_var('author_name')) : null; return $store_user ? $store_user->ID : 0; } if (function_exists('is_multivendorx_store_page') && is_multivendorx_store_page()) { $vendor = get_mvx_vendor(get_query_var('author')); return $vendor ? $vendor->get_id() : 0; } return 0; } } if (!function_exists('pure_get_rating_stars')) { function pure_get_rating_stars($rating) { $rating = floatval($rating); $rating = min(5, max(0, $rating)); $full_stars = floor($rating); $half_star = ($rating - $full_stars) >= 0.5 ? 1 : 0; $empty_stars = 5 - $full_stars - $half_star; $output = ''; $output .= str_repeat('', $full_stars); if ($half_star) { $output .= ''; } $output .= str_repeat('', $empty_stars); $output .= ''; return $output; } } if (!function_exists('pure_get_svg')) { function pure_get_svg($icon) { $icons = [ 'cart' => '', 'heart' => '', 'heart-filled' => '', 'compare' => '', 'search' => '', 'user' => '', 'menu' => '', 'close' => '', 'chevron-down' => '', 'chevron-up' => '', 'chevron-left' => '', 'chevron-right' => '', 'arrow-right' => '', 'arrow-left' => '', 'check' => '', 'plus' => '', 'minus' => '', 'star' => '', 'grid' => '', 'list' => '', 'filter' => '', 'sun' => '', 'moon' => '', 'phone' => '', 'mail' => '', 'map-pin' => '', 'clock' => '', 'eye' => '', 'share' => '', 'trash' => '', 'edit' => '', 'tag' => '', 'truck' => '', 'shield' => '', 'refresh' => '', 'loader' => '', 'external-link' => '', ]; if (isset($icons[$icon])) { return '' . $icons[$icon] . ''; } return ''; } } if (!function_exists('pure_pagination')) { function pure_pagination($query = null) { if (!$query) { global $wp_query; $query = $wp_query; } $total = $query->max_num_pages; if ($total <= 1) { return; } $current = max(1, get_query_var('paged', 1)); $big = 999999999; $args = [ 'base' => str_replace($big, '%#%', esc_url(get_pagenum_link($big))), 'format' => '?paged=%#%', 'current' => $current, 'total' => $total, 'prev_text' => pure_get_svg('chevron-left') . '' . esc_html__('Previous', 'pure-theme') . '', 'next_text' => '' . esc_html__('Next', 'pure-theme') . '' . pure_get_svg('chevron-right'), 'type' => 'list', 'end_size' => 1, 'mid_size' => 2, ]; $links = paginate_links($args); if ($links) { echo ''; } } } if (!function_exists('pure_breadcrumbs')) { function pure_breadcrumbs() { $delimiter = pure_get_svg('chevron-right'); $home_text = esc_html__('Home', 'pure-theme'); $before = ''; $after = ''; echo ''; } } if (!function_exists('pure_social_share')) { function pure_social_share() { global $post; $url = get_permalink($post->ID); $title = urlencode(get_the_title($post->ID)); $thumbnail = get_the_post_thumbnail_url($post->ID, 'full'); $excerpt = urlencode(get_the_excerpt($post)); $shares = [ 'facebook' => [ 'url' => 'https://www.facebook.com/sharer/sharer.php?u=' . urlencode($url), 'label' => esc_attr__('Share on Facebook', 'pure-theme'), 'icon' => 'facebook', ], 'twitter' => [ 'url' => 'https://twitter.com/intent/tweet?url=' . urlencode($url) . '&text=' . $title, 'label' => esc_attr__('Share on X', 'pure-theme'), 'icon' => 'twitter', ], 'pinterest' => [ 'url' => 'https://pinterest.com/pin/create/button/?url=' . urlencode($url) . '&media=' . urlencode($thumbnail) . '&description=' . $excerpt, 'label' => esc_attr__('Share on Pinterest', 'pure-theme'), 'icon' => 'pinterest', ], 'linkedin' => [ 'url' => 'https://www.linkedin.com/sharing/share-offsite/?url=' . urlencode($url), 'label' => esc_attr__('Share on LinkedIn', 'pure-theme'), 'icon' => 'linkedin', ], 'reddit' => [ 'url' => 'https://reddit.com/submit?url=' . urlencode($url) . '&title=' . $title, 'label' => esc_attr__('Share on Reddit', 'pure-theme'), 'icon' => 'reddit', ], 'whatsapp' => [ 'url' => 'https://wa.me/?text=' . urlencode($title . ' ' . $url), 'label' => esc_attr__('Share on WhatsApp', 'pure-theme'), 'icon' => 'whatsapp', ], 'telegram' => [ 'url' => 'https://t.me/share/url?url=' . urlencode($url) . '&text=' . $title, 'label' => esc_attr__('Share on Telegram', 'pure-theme'), 'icon' => 'telegram', ], 'email' => [ 'url' => 'mailto:?subject=' . $title . '&body=' . urlencode($url), 'label' => esc_attr__('Share via Email', 'pure-theme'), 'icon' => 'mail', ], 'copy' => [ 'url' => $url, 'label' => esc_attr__('Copy link', 'pure-theme'), 'icon' => 'copy', 'class' => 'pure-share--copy', ], ]; $social_icons = [ 'facebook' => '', 'twitter' => '', 'pinterest' => '', 'linkedin' => '', 'reddit' => '', 'whatsapp' => '', 'telegram' => '', 'copy' => '', ]; $output = '
'; $output .= '' . esc_html__('Share:', 'pure-theme') . ''; foreach ($shares as $key => $share) { $class = isset($share['class']) ? ' ' . $share['class'] : ''; $output .= ''; $output .= $social_icons[$key] ?? pure_get_svg($share['icon']); $output .= ''; } $output .= '
'; return $output; } } if (!function_exists('pure_get_placeholder_image')) { function pure_get_placeholder_image($size = 'medium') { $size_map = [ 'thumbnail' => [150, 150], 'medium' => [300, 300], 'large' => [600, 600], 'full' => [800, 800], 'pure-product-thumb' => [400, 400], 'pure-product-medium' => [600, 600], 'pure-product-large' => [800, 800], 'pure-store-banner' => [1200, 400], 'pure-store-logo' => [200, 200], 'pure-blog-thumb' => [800, 500], 'pure-hero-banner' => [1920, 600], 'pure-category-thumb' => [300, 300], ]; if (isset($size_map[$size])) { list($width, $height) = $size_map[$size]; } else { $width = 600; $height = 600; } return 'https://picsum.photos/' . $width . '/' . $height; } } if (!function_exists('pure_minify_css')) { function pure_minify_css($css) { $css = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $css); $css = str_replace(["\r\n", "\r", "\n", "\t", ' ', ' ', ' '], '', $css); $css = str_replace([' {', '{ '], '{', $css); $css = str_replace([' }', '} '], '}', $css); $css = str_replace([' ;', '; '], ';', $css); $css = str_replace([' :', ': '], ':', $css); $css = str_replace([', ', ', '], ',', $css); return trim($css); } } if (!function_exists('pure_minify_js')) { function pure_minify_js($js) { $js = preg_replace('#\/\/[^\n]*#', '', $js); $js = preg_replace('#\/\*.*?\*\/#s', '', $js); $js = preg_replace('/\s+/', ' ', $js); $js = str_replace([' {', '{ '], '{', $js); $js = str_replace([' }', '} '], '}', $js); $js = str_replace([' (', '( '], '(', $js); $js = str_replace([' )', ') '], ')', $js); $js = str_replace([' ;', '; '], ';', $js); return trim($js); } } if (!function_exists('pure_truncate')) { function pure_truncate($text, $length = 150) { $text = wp_strip_all_tags($text); if (mb_strlen($text, 'UTF-8') <= $length) { return $text; } $text = mb_substr($text, 0, $length, 'UTF-8'); $text = preg_replace('/\s+\S*$/', '', $text); return $text . '…'; } } if (!function_exists('pure_get_price_html')) { function pure_get_price_html($product) { if (!$product || !is_object($product)) { return ''; } $regular_price = $product->get_regular_price(); $sale_price = $product->get_sale_price(); $price = $product->get_price(); if (!$price && '0' !== $price) { return ''; } $output = ''; if ($product->is_type('variable')) { $min_price = $product->get_variation_price('min', true); $max_price = $product->get_variation_price('max', true); if ($min_price === $max_price) { $output .= '' . wc_price($min_price) . ''; } else { $output .= '' . wc_price($min_price) . ' - ' . wc_price($max_price) . ''; } } elseif ($sale_price && $regular_price && $sale_price < $regular_price) { $output .= '' . wc_price($regular_price) . ''; $output .= '' . wc_price($sale_price) . ''; $discount = round(100 - ($sale_price / $regular_price * 100)); $output .= '-' . $discount . '%'; } else { $output .= '' . wc_price($price) . ''; } $output .= ''; return $output; } } if (!function_exists('pure_get_product_badges')) { function pure_get_product_badges($product) { if (!$product || !is_object($product)) { return ''; } $badges = []; $regular_price = $product->get_regular_price(); $sale_price = $product->get_sale_price(); if ($sale_price && $regular_price && $sale_price < $regular_price) { $discount = round(100 - ($sale_price / $regular_price * 100)); $badges[] = '-' . $discount . '%'; } $created = strtotime($product->get_date_created()); $days_new = apply_filters('pure_product_new_days', 30); if ($created && (time() - $created) < ($days_new * DAY_IN_SECONDS)) { $badges[] = '' . esc_html__('New', 'pure-theme') . ''; } if ($product->is_featured()) { $badges[] = '' . esc_html__('Hot', 'pure-theme') . ''; } $stock = $product->get_stock_quantity(); if ($stock !== null && $stock > 0 && $stock <= 5) { $badges[] = '' . esc_html__('Limited', 'pure-theme') . ''; } if (empty($badges)) { return ''; } return '
' . implode('', $badges) . '
'; } } if (!function_exists('pure_countdown_timer')) { function pure_countdown_timer($end_date) { if (empty($end_date)) { return ''; } $timestamp = is_numeric($end_date) ? intval($end_date) : strtotime($end_date); if ($timestamp <= time()) { return ''; } $output = '
'; $output .= '
00' . esc_html__('Days', 'pure-theme') . '
'; $output .= ':'; $output .= '
00' . esc_html__('Hours', 'pure-theme') . '
'; $output .= ':'; $output .= '
00' . esc_html__('Mins', 'pure-theme') . '
'; $output .= ':'; $output .= '
00' . esc_html__('Secs', 'pure-theme') . '
'; $output .= '
'; return $output; } } if (!function_exists('pure_is_elementor_active')) { function pure_is_elementor_active() { return did_action('elementor/loaded') || class_exists('\Elementor\Plugin'); } } if (!function_exists('pure_is_dokan_active')) { function pure_is_dokan_active() { return class_exists('WeDevs_Dokan'); } } if (!function_exists('pure_is_wcfm_active')) { function pure_is_wcfm_active() { return class_exists('WCFM'); } } if (!function_exists('pure_is_multivendorx_active')) { function pure_is_multivendorx_active() { return class_exists('MVX'); } } if (!function_exists('pure_get_pexels_images')) { function pure_get_pexels_images($query = 'product', $per_page = 10) { $api_key = 'dWm4l4lSXnsvKeAhJZGAZE6cMclZbC90xytQfRh52ORAZwDuX3o0wR0u'; $cache_key = 'pure_pexels_' . md5($query . '_' . $per_page); $cached = get_transient($cache_key); if ($cached !== false) { return $cached; } $url = add_query_arg([ 'query' => urlencode($query), 'per_page' => intval($per_page), ], 'https://api.pexels.com/v1/search'); $response = wp_remote_get($url, [ 'headers' => [ 'Authorization' => $api_key, ], 'timeout' => 15, ]); if (is_wp_error($response)) { return []; } $body = wp_remote_retrieve_body($response); $data = json_decode($body, true); if (empty($data['photos'])) { return []; } $images = []; foreach ($data['photos'] as $photo) { $images[] = [ 'id' => $photo['id'], 'url' => $photo['src']['large'], 'thumb' => $photo['src']['medium'], 'alt' => $photo['alt'] ?? $query, 'photographer' => $photo['photographer'], 'photographer_url' => $photo['photographer_url'], 'width' => $photo['width'], 'height' => $photo['height'], 'source' => 'pexels', ]; } set_transient($cache_key, $images, HOUR_IN_SECONDS * 6); return $images; } } if (!function_exists('pure_get_pixabay_images')) { function pure_get_pixabay_images($query = 'product', $per_page = 10) { $api_key = '56587750-bbc14e22278df58b47f5cdd94'; $cache_key = 'pure_pixabay_' . md5($query . '_' . $per_page); $cached = get_transient($cache_key); if ($cached !== false) { return $cached; } $url = add_query_arg([ 'key' => $api_key, 'q' => urlencode($query), 'per_page' => intval($per_page), 'image_type'=> 'photo', 'safesearch'=> 'true', ], 'https://pixabay.com/api/'); $response = wp_remote_get($url, [ 'timeout' => 15, ]); if (is_wp_error($response)) { return []; } $body = wp_remote_retrieve_body($response); $data = json_decode($body, true); if (empty($data['hits'])) { return []; } $images = []; foreach ($data['hits'] as $hit) { $images[] = [ 'id' => $hit['id'], 'url' => $hit['largeImageURL'], 'thumb' => $hit['webformatURL'], 'alt' => $hit['tags'] ?? $query, 'photographer' => $hit['user'], 'photographer_url' => 'https://pixabay.com/users/' . $hit['user'] . '-' . $hit['user_id'] . '/', 'width' => $hit['imageWidth'], 'height' => $hit['imageHeight'], 'likes' => $hit['likes'], 'downloads' => $hit['downloads'], 'source' => 'pixabay', ]; } set_transient($cache_key, $images, HOUR_IN_SECONDS * 6); return $images; } } class Pure_Theme { private static $_instance = null; private $_options = []; private $_vendor_data = null; private $_theme_defaults = [ 'primary_color' => '#2563eb', 'secondary_color' => '#7c3aed', 'accent_color' => '#f59e0b', 'header_layout' => 'v1', 'sticky_header' => true, 'transparent_header' => false, 'dark_mode' => 'auto', 'default_sidebar_layout' => 'right-sidebar', 'shop_sidebar_layout' => 'left-sidebar', 'product_sidebar_layout' => 'no-sidebar', 'blog_sidebar_layout' => 'right-sidebar', 'page_sidebar_layout' => 'no-sidebar', 'product_columns' => 4, 'product_per_page' => 12, 'shop_banner' => '', 'shop_banner_link' => '', 'ajax_search' => true, 'quick_view' => true, 'wishlist' => true, 'compare' => true, 'sticky_cart' => true, 'infinite_scroll' => false, 'load_more' => true, 'lazy_loading' => true, 'preloader' => false, 'back_to_top' => true, 'typography_font_family' => 'Inter', 'typography_base_size' => 16, 'typography_heading_font'=> 'Inter', 'container_width' => 1320, 'border_radius' => 8, 'sale_badge_bg' => '#ef4444', 'new_badge_bg' => '#10b981', 'hot_badge_bg' => '#f59e0b', 'limited_badge_bg' => '#8b5cf6', 'header_top_bar' => true, 'header_search' => true, 'header_account' => true, 'header_wishlist' => true, 'header_cart' => true, 'header_compare' => true, 'mobile_menu_style' => 'off-canvas', 'footer_layout' => 'v1', 'footer_columns' => 5, 'footer_copyright' => '', 'footer_payment_icons' => true, 'performance_minify_css' => false, 'performance_minify_js' => false, 'performance_defer_js' => true, 'performance_webp' => true, 'skin' => 'default', ]; public static function get_instance() { if (is_null(self::$_instance)) { self::$_instance = new self(); } return self::$_instance; } private function __construct() { $this->_init_options(); $this->_init_hooks(); } private function _init_options() { $saved = get_option('pure_theme_options', []); $this->_options = wp_parse_args($saved, $this->_theme_defaults); $this->_options = apply_filters('pure_theme_options', $this->_options); } private function _init_hooks() { add_action('init', [$this, 'init']); add_action('wp_head', [$this, 'output_head_scripts'], 5); add_filter('pure_get_option', [$this, 'filter_option'], 10, 2); add_action('customize_save_after', [$this, 'refresh_options']); add_action('update_option_pure_theme_options', [$this, 'refresh_options']); } public function __clone() { _doing_it_wrong(__FUNCTION__, esc_html__('Singleton class cannot be cloned.', 'pure-theme'), '1.0.0'); } public function __wakeup() { _doing_it_wrong(__FUNCTION__, esc_html__('Singleton class cannot be unserialized.', 'pure-theme'), '1.0.0'); } public function init() { $this->_options = apply_filters('pure_theme_options_refreshed', $this->_options); } public function refresh_options() { $this->_init_options(); } public function get_option($key, $default = null) { if (isset($this->_options[$key])) { return apply_filters('pure_theme_option_' . $key, $this->_options[$key]); } return $default; } public function set_option($key, $value) { $this->_options[$key] = $value; update_option('pure_theme_options', $this->_options); } public function get_all_options() { return $this->_options; } public function filter_option($value, $key) { return $this->get_option($key, $value); } public function get_dark_mode_preference() { $mode = $this->get_option('dark_mode', 'auto'); if (isset($_COOKIE['pure_dark_mode'])) { $cookie = sanitize_text_field($_COOKIE['pure_dark_mode']); if (in_array($cookie, ['dark', 'light'], true)) { return $cookie; } } if ($mode === 'dark') { return 'dark'; } if ($mode === 'light') { return 'light'; } return 'light'; } public function handle_dark_mode_toggle() { $current = $this->get_dark_mode_preference(); $new = ($current === 'dark') ? 'light' : 'dark'; setcookie('pure_dark_mode', $new, time() + YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN, is_ssl(), true); return $new; } public function get_vendor_data($vendor_id) { if (!$vendor_id) { return null; } if (isset($this->_vendor_data[$vendor_id])) { return $this->_vendor_data[$vendor_id]; } $vendor = get_userdata($vendor_id); if (!$vendor) { return null; } $data = [ 'id' => $vendor_id, 'name' => $vendor->display_name, 'slug' => $vendor->user_nicename, 'description' => get_user_meta($vendor_id, 'description', true), 'avatar' => get_avatar_url($vendor_id, ['size' => 200]), 'banner' => get_user_meta($vendor_id, 'pure_vendor_banner', true), 'logo' => get_user_meta($vendor_id, 'pure_vendor_logo', true), 'email' => $vendor->user_email, 'website' => $vendor->user_url, 'phone' => get_user_meta($vendor_id, 'billing_phone', true), 'address' => get_user_meta($vendor_id, 'billing_address_1', true), 'city' => get_user_meta($vendor_id, 'billing_city', true), 'state' => get_user_meta($vendor_id, 'billing_state', true), 'country' => get_user_meta($vendor_id, 'billing_country', true), 'postcode' => get_user_meta($vendor_id, 'billing_postcode', true), 'rating' => 0, 'rating_count'=> 0, 'joined' => $vendor->user_registered, 'social' => [ 'facebook' => get_user_meta($vendor_id, 'pure_vendor_facebook', true), 'twitter' => get_user_meta($vendor_id, 'pure_vendor_twitter', true), 'instagram' => get_user_meta($vendor_id, 'pure_vendor_instagram', true), 'youtube' => get_user_meta($vendor_id, 'pure_vendor_youtube', true), 'linkedin' => get_user_meta($vendor_id, 'pure_vendor_linkedin', true), ], ]; if (function_exists('dokan_is_seller_enabled') && dokan_is_seller_enabled($vendor_id)) { $dokan_vendor = dokan()->vendor->get($vendor_id); if ($dokan_vendor) { $data['store_name'] = $dokan_vendor->get_shop_name(); $data['store_url'] = $dokan_vendor->get_shop_url(); $data['banner'] = $data['banner'] ?: $dokan_vendor->get_banner(); $data['logo'] = $data['logo'] ?: $dokan_vendor->get_avatar(); $data['rating'] = $dokan_vendor->get_rating()['rating'] ?? 0; $data['rating_count'] = $dokan_vendor->get_rating()['count'] ?? 0; $data['social'] = $dokan_vendor->get_social_profiles(); } } if (function_exists('get_wcfm_vendor_store_name')) { $store_name = get_user_meta($vendor_id, 'wcfmmp_profile_settings', true); if ($store_name && isset($store_name['store_name'])) { $data['store_name'] = $store_name['store_name']; $data['store_url'] = function_exists('wcfmmp_get_store_url') ? wcfmmp_get_store_url($vendor_id) : ''; $data['banner'] = $data['banner'] ?: (isset($store_name['banner']) ? $store_name['banner'] : ''); $data['logo'] = $data['logo'] ?: (isset($store_name['gravatar']) ? $store_name['gravatar'] : ''); } } if (function_exists('get_mvx_vendor')) { $mvx_vendor = get_mvx_vendor($vendor_id); if ($mvx_vendor) { $data['store_name'] = $mvx_vendor->page_title; $data['store_url'] = $mvx_vendor->get_permalink(); $data['banner'] = $data['banner'] ?: $mvx_vendor->get_image('banner'); $data['logo'] = $data['logo'] ?: $mvx_vendor->get_image(); } } $this->_vendor_data[$vendor_id] = apply_filters('pure_vendor_data', $data, $vendor_id); return $this->_vendor_data[$vendor_id]; } public function get_followers_count($vendor_id) { $count = get_user_meta($vendor_id, 'pure_followers_count', true); return $count ? intval($count) : 0; } public function is_following($vendor_id) { $user_id = get_current_user_id(); if (!$user_id) { return false; } $following = get_user_meta($user_id, 'pure_following_vendors', true); if (!is_array($following)) { $following = []; } return in_array($vendor_id, $following); } public function toggle_follow($vendor_id) { $user_id = get_current_user_id(); if (!$user_id) { return ['error' => esc_html__('You must be logged in to follow vendors.', 'pure-theme')]; } $following = get_user_meta($user_id, 'pure_following_vendors', true); if (!is_array($following)) { $following = []; } if (in_array($vendor_id, $following)) { $following = array_diff($following, [$vendor_id]); $is_following = false; $this->decrease_followers_count($vendor_id); } else { $following[] = $vendor_id; $is_following = true; $this->increase_followers_count($vendor_id); } update_user_meta($user_id, 'pure_following_vendors', array_values($following)); return [ 'success' => true, 'is_following' => $is_following, 'count' => $this->get_followers_count($vendor_id), 'message' => $is_following ? esc_html__('You are now following this vendor.', 'pure-theme') : esc_html__('You have unfollowed this vendor.', 'pure-theme'), ]; } private function increase_followers_count($vendor_id) { $count = intval(get_user_meta($vendor_id, 'pure_followers_count', true)); update_user_meta($vendor_id, 'pure_followers_count', $count + 1); } private function decrease_followers_count($vendor_id) { $count = intval(get_user_meta($vendor_id, 'pure_followers_count', true)); $count = max(0, $count - 1); update_user_meta($vendor_id, 'pure_followers_count', $count); } public function get_wishlist_items() { if (isset($_COOKIE['pure_wishlist'])) { $items = json_decode(stripslashes($_COOKIE['pure_wishlist']), true); if (is_array($items)) { return array_map('intval', $items); } } $user_id = get_current_user_id(); if ($user_id) { $items = get_user_meta($user_id, 'pure_wishlist', true); if (is_array($items)) { return array_map('intval', $items); } } return []; } public function add_to_wishlist($product_id) { $items = $this->get_wishlist_items(); if (!in_array($product_id, $items)) { $items[] = $product_id; } $this->save_wishlist($items); return [ 'success' => true, 'count' => count($items), 'message' => esc_html__('Product added to wishlist.', 'pure-theme'), ]; } public function remove_from_wishlist($product_id) { $items = $this->get_wishlist_items(); $items = array_diff($items, [$product_id]); $this->save_wishlist(array_values($items)); return [ 'success' => true, 'count' => count($items), 'message' => esc_html__('Product removed from wishlist.', 'pure-theme'), ]; } public function is_in_wishlist($product_id) { return in_array($product_id, $this->get_wishlist_items()); } private function save_wishlist($items) { $user_id = get_current_user_id(); if ($user_id) { update_user_meta($user_id, 'pure_wishlist', $items); } $json = wp_json_encode($items); setcookie('pure_wishlist', $json, time() + YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN, is_ssl(), false); } public function get_compare_items() { if (isset($_COOKIE['pure_compare'])) { $items = json_decode(stripslashes($_COOKIE['pure_compare']), true); if (is_array($items)) { return array_map('intval', $items); } } return []; } public function add_to_compare($product_id) { $items = $this->get_compare_items(); if (!in_array($product_id, $items) && count($items) < 4) { $items[] = $product_id; } $this->save_compare($items); return [ 'success' => true, 'count' => count($items), 'message' => esc_html__('Product added to compare.', 'pure-theme'), ]; } public function remove_from_compare($product_id) { $items = $this->get_compare_items(); $items = array_diff($items, [$product_id]); $this->save_compare(array_values($items)); return [ 'success' => true, 'count' => count($items), 'message' => esc_html__('Product removed from compare.', 'pure-theme'), ]; } public function is_in_compare($product_id) { return in_array($product_id, $this->get_compare_items()); } private function save_compare($items) { $json = wp_json_encode($items); setcookie('pure_compare', $json, time() + DAY_IN_SECONDS * 30, COOKIEPATH, COOKIE_DOMAIN, is_ssl(), false); } public function output_head_scripts() { $inline_css = ''; $primary = $this->get_option('primary_color', '#2563eb'); $secondary = $this->get_option('secondary_color', '#7c3aed'); $accent = $this->get_option('accent_color', '#f59e0b'); $font_family = $this->get_option('typography_font_family', 'Inter'); $base_size = $this->get_option('typography_base_size', 16); $heading_font = $this->get_option('typography_heading_font', 'Inter'); $container_width = $this->get_option('container_width', 1320); $border_radius = $this->get_option('border_radius', 8); $inline_css .= ':root{'; $inline_css .= '--pure-primary:' . esc_attr($primary) . ';'; $inline_css .= '--pure-primary-dark:' . esc_attr(self::adjust_color($primary, -20)) . ';'; $inline_css .= '--pure-primary-light:' . esc_attr(self::adjust_color($primary, 30)) . ';'; $inline_css .= '--pure-secondary:' . esc_attr($secondary) . ';'; $inline_css .= '--pure-accent:' . esc_attr($accent) . ';'; $inline_css .= '--pure-font-sans:"' . esc_attr($font_family) . '",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;'; $inline_css .= '--pure-font-size:' . intval($base_size) . 'px;'; $inline_css .= '--pure-container:' . intval($container_width) . 'px;'; $inline_css .= '--pure-radius: ' . intval($border_radius) / 16 . 'rem;'; $inline_css .= '--pure-radius-md: ' . (intval($border_radius) + 4) / 16 . 'rem;'; $inline_css .= '}'; echo '' . "\n"; echo '' . "\n"; } public static function adjust_color($hex, $percent) { $hex = ltrim($hex, '#'); if (strlen($hex) === 3) { $hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2]; } $r = hexdec(substr($hex, 0, 2)); $g = hexdec(substr($hex, 2, 2)); $b = hexdec(substr($hex, 4, 2)); $r = max(0, min(255, $r + $percent)); $g = max(0, min(255, $g + $percent)); $b = max(0, min(255, $b + $percent)); return sprintf('#%02x%02x%02x', $r, $g, $b); } public static function maybe_init() { return self::get_instance(); } } function Pure_Theme() { return Pure_Theme::get_instance(); } Pure_Theme::get_instance();