WooCommerce 产品比较工具

功能强大且用户友好的 WooCommerce 产品比较工具。

<?php
/**
* Plugin Name: BDFG WooCommerce Compare
* Plugin URI: https://beiduofengou.net/2024/02/15/bdfg-woocommerce-compare/
* Description: A professional and user-friendly WooCommerce product comparison tool developed by beiduofengou
* Version: 2.3.1
* Author: beiduofengou
* Author URI: https://beiduofengou.net
* Text Domain: bdfg-woo-compare
* Domain Path: /languages
* Requires at least: 5.8
* Requires PHP: 7.4
* WC requires at least: 5.0
* WC tested up to: 8.2
* License: GPL v2 or later
*
* @package BDFG_Woo_Compare
* @author beiduofengou <[email protected]>
* @link https://beiduofengou.net
* @since 1.0.0
*/

if (!defined('ABSPATH')) {
exit('Direct access not allowed.');
}

if (!class_exists('BDFG_Woo_Compare')) {

class BDFG_Woo_Compare {

/**
* 插件实例
*
* @var BDFG_Woo_Compare
*/
private static $instance = null;

/**
* 插件版本
*
* @var string
*/
private $version = '2.3.1';

/**
* 系统要求
*
* @var array
*/
private $requirements = array(
'php' => '7.4',
'wordpress' => '5.8',
'woocommerce' => '5.0'
);

/**
* 获取插件实例
*
* @return BDFG_Woo_Compare
*/
public static function get_instance() {
if (null === self::$instance) {
self::$instance = new self();
}
return self::$instance;
}

/**
* 构造函数
*/
private function __construct() {
$this->define_constants();
$this->init_hooks();

if ($this->check_requirements()) {
$this->includes();
$this->init();

// 添加插件设置链接
add_filter('plugin_action_links_' . plugin_basename(__FILE__), array($this, 'add_plugin_links'));

// 添加插件更新检查
add_action('admin_init', array($this, 'check_version'));
}
}

/**
* 定义常量
*/
private function define_constants() {
// 版本信息
define('BDFG_COMPARE_VERSION', $this->version);
define('BDFG_COMPARE_DB_VERSION', '1.0.3');

// 路径信息
define('BDFG_COMPARE_FILE', __FILE__);
define('BDFG_COMPARE_PATH', plugin_dir_path(__FILE__));
define('BDFG_COMPARE_URL', plugin_dir_url(__FILE__));
define('BDFG_COMPARE_ASSETS_URL', BDFG_COMPARE_URL . 'assets/');
define('BDFG_COMPARE_TEMPLATES_PATH', BDFG_COMPARE_PATH . 'templates/');

// 其他配置
define('BDFG_COMPARE_MAX_PRODUCTS', 6);
define('BDFG_COMPARE_COOKIE_NAME', 'bdfg_compare_list');
define('BDFG_COMPARE_SESSION_KEY', 'bdfg_compare_session');
}

/**
* 初始化钩子
*/
private function init_hooks() {
// 加载文本域
add_action('init', array($this, 'load_plugin_textdomain'));

// 注册激活和停用钩子
register_activation_hook(__FILE__, array($this, 'activate'));
register_deactivation_hook(__FILE__, array($this, 'deactivate'));

// 添加定时清理任务
add_action('bdfg_daily_cleanup', array($this, 'cleanup_old_data'));
}

/**
* 检查系统要求
*
* @return bool
*/
private function check_requirements() {
// PHP版本检查
if (version_compare(PHP_VERSION, $this->requirements['php'], '<')) {
add_action('admin_notices', array($this, 'php_version_notice'));
return false;
}

// WordPress版本检查
if (version_compare(get_bloginfo('version'), $this->requirements['wordpress'], '<')) {
add_action('admin_notices', array($this, 'wordpress_version_notice'));
return false;
}

// WooCommerce依赖检查
if (!class_exists('WooCommerce')) {
add_action('admin_notices', array($this, 'woocommerce_missing_notice'));
return false;
}

if (defined('WC_VERSION') && version_compare(WC_VERSION, $this->requirements['woocommerce'], '<')) {
add_action('admin_notices', array($this, 'woocommerce_version_notice'));
return false;
}

return true;
}

/**
* 包含必要的文件
*/
private function includes() {
// 工具类
require_once BDFG_COMPARE_PATH . 'includes/class-bdfg-utils.php';

// 核心功能
require_once BDFG_COMPARE_PATH . 'includes/class-bdfg-core-functions.php';
require_once BDFG_COMPARE_PATH . 'includes/class-bdfg-template-loader.php';
require_once BDFG_COMPARE_PATH . 'includes/class-bdfg-ajax-handler.php';

// Session处理
require_once BDFG_COMPARE_PATH . 'includes/class-bdfg-session.php';

// 前端功能
if (!is_admin() || wp_doing_ajax()) {
require_once BDFG_COMPARE_PATH . 'public/class-bdfg-public.php';
}

// 管理员功能
if (is_admin()) {
require_once BDFG_COMPARE_PATH . 'admin/class-bdfg-admin.php';
require_once BDFG_COMPARE_PATH . 'admin/class-bdfg-settings.php';
}

// 扩展功能
require_once BDFG_COMPARE_PATH . 'includes/class-bdfg-compare-extended.php';
}

/**
* 初始化插件
*/
private function init() {
// 初始化会话
BDFG_Session::init();

// 添加比较按钮
$button_position = get_option('bdfg_compare_button_position', 'woocommerce_after_add_to_cart_button');
add_action($button_position, array($this, 'add_compare_button'), 20);

// 注册小工具
add_action('widgets_init', array($this, 'register_widgets'));

// 注册短代码
add_shortcode('bdfg_compare', array($this, 'compare_shortcode'));
}

/**
* 添加设置链接
*/
public function add_plugin_links($links) {
$plugin_links = array(
'<a href="' . admin_url('admin.php?page=bdfg-compare-settings') . '">' . __('Settings', 'bdfg-woo-compare') . '</a>',
'<a href="https://beiduofengou.net/docs/bdfg-woo-compare" target="_blank">' . __('Documentation', 'bdfg-woo-compare') . '</a>'
);
return array_merge($plugin_links, $links);
}

/**
* 加载语言文件
*/
public function load_plugin_textdomain() {
load_plugin_textdomain(
'bdfg-woo-compare',
false,
dirname(plugin_basename(__FILE__)) . '/languages/'
);
}

/**
* 添加比较按钮
*/
public function add_compare_button() {
global $product;
if (!$product) return;

$button_text = get_option('bdfg_compare_button_text', __('Compare', 'bdfg-woo-compare'));
$button_class = get_option('bdfg_compare_button_class', 'button bdfg-compare-btn');

echo sprintf(
'<button type="button" class="%s" data-product-id="%d" data-nonce="%s">%s</button>',
esc_attr($button_class),
esc_attr($product->get_id()),
wp_create_nonce('bdfg_compare_nonce'),
esc_html($button_text)
);
}

/**
* 比较短代码
*/
public function compare_shortcode($atts) {
$defaults = array(
'products' => '',
'fields' => '',
'show_remove' => 'yes'
);

$atts = shortcode_atts($defaults, $atts, 'bdfg_compare');

ob_start();
include BDFG_COMPARE_TEMPLATES_PATH . 'compare-table.php';
return ob_get_clean();
}

/**
* 插件激活
*/
public static function activate() {
if (!current_user_can('activate_plugins')) {
return;
}

// 创建数据表
self::create_tables();

// 设置默认选项
self::set_default_options();

// 添加定时任务
if (!wp_next_scheduled('bdfg_daily_cleanup')) {
wp_schedule_event(time(), 'daily', 'bdfg_daily_cleanup');
}

// 清理缓存
wp_cache_flush();
}

/**
* 创建数据表
*/
private static function create_tables() {
global $wpdb;

$charset_collate = $wpdb->get_charset_collate();

$sql = "CREATE TABLE IF NOT EXISTS {$wpdb->prefix}bdfg_compare_lists (
id bigint(20) NOT NULL AUTO_INCREMENT,
user_id bigint(20) NOT NULL DEFAULT 0,
name varchar(255) NOT NULL,
products longtext NOT NULL,
created datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
modified datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY user_id (user_id)
) $charset_collate;";

require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
}

/**
* 设置默认选项
*/
private static function set_default_options() {
$default_options = array(
'bdfg_compare_page_id' => 0,
'bdfg_compare_button_position' => 'woocommerce_after_add_to_cart_button',
'bdfg_compare_button_text' => __('Compare', 'bdfg-woo-compare'),
'bdfg_compare_fields' => array('image', 'title', 'price', 'description', 'sku', 'stock', 'weight', 'dimensions'),
'bdfg_compare_max_products' => 4,
'bdfg_compare_enable_share' => 'yes',
'bdfg_compare_enable_pdf' => 'yes',
'bdfg_compare_enable_email' => 'yes'
);

foreach ($default_options as $option => $value) {
if (get_option($option) === false) {
update_option($option, $value);
}
}
}

/**
* 插件停用
*/
public static function deactivate() {
if (!current_user_can('activate_plugins')) {
return;
}

// 清理定时任务
wp_clear_scheduled_hook('bdfg_daily_cleanup');

// 清理临时数据
self::cleanup_temp_data();
}

/**
* 清理临时数据
*/
private static function cleanup_temp_data() {
global $wpdb;

// 清理过期的会话数据
$wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_bdfg_%'");
$wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_timeout_bdfg_%'");

// 清理缓存
wp_cache_flush();
}

/**
* 系统要求通知
*/
public function php_version_notice() {
$message = sprintf(
__('BDFG WooCommerce Compare requires PHP version %s or higher. You are running version %s', 'bdfg-woo-compare'),
$this->requirements['php'],
PHP_VERSION
);
echo '<div class="error"><p>' . esc_html($message) . '</p></div>';
}

public function wordpress_version_notice() {
$message = sprintf(
__('BDFG WooCommerce Compare requires WordPress version %s or higher.', 'bdfg-woo-compare'),
$this->requirements['wordpress']
);
echo '<div class="error"><p>' . esc_html($message) . '</p></div>';
}

public function woocommerce_missing_notice() {
$message = __('BDFG WooCommerce Compare requires WooCommerce to be installed and activated.', 'bdfg-woo-compare');
echo '<div class="error"><p>' . esc_html($message) . '</p></div>';
}

public function woocommerce_version_notice() {
$message = sprintf(
__('BDFG WooCommerce Compare requires WooCommerce version %s or higher.', 'bdfg-woo-compare'),
$this->requirements['woocommerce']
);
echo '<div class="error"><p>' . esc_html($message) . '</p></div>';
}
}

// 初始化插件
add_action('plugins_loaded', array('BDFG_Woo_Compare', 'get_instance'));

// 注册激活和停用钩子
register_activation_hook(__FILE__, array('BDFG_Woo_Compare', 'activate'));
register_deactivation_hook(__FILE__, array('BDFG_Woo_Compare', 'deactivate'));
}

includes/class-bdfg-core-functions.php

相关文章: WordPress 地图定位插件

<?php
/**
* BDFG WooCommerce Compare Core Functions
*
* @package BDFG_Woo_Compare
* @author beiduofengou <[email protected]>
* @version 2.3.1
* @since 1.0.0
* @last_modified 2025-02-15 17:41:43
* @developer beiduofengou
*/

if (!defined('ABSPATH')) {
exit('Direct access not allowed.');
}

class BDFG_Core_Functions {

/**
* 单例实例
*
* @var BDFG_Core_Functions
*/
private static $instance = null;

/**
* 缓存相关变量
*/
private $compare_table_cache = array();
private $product_data_cache = array();
private $cache_expiry = 3600; // 缓存过期时间(秒)

/**
* 获取实例
*/
public static function get_instance() {
if (null === self::$instance) {
self::$instance = new self();
}
return self::$instance;
}

/**
* 构造函数
*/
private function __construct() {
// 初始化缓存
add_action('init', array($this, 'init_cache'));

// 监听产品更新事件
$this->init_product_hooks();

// 注册AJAX处理器
$this->register_ajax_handlers();
}

/**
* 初始化产品相关钩子
*/
private function init_product_hooks() {
// 产品数据更新时清理缓存
add_action('woocommerce_update_product', array($this, 'clear_product_cache'));
add_action('woocommerce_delete_product', array($this, 'clear_product_cache'));
add_action('woocommerce_trash_product', array($this, 'clear_product_cache'));

// 产品库存变化时更新缓存
add_action('woocommerce_product_set_stock', array($this, 'clear_product_cache'));
add_action('woocommerce_variation_set_stock', array($this, 'clear_product_cache'));
}

/**
* 注册AJAX处理器
*/
private function register_ajax_handlers() {
add_action('wp_ajax_bdfg_get_compare_data', array($this, 'ajax_get_compare_data'));
add_action('wp_ajax_nopriv_bdfg_get_compare_data', array($this, 'ajax_get_compare_data'));

add_action('wp_ajax_bdfg_update_field_visibility', array($this, 'ajax_update_field_visibility'));
}

/**
* 初始化缓存
*/
public function init_cache() {
$this->compare_table_cache = get_transient('bdfg_compare_table_cache');
if (false === $this->compare_table_cache) {
$this->compare_table_cache = array();
}
}

/**
* 获取比较字段
*
* @return array 比较字段配置
*/
public function get_compare_fields() {
$default_fields = array(
'image' => array(
'label' => __('Product Image', 'bdfg-woo-compare'),
'callback' => array($this, 'get_product_image'),
'priority' => 10,
'visible' => true
),
'title' => array(
'label' => __('Product Name', 'bdfg-woo-compare'),
'callback' => array($this, 'get_product_title'),
'priority' => 20,
'visible' => true
),
'price' => array(
'label' => __('Price', 'bdfg-woo-compare'),
'callback' => array($this, 'get_product_price'),
'priority' => 30,
'visible' => true
),
'description' => array(
'label' => __('Description', 'bdfg-woo-compare'),
'callback' => array($this, 'get_product_description'),
'priority' => 40,
'visible' => true
),
'sku' => array(
'label' => __('SKU', 'bdfg-woo-compare'),
'callback' => array($this, 'get_product_sku'),
'priority' => 50,
'visible' => true
),
'stock' => array(
'label' => __('Stock Status', 'bdfg-woo-compare'),
'callback' => array($this, 'get_stock_status'),
'priority' => 60,
'visible' => true
),
'weight' => array(
'label' => __('Weight', 'bdfg-woo-compare'),
'callback' => array($this, 'get_product_weight'),
'priority' => 70,
'visible' => true
),
'dimensions' => array(
'label' => __('Dimensions', 'bdfg-woo-compare'),
'callback' => array($this, 'get_product_dimensions'),
'priority' => 80,
'visible' => true
)
);

return apply_filters('bdfg_compare_fields', $default_fields);
}

/**
* 获取产品数据
*
* @param int $product_id
* @return array|bool 产品数据或false
*/
public function get_product_data($product_id) {
// 检查缓存
if (isset($this->product_data_cache[$product_id])) {
return $this->product_data_cache[$product_id];
}

$cached_data = get_transient('bdfg_product_' . $product_id);
if (false !== $cached_data) {
$this->product_data_cache[$product_id] = $cached_data;
return $cached_data;
}

$product = wc_get_product($product_id);
if (!$product) {
return false;
}

// 收集产品数据
$data = array(
'id' => $product_id,
'title' => $product->get_name(),
'url' => get_permalink($product_id),
'image' => $this->get_product_image($product),
'price' => array(
'regular' => $product->get_regular_price(),
'sale' => $product->get_sale_price(),
'html' => $product->get_price_html()
),
'sku' => $product->get_sku(),
'stock' => array(
'status' => $product->get_stock_status(),
'quantity' => $product->get_stock_quantity(),
'html' => $this->get_stock_status($product)
),
'description' => array(
'short' => $product->get_short_description(),
'full' => $product->get_description()
),
'dimensions' => array(
'length' => $product->get_length(),
'width' => $product->get_width(),
'height' => $product->get_height(),
'formatted' => $this->get_product_dimensions($product)
),
'weight' => array(
'value' => $product->get_weight(),
'formatted' => $this->get_product_weight($product)
),
'attributes' => $this->get_product_attributes($product),
'categories' => $this->get_product_categories($product),
'tags' => $this->get_product_tags($product),
'meta' => array(
'updated' => current_time('mysql'),
'currency' => get_woocommerce_currency()
)
);

// 缓存数据
set_transient('bdfg_product_' . $product_id, $data, $this->cache_expiry);
$this->product_data_cache[$product_id] = $data;

return $data;
}

/**
* 获取产品图片
*/
public function get_product_image($product) {
$image_id = $product->get_image_id();
if (!$image_id) {
return wc_placeholder_img();
}

return wp_get_attachment_image(
$image_id,
'woocommerce_thumbnail',
false,
array(
'class' => 'bdfg-compare-product-image',
'alt' => $product->get_name()
)
);
}

/**
* 获取库存状态
*/
public function get_stock_status($product) {
$availability = $product->get_availability();
$stock_html = '<div class="bdfg-stock-status stock ' . esc_attr($availability['class']) . '">';
$stock_html .= esc_html($availability['availability']);

if ($product->managing_stock()) {
$stock_html .= ' (' . $product->get_stock_quantity() . ')';
}

$stock_html .= '</div>';

return $stock_html;
}

/**
* 获取产品尺寸
*/
public function get_product_dimensions($product) {
if (!$product->has_dimensions()) {
return '-';
}

return wc_format_dimensions($product->get_dimensions(false));
}

/**
* 获取产品重量
*/
public function get_product_weight($product) {
$weight = $product->get_weight();
if (!$weight) {
return '-';
}

return wc_format_weight($weight);
}

/**
* 获取产品属性
*/
private function get_product_attributes($product) {
$attributes = array();

if ($product->get_type() == 'variation') {
$variation_attributes = $product->get_variation_attributes();
foreach ($variation_attributes as $attribute_name => $attribute_value) {
$attributes[] = array(
'name' => wc_attribute_label(str_replace('attribute_', '', $attribute_name)),
'value' => $attribute_value
);
}
} else {
foreach ($product->get_attributes() as $attribute) {
if ($attribute->is_taxonomy()) {
$terms = wp_get_post_terms($product->get_id(), $attribute->get_name(), 'all');
$attribute_value = array();
foreach ($terms as $term) {
$attribute_value[] = $term->name;
}
$attributes[] = array(
'name' => wc_attribute_label($attribute->get_name()),
'value' => implode(', ', $attribute_value)
);
} else {
$attributes[] = array(
'name' => $attribute->get_name(),
'value' => $attribute->get_options()
);
}
}
}

return $attributes;
}

/**
* 获取产品分类
*/
private function get_product_categories($product) {
$categories = array();
$terms = get_the_terms($product->get_id(), 'product_cat');

if ($terms && !is_wp_error($terms)) {
foreach ($terms as $term) {
$categories[] = array(
'id' => $term->term_id,
'name' => $term->name,
'slug' => $term->slug,
'url' => get_term_link($term)
);
}
}

return $categories;
}

/**
* 清理产品缓存
*/
public function clear_product_cache($product_id) {
delete_transient('bdfg_product_' . $product_id);
unset($this->product_data_cache[$product_id]);
$this->clear_table_cache();
}

/**
* AJAX处理器 - 获取比较数据
*/
public function ajax_get_compare_data() {
check_ajax_referer('bdfg_compare_nonce', 'nonce');

$product_ids = isset($_POST['products']) ? array_map('absint', $_POST['products']) : array();

if (empty($product_ids)) {
wp_send_json_error(array(
'message' => __('No products selected', 'bdfg-woo-compare')
));
}

$data = array();
foreach ($product_ids as $product_id) {
$product_data = $this->get_product_data($product_id);
if ($product_data) {
$data[] = $product_data;
}
}

wp_send_json_success(array(
'products' => $data,
'fields' => $this->get_compare_fields()
));
}

/**
* 清理所有缓存
*/
public function clear_all_cache() {
global $wpdb;

// 清理产品缓存
$wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_bdfg_product_%'");
$wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_timeout_bdfg_product_%'");

// 清理表格缓存
delete_transient('bdfg_compare_table_cache');

// 重置内存缓存
$this->product_data_cache = array();
$this->compare_table_cache = array();
}
}

includes/class-bdfg-compare-extended.php

<?php
/**
* BDFG WooCommerce Compare Extended Features
* 高级比较功能扩展
*
* @package BDFG_Woo_Compare
* @author beiduofengou <[email protected]>
* @since 2.3.1
*/

if (!defined('ABSPATH')) {
exit('Direct access not allowed.');
}

class BDFG_Compare_Extended {

private static $instance = null;
private $share_expiry = 7; // 分享链接有效期(天)
private $watch_list_limit = 20; // 每个用户可关注的最大商品数

/**
* 获取单例实例
*/
public static function get_instance() {
if (null === self::$instance) {
self::$instance = new self();
}
return self::$instance;
}

/**
* 构造函数 - 初始化钩子和过滤器
*/
private function __construct() {
// 分享功能
add_action('wp_ajax_bdfg_share_compare', array($this, 'generate_share_link'));
add_action('wp_ajax_nopriv_bdfg_share_compare', array($this, 'generate_share_link'));
add_action('template_redirect', array($this, 'handle_shared_compare'));

// 保存功能
add_action('wp_ajax_bdfg_save_compare', array($this, 'save_compare_list'));
add_action('wp_ajax_bdfg_load_saved_compare', array($this, 'load_saved_compare'));

// 商品监控
add_action('woocommerce_product_set_regular_price', array($this, 'check_price_change'), 10, 2);
add_action('woocommerce_product_set_sale_price', array($this, 'check_price_change'), 10, 2);
add_action('wp_ajax_bdfg_watch_product', array($this, 'toggle_product_watch'));

// 高亮差异
add_filter('bdfg_compare_field_value', array($this, 'highlight_differences'), 10, 3);

// 自定义比较属性
add_filter('bdfg_compare_fields', array($this, 'add_custom_attributes'));

// 定期清理过期数据
add_action('bdfg_daily_cleanup', array($this, 'cleanup_expired_data'));
}

/**
* 生成分享链接
*/
public function generate_share_link() {
check_ajax_referer('bdfg_share_nonce', 'nonce');

// 获取比较列表
$session = BDFG_Compare_Session::get_instance();
$products = $session->get_products();

if (empty($products)) {
wp_send_json_error(array(
'message' => __('No products to share', 'bdfg-woo-compare')
));
}

// 生成唯一分享ID
$share_id = wp_generate_uuid4();
$share_data = array(
'products' => $products,
'created' => current_time('mysql'),
'expires' => date('Y-m-d H:i:s', strtotime("+{$this->share_expiry} days"))
);

// 保存分享数据
set_transient("bdfg_share_{$share_id}", $share_data, $this->share_expiry * DAY_IN_SECONDS);

// 生成分享URL
$share_url = add_query_arg(array(
'bdfg-compare' => $share_id,
'utm_source' => 'share',
'utm_medium' => 'compare',
'utm_campaign' => 'product_comparison'
), home_url());

wp_send_json_success(array(
'share_url' => $share_url,
'expires' => human_time_diff(strtotime($share_data['expires']))
));
}

/**
* 处理分享链接访问
*/
public function handle_shared_compare() {
$share_id = isset($_GET['bdfg-compare']) ? sanitize_text_field($_GET['bdfg-compare']) : '';
if (!$share_id) {
return;
}

// 获取分享数据
$share_data = get_transient("bdfg_share_{$share_id}");
if (!$share_data) {
wp_die(__('This comparison link has expired or is invalid.', 'bdfg-woo-compare'), '', array('back_link' => true));
}

// 加载比较页面
$session = BDFG_Compare_Session::get_instance();
$session->set_products($share_data['products']);

wp_redirect(BDFG_Compare_Public::get_compare_page_url());
exit;
}

/**
* 保存比较列表
*/
public function save_compare_list() {
if (!is_user_logged_in()) {
wp_send_json_error(array(
'message' => __('Please login to save comparisons', 'bdfg-woo-compare')
));
}

check_ajax_referer('bdfg_save_nonce', 'nonce');

$name = isset($_POST['name']) ? sanitize_text_field($_POST['name']) : '';
if (empty($name)) {
$name = sprintf(__('Comparison #%s', 'bdfg-woo-compare'), uniqid());
}

// 获取当前比较列表
$session = BDFG_Compare_Session::get_instance();
$products = $session->get_products();

if (empty($products)) {
wp_send_json_error(array(
'message' => __('No products to save', 'bdfg-woo-compare')
));
}

// 保存比较列表
$user_id = get_current_user_id();
$saved_lists = get_user_meta($user_id, 'bdfg_saved_comparisons', true);
if (!is_array($saved_lists)) {
$saved_lists = array();
}

$saved_lists[] = array(
'id' => uniqid('bdfg_'),
'name' => $name,
'products' => $products,
'date' => current_time('mysql'),
'modified' => current_time('mysql')
);

update_user_meta($user_id, 'bdfg_saved_comparisons', $saved_lists);

wp_send_json_success(array(
'message' => __('Comparison saved successfully', 'bdfg-woo-compare'),
'list' => end($saved_lists)
));
}

/**
* 监控商品价格变化
*/
public function check_price_change($product_id, $price) {
$old_price = get_post_meta($product_id, '_price', true);
if ($old_price != $price) {
$watchers = get_post_meta($product_id, 'bdfg_price_watchers', true);
if (!empty($watchers)) {
$this->notify_price_change($product_id, $old_price, $price, $watchers);
}
}
}

/**
* 通知价格变化
*/
private function notify_price_change($product_id, $old_price, $new_price, $watchers) {
$product = wc_get_product($product_id);
if (!$product) {
return;
}

$subject = sprintf(
__('[%s] Price Alert: %s', 'bdfg-woo-compare'),
get_bloginfo('name'),
$product->get_name()
);

$template = 'emails/price-alert.php';
$template_data = array(
'product' => $product,
'old_price' => $old_price,
'new_price' => $new_price,
'product_url' => $product->get_permalink()
);

foreach ($watchers as $user_id) {
$user = get_user_by('id', $user_id);
if (!$user) {
continue;
}

// 使用WooCommerce邮件模板发送通知
WC()->mailer()->send(
$user->user_email,
$subject,
wc_get_template_html($template, $template_data)
);
}
}

/**
* 清理过期数据
*/
public function cleanup_expired_data() {
global $wpdb;

// 清理过期的分享链接
$expired_shares = $wpdb->get_col(
$wpdb->prepare(
"SELECT option_name FROM $wpdb->options
WHERE option_name LIKE %s
AND option_value < %s",
'bdfg_share_%',
current_time('mysql', 1)
)
);

foreach ($expired_shares as $option_name) {
delete_option($option_name);
}

// 清理过期的价格监控
$this->cleanup_watch_lists();
}

// 其他辅助方法...
}

// 初始化扩展功能
BDFG_Compare_Extended::get_instance();

assets/js/bdfg-compare-public.js

相关文章: WooCommerce 客户分析报告插件

/**
* BDFG WooCommerce Compare - Frontend JavaScript
*
* @package BDFG_Woo_Compare
* @author beiduofengou
* @version 2.3.1
*/

(function($) {
'use strict';

var BDFG_Compare = {

init: function() {
this.modal = $('#bdfg-compare-modal');
this.compareBtn = $('.bdfg-compare-btn');
this.compareTable = $('.bdfg-compare-table');
this.noticeTimeout = null;

this.bindEvents();
this.initTooltips();
},

bindEvents: function() {
var self = this;

// 添加到比较列表
$(document).on('click', '.bdfg-compare-btn', function(e) {
e.preventDefault();
self.addToCompare($(this));
});

// 从比较列表中移除
$(document).on('click', '.bdfg-remove-compare', function(e) {
e.preventDefault();
self.removeFromCompare($(this));
});

// 分享比较列表
$(document).on('click', '.bdfg-share-compare', function(e) {
e.preventDefault();
self.shareCompare($(this));
});

// 导出比较列表
$(document).on('click', '.bdfg-export-pdf, .bdfg-export-csv', function(e) {
e.preventDefault();
self.exportCompare($(this));
});

// 保存比较列表
$(document).on('click', '.bdfg-save-compare', function(e) {
e.preventDefault();
self.saveCompare($(this));
});

// 关闭弹窗
$(document).on('click', '.bdfg-modal-close', function() {
self.closeModal();
});

// ESC关闭弹窗
$(document).keyup(function(e) {
if (e.key === "Escape") {
self.closeModal();
}
});
},

addToCompare: function(button) {
var self = this;
var productId = button.data('product-id');

$.ajax({
url: bdfgCompare.ajaxurl,
type: 'POST',
data: {
action: 'bdfg_add_to_compare',
product_id: productId,
nonce: button.data('nonce')
},
beforeSend: function() {
button.addClass('loading');
},
success: function(response) {
if (response.success) {
self.showNotice(response.data.message, 'success');
self.updateCompareCount(response.data.count);
button.addClass('added').text(bdfgCompare.i18n.added);
} else {
self.showNotice(response.data.message, 'error');
}
},
error: function() {
self.showNotice(bdfgCompare.i18n.error, 'error');
},
complete: function() {
button.removeClass('loading');
}
});
},

removeFromCompare: function(button) {
var self = this;
var productId = button.data('product-id');

if (!confirm(bdfgCompare.i18n.removeConfirm)) {
return;
}

$.ajax({
url: bdfgCompare.ajaxurl,
type: 'POST',
data: {
action: 'bdfg_remove_from_compare',
product_id: productId,
nonce: button.data('nonce')
},
beforeSend: function() {
button.addClass('loading');
},
success: function(response) {
if (response.success) {
self.showNotice(response.data.message, 'success');
self.updateCompareCount(response.data.count);
self.updateCompareTable(response.data.html);
} else {
self.showNotice(response.data.message, 'error');
}
},
error: function() {
self.showNotice(bdfgCompare.i18n.error, 'error');
},
complete: function() {
button.removeClass('loading');
}
});
},

shareCompare: function(button) {
var self = this;

$.ajax({
url: bdfgCompare.ajaxurl,
type: 'POST',
data: {
action: 'bdfg_share_compare',
nonce: button.data('nonce')
},
beforeSend: function() {
button.addClass('loading');
},
success: function(response) {
if (response.success) {
self.showShareModal(response.data.share_url);
} else {
self.showNotice(response.data.message, 'error');
}
},
error: function() {
self.showNotice(bdfgCompare.i18n.error, 'error');
},
complete: function() {
button.removeClass('loading');
}
});
},

exportCompare: function(button) {
var format = button.data('format');
var self = this;

$.ajax({
url: bdfgCompare.ajaxurl,
type: 'POST',
data: {
action: 'bdfg_export_compare',
format: format,
nonce: button.data('nonce')
},
beforeSend: function() {
button.addClass('loading');
},
success: function(response) {
if (response.success) {
window.location.href = response.data.file_url;
} else {
self.showNotice(response.data.message, 'error');
}
},
error: function() {
self.showNotice(bdfgCompare.i18n.error, 'error');
},
complete: function() {
button.removeClass('loading');
}
});
},

saveCompare: function(button) {
var self = this;
var name = prompt(bdfgCompare.i18n.savePrompt);

if (name === null) {
return;
}

$.ajax({
url: bdfgCompare.ajaxurl,
type: 'POST',
data: {
action: 'bdfg_save_compare',
name: name,
nonce: button.data('nonce')
},
beforeSend: function() {
button.addClass('loading');
},
success: function(response) {
if (response.success) {
self.showNotice(response.data.message, 'success');
} else {
self.showNotice(response.data.message, 'error');
}
},
error: function() {
self.showNotice(bdfgCompare.i18n.error, 'error');
},
complete: function() {
button.removeClass('loading');
}
});
},

showNotice: function(message, type) {
var self = this;

// 清除之前的通知
if (self.noticeTimeout) {
clearTimeout(self.noticeTimeout);
}

// 移除现有通知
$('.bdfg-notice').remove();

// 创建新通知
var notice = $('<div/>', {
'class': 'bdfg-notice bdfg-notice-' + type,
'html': message
}).appendTo('body');

// 显示动画
setTimeout(function() {
notice.addClass('bdfg-notice-show');
}, 10);

// 3秒后隐藏
self.noticeTimeout = setTimeout(function() {
notice.removeClass('bdfg-notice-show');
setTimeout(function() {
notice.remove();
}, 300);
}, 3000);
},

showShareModal: function(shareUrl) {
var modalContent =
'<div class="bdfg-modal-content">' +
'<span class="bdfg-modal-close">&times;</span>' +
'<h3>' + bdfgCompare.i18n.shareTitle + '</h3>' +
'<div class="bdfg-share-url">' +
'<input type="text" value="' + shareUrl + '" readonly>' +
'<button class="bdfg-copy-url">' + bdfgCompare.i18n.copyUrl + '</button>' +
'</div>' +
'<div class="bdfg-social-share">' +
'<a href="https://www.facebook.com/sharer/sharer.php?u=' + encodeURIComponent(shareUrl) + '" target="_blank" class="bdfg-share-facebook">Facebook</a>' +
'<a href="https://twitter.com/intent/tweet?url=' + encodeURIComponent(shareUrl) + '" target="_blank" class="bdfg-share-twitter">Twitter</a>' +
'</div>' +
'</div>';

this.modal.html(modalContent).show();

// 复制链接功能
$('.bdfg-copy-url').on('click', function() {
var urlInput = $(this).prev('input');
urlInput.select();
document.execCommand('copy');
$(this).text(bdfgCompare.i18n.copied);
});
},

closeModal: function() {
this.modal.hide().empty();
},

updateCompareCount: function(count) {
$('.bdfg-compare-count').text(count);

if (count > 0) {
$('.bdfg-compare-widget').addClass('has-items');
} else {
$('.bdfg-compare-widget').removeClass('has-items');
}
},

updateCompareTable: function(html) {
if (this.compareTable.length) {
this.compareTable.replaceWith(html);
}
},

initTooltips: function() {
$('.bdfg-tooltip').tooltipster({
theme: 'tooltipster-borderless',
delay: 100,
animationDuration: 200
});
}
};

// 初始化
$(document).ready(function() {
BDFG_Compare.init();
});

})(jQuery);

assets/css/bdfg-compare-public.css

/**
* BDFG WooCommerce Compare - Frontend Styles
*
* @package BDFG_Woo_Compare
* @author beiduofengou
* @version 2.3.1
*/

/* 比较按钮样式 */
.bdfg-compare-btn {
margin: 10px 0;
padding: 8px 15px;
background-color: #f7f7f7;
border: 1px solid #ddd;
border-radius: 3px;
cursor: pointer;
transition: all 0.3s ease;
}

.bdfg-compare-btn:hover {
background-color: #ebebeb;
border-color: #ccc;
}

.bdfg-compare-btn.loading {
opacity: 0.7;
cursor: wait;
}

/* 比较表格样式 */
.bdfg-compare-wrapper {
margin: 30px 0;
overflow-x: auto;
}

.bdfg-compare-table {
width: 100%;
border-collapse: collapse;
background: #fff;
margin-bottom: 20px;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}

.bdfg-compare-table th,
.bdfg-compare-table td {
padding: 15px;
text-align: left;
border: 1px solid #eee;
vertical-align: top;
}

.bdfg-compare-table th {
background: #f8f8f8;
font-weight: 600;
min-width: 150px;
}

.bdfg-compare-table td {
min-width: 200px;
}

/* 图片样式 */
.bdfg-compare-image {
text-align: center;
margin-bottom: 10px;
}

.bdfg-compare-image img {
max-width: 150px;
height: auto;
}

/* 价格样式 */
.bdfg-compare-price {
font-size: 1.1em;
color: #77a464;
font-weight: 600;
}

/* 差异高亮 */
.bdfg-highlight {
background-color: #fff9c4;
padding: 2px 5px;
border-radius: 2px;
}

/* 操作按钮 */
.bdfg-compare-actions-top {
margin-bottom: 20px;
display: flex;
gap: 10px;
flex-wrap: wrap;
}

.bdfg-compare-actions-top button {
padding: 8px 15px;
background: #2271b1;
color: #fff;
border: none;
border-radius: 3px;
cursor: pointer;
transition: all 0.3s ease;
}

.bdfg-compare-actions-top button:hover {
background: #135e96;
}

/* 弹窗样式 */
.bdfg-modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.5);
z-index: 999999;
}

.bdfg-modal-content {
position: relative;
background: #fff;
width: 90%;
max-width: 600px;
margin: 50px auto;
padding: 20px;
border-radius: 5px;
box-shadow: 0 3px 6px rgba(0,0,0,0.3);
}

.bdfg-modal-close {
position: absolute;
top: 10px;
right: 10px;
font-size: 24px;
cursor: pointer;
color: #666;
}

/* 响应式调整 */
@media screen and (max-width: 768px) {
.bdfg-compare-table {
font-size: 14px;
}

.bdfg-compare-table th,
.bdfg-compare-table td {
padding: 10px;
}

.bdfg-compare-image img {
max-width: 100px;
}
}

templates/compare-table.php

相关文章: WordPress 智能缓存管理

<?php
/**
* Compare table template
*
* @package BDFG_Woo_Compare
* @author beiduofengou <[email protected]>
* @version 2.3.1
*/

if (!defined('ABSPATH')) {
exit;
}
?>

<div class="bdfg-compare-wrapper">
<?php if (empty($products)) : ?>
<div class="bdfg-compare-empty">
<p><?php esc_html_e('No products added to compare list.', 'bdfg-woo-compare'); ?></p>
<a href="<?php echo esc_url(wc_get_page_permalink('shop')); ?>" class="button">
<?php esc_html_e('Browse products', 'bdfg-woo-compare'); ?>
</a>
</div>
<?php else : ?>
<div class="bdfg-compare-actions-top">
<button class="bdfg-share-compare" data-nonce="<?php echo wp_create_nonce('bdfg_share_nonce'); ?>">
<?php esc_html_e('Share Comparison', 'bdfg-woo-compare'); ?>
</button>

<div class="bdfg-export-buttons">
<button class="bdfg-export-pdf" data-format="pdf" data-nonce="<?php echo wp_create_nonce('bdfg_export_nonce'); ?>">
<?php esc_html_e('Export as PDF', 'bdfg-woo-compare'); ?>
</button>
<button class="bdfg-export-csv" data-format="csv" data-nonce="<?php echo wp_create_nonce('bdfg_export_nonce'); ?>">
<?php esc_html_e('Export as CSV', 'bdfg-woo-compare'); ?>
</button>
</div>

<?php if (is_user_logged_in()) : ?>
<button class="bdfg-save-compare" data-nonce="<?php echo wp_create_nonce('bdfg_save_nonce'); ?>">
<?php esc_html_e('Save Comparison', 'bdfg-woo-compare'); ?>
</button>
<?php endif; ?>
</div>

<table class="bdfg-compare-table">
<tbody>
<?php foreach ($fields as $field_id => $field) : ?>
<tr class="bdfg-compare-row bdfg-compare-<?php echo esc_attr($field_id); ?>">
<th class="bdfg-compare-label">
<?php echo esc_html($field['label']); ?>
</th>
<?php foreach ($products as $product) : ?>
<td class="bdfg-compare-value">
<?php
if (is_callable($field['callback'])) {
echo call_user_func($field['callback'], $product);
}
?>
</td>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
</div>

admin/class-bdfg-settings.php

<?php
/**
* BDFG WooCommerce Compare Settings
*
* @package BDFG_Woo_Compare
* @author beiduofengou <[email protected]>
* @version 2.3.1
* @since 1.0.0
*/

if (!defined('ABSPATH')) {
exit;
}

class BDFG_Compare_Settings {

/**
* 设置页面钩子
*/
private $settings_page;

/**
* 设置选项
*/
private $options;

/**
* 构造函数
*/
public function __construct() {
add_action('admin_menu', array($this, 'add_settings_page'));
add_action('admin_init', array($this, 'init_settings'));

// 加载当前设置
$this->options = get_option('bdfg_compare_settings');
}

/**
* 添加设置菜单
*/
public function add_settings_page() {
$this->settings_page = add_submenu_page(
'woocommerce',
__('Compare Settings', 'bdfg-woo-compare'),
__('Compare', 'bdfg-woo-compare'),
'manage_options',
'bdfg-compare-settings',
array($this, 'render_settings_page')
);

// 加载设置页面的样式和脚本
add_action('load-' . $this->settings_page, array($this, 'enqueue_admin_assets'));
}

/**
* 初始化设置
*/
public function init_settings() {
register_setting(
'bdfg_compare_settings',
'bdfg_compare_settings',
array($this, 'sanitize_settings')
);

// 常规设置
add_settings_section(
'bdfg_compare_general',
__('General Settings', 'bdfg-woo-compare'),
array($this, 'render_general_section'),
'bdfg_compare_settings'
);

// 按钮设置
add_settings_section(
'bdfg_compare_button',
__('Button Settings', 'bdfg-woo-compare'),
array($this, 'render_button_section'),
'bdfg_compare_settings'
);

// 表格设置
add_settings_section(
'bdfg_compare_table',
__('Table Settings', 'bdfg-woo-compare'),
array($this, 'render_table_section'),
'bdfg_compare_settings'
);

// 添加设置字段
$this->add_settings_fields();
}

/**
* 添加设置字段
*/
private function add_settings_fields() {
// 常规设置字段
add_settings_field(
'max_products',
__('Maximum Products', 'bdfg-woo-compare'),
array($this, 'render_number_field'),
'bdfg_compare_settings',
'bdfg_compare_general',
array(
'id' => 'max_products',
'desc' => __('Maximum number of products that can be compared', 'bdfg-woo-compare'),
'default' => 4
)
);

// 按钮设置字段
add_settings_field(
'button_position',
__('Button Position', 'bdfg-woo-compare'),
array($this, 'render_select_field'),
'bdfg_compare_settings',
'bdfg_compare_button',
array(
'id' => 'button_position',
'options' => array(
'woocommerce_after_add_to_cart_button' => __('After Add to Cart', 'bdfg-woo-compare'),
'woocommerce_before_add_to_cart_button' => __('Before Add to Cart', 'bdfg-woo-compare'),
'woocommerce_after_shop_loop_item' => __('After Product', 'bdfg-woo-compare')
),
'default' => 'woocommerce_after_add_to_cart_button'
)
);
}

/**
* 渲染设置页面
*/
public function render_settings_page() {
if (!current_user_can('manage_options')) {
return;
}
?>
<div class="wrap bdfg-compare-settings">
<h1><?php echo esc_html(get_admin_page_title()); ?></h1>

<?php settings_errors(); ?>

<form action="options.php" method="post">
<?php
settings_fields('bdfg_compare_settings');
do_settings_sections('bdfg_compare_settings');
submit_button();
?>
</form>
</div>
<?php
}

}

// 初始化设置类
new BDFG_Compare_Settings();

includes/class-bdfg-template-loader.php

相关文章: WordPress优惠券提醒插件系统

<?php
/**
* BDFG WooCommerce Compare Template Loader
*
* @package BDFG_Woo_Compare
* @author beiduofengou <[email protected]>
* @version 2.3.1
*/

if (!defined('ABSPATH')) {
exit;
}

class BDFG_Template_Loader {

/**
* 获取模板路径
*/
public static function locate_template($template_name) {
$template = '';

// 主题中的模板优先
$template_path = 'bdfg-compare/';

// 在主题中查找
$template = locate_template(
array(
$template_path . $template_name,
$template_name
)
);

// 使用插件默认模板
if (!$template) {
$template = BDFG_COMPARE_TEMPLATES_PATH . $template_name;
}

return apply_filters('bdfg_compare_locate_template', $template, $template_name);
}

/**
* 获取模板内容
*/
public static function get_template($template_name, $args = array()) {
$template = self::locate_template($template_name);

if (!file_exists($template)) {
/* translators: %s template */
_doing_it_wrong(__FUNCTION__, sprintf(__('%s does not exist.', 'bdfg-woo-compare'), '<code>' . $template . '</code>'), '2.3.0');
return;
}

// 提取变量供模板使用
if ($args && is_array($args)) {
extract($args);
}

include $template;
}
}

Leave a Comment