WooCommerce 高级产品定价和折扣管理

WooCommerce 商店的高级产品定价和折扣管理。

<?php
/**
* Plugin Name: BDFG Dynamic Pricing
* Plugin URI: https://beiduofengou.net/2024/10/16/bdfg-dynamic-pricing/
* Description: Advanced dynamic pricing and discount management system for WooCommerce. Create flexible pricing rules, boost sales with marketing features, and grow your business.
* Version: 2.3.0
* Requires at least: 5.8
* Requires PHP: 7.4
* Author: BeiDuoFengOu
* Author URI: https://beiduofengou.net
* Text Domain: bdfg-dynamic-pricing
* Domain Path: /languages
* License: GPL v2 or later
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
* WC requires at least: 5.0
* WC tested up to: 8.0
*
* @package BDFG_Dynamic_Pricing
* @author BeiDuoFengOu
* @copyright 2024 BeiDuoFengOu
*/

if (!defined('ABSPATH')) {
exit; // 防止直接访问
}

// 定义插件常量
define('BDFG_VERSION', '2.3.0');
define('BDFG_PLUGIN_FILE', __FILE__);
define('BDFG_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('BDFG_PLUGIN_URL', plugin_dir_url(__FILE__));
define('BDFG_PLUGIN_BASENAME', plugin_basename(__FILE__));
define('BDFG_MINIMUM_WP_VERSION', '5.8');
define('BDFG_MINIMUM_WC_VERSION', '5.0');

/**
* 主插件类
*/
final class BDFG_Dynamic_Pricing {
/**
* 插件实例
*
* @var BDFG_Dynamic_Pricing
*/
private static $instance = null;

/**
* 插件设置
*
* @var array
*/
private $settings;

/**
* 营销扩展实例
*
* @var BDFG_Marketing_Notification_Extension
*/
private $marketing;

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

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

// 加载设置
$this->settings = get_option('bdfg_settings', $this->get_default_settings());

// 如果启用了营销功能,初始化营销扩展
if ($this->is_marketing_enabled()) {
$this->init_marketing();
}

do_action('bdfg_loaded');
}

/**
* 定义额外的常量
*/
private function define_constants() {
define('BDFG_DB_VERSION', '2.3.0');
define('BDFG_ABSPATH', dirname(BDFG_PLUGIN_FILE) . '/');
}

/**
* 检查系统要求
*/
private function check_requirements() {
if (version_compare(get_bloginfo('version'), BDFG_MINIMUM_WP_VERSION, '<')) {
add_action('admin_notices', array($this, 'wordpress_version_notice'));
return;
}

if (!class_exists('WooCommerce')) {
add_action('admin_notices', array($this, 'woocommerce_missing_notice'));
return;
}

if (defined('WC_VERSION') && version_compare(WC_VERSION, BDFG_MINIMUM_WC_VERSION, '<')) {
add_action('admin_notices', array($this, 'woocommerce_version_notice'));
return;
}
}

/**
* 包含必要的文件
*/
private function includes() {
// 核心文件
require_once BDFG_PLUGIN_DIR . 'includes/class-bdfg-autoloader.php';
require_once BDFG_PLUGIN_DIR . 'includes/class-bdfg-installer.php';
require_once BDFG_PLUGIN_DIR . 'includes/class-bdfg-dynamic-pricing-extended.php';
require_once BDFG_PLUGIN_DIR . 'includes/class-bdfg-marketing-notification-extension.php';

// 管理员界面
if (is_admin()) {
require_once BDFG_PLUGIN_DIR . 'includes/admin/class-bdfg-admin.php';
}

// API和集成
require_once BDFG_PLUGIN_DIR . 'includes/api/class-bdfg-api.php';
require_once BDFG_PLUGIN_DIR . 'includes/integrations/class-bdfg-woocommerce.php';
}

/**
* 初始化钩子
*/
private function init_hooks() {
// 激活和停用钩子
register_activation_hook(BDFG_PLUGIN_FILE, array($this, 'activate'));
register_deactivation_hook(BDFG_PLUGIN_FILE, array($this, 'deactivate'));

// 初始化动作
add_action('plugins_loaded', array($this, 'load_plugin_textdomain'));
add_action('init', array($this, 'init'), 0);

// WooCommerce集成
add_action('woocommerce_loaded', array($this, 'woocommerce_loaded'));

// 过滤器
add_filter('woocommerce_get_price_html', array($this, 'maybe_add_discount_badge'), 10, 2);
add_filter('plugin_action_links_' . BDFG_PLUGIN_BASENAME, array($this, 'add_plugin_action_links'));

// AJAX处理
add_action('wp_ajax_bdfg_save_rule', array($this, 'ajax_save_rule'));
add_action('wp_ajax_bdfg_delete_rule', array($this, 'ajax_delete_rule'));
}

/**
* 获取默认设置
*
* @return array
*/
private function get_default_settings() {
return array(
'general' => array(
'enable_dynamic_pricing' => 'yes',
'price_display_format' => 'both_prices',
'sale_badge_text' => __('Sale!', 'bdfg-dynamic-pricing'),
'enable_logging' => 'no'
),
'marketing' => array(
'enable_marketing_features' => 'yes',
'countdown_timer' => 'yes',
'stock_countdown' => 'yes',
'social_share_discount' => 'yes',
'email_notifications' => 'yes'
),
'advanced' => array(
'cache_duration' => 3600,
'debug_mode' => 'no',
'clean_on_uninstall' => 'no',
'performance_mode' => 'balanced'
)
);
}

/**
* 插件激活
*/
public function activate() {
if (!class_exists('WooCommerce')) {
deactivate_plugins(plugin_basename(BDFG_PLUGIN_FILE));
wp_die(
__('BDFG Dynamic Pricing requires WooCommerce to be installed and activated.', 'bdfg-dynamic-pricing'),
'Plugin dependency check',
array('back_link' => true)
);
}

// 运行数据库更新
BDFG_Installer::install();

// 添加默认设置
if (!get_option('bdfg_settings')) {
update_option('bdfg_settings', $this->get_default_settings());
}

// 记录安装时间
add_option('bdfg_installation_time', current_time('mysql'));

// 刷新重写规则
flush_rewrite_rules();

do_action('bdfg_activated');
}

/**
* 插件停用
*/
public function deactivate() {
// 清理定时任务
wp_clear_scheduled_hook('bdfg_daily_maintenance');
wp_clear_scheduled_hook('bdfg_cleanup_old_statistics');

// 清理临时数据
$this->cleanup_temp_data();

// 刷新重写规则
flush_rewrite_rules();

do_action('bdfg_deactivated');
}

/**
* 加载文本域
*/
public function load_plugin_textdomain() {
load_plugin_textdomain(
'bdfg-dynamic-pricing',
false,
dirname(plugin_basename(BDFG_PLUGIN_FILE)) . '/languages/'
);
}

/**
* 初始化插件
*/
public function init() {
// 检查版本并执行更新
$this->check_version();

// 初始化会话
$this->maybe_init_session();

// 初始化管理界面
if (is_admin()) {
new BDFG_Admin($this);
}

do_action('bdfg_init');
}

/**
* 检查并初始化会话
*/
private function maybe_init_session() {
if (!session_id() && !headers_sent()) {
session_start();
}
}

/**
* WooCommerce加载完成后的操作
*/
public function woocommerce_loaded() {
// 添加价格过滤器
add_filter('woocommerce_product_get_price', array($this, 'apply_dynamic_pricing'), 10, 2);
add_filter('woocommerce_product_get_regular_price', array($this, 'apply_dynamic_pricing'), 10, 2);
add_filter('woocommerce_product_variation_get_price', array($this, 'apply_dynamic_pricing'), 10, 2);
}

/**
* 应用动态定价
*
* @param float $price
* @param WC_Product $product
* @return float
*/
public function apply_dynamic_pricing($price, $product) {
if (!$this->should_apply_pricing($product)) {
return $price;
}

$rules = $this->get_applicable_rules($product);
foreach ($rules as $rule) {
$price = $this->calculate_discounted_price($price, $rule);
}

return $price;
}

/**
* 检查是否启用了营销功能
*
* @return bool
*/
public function is_marketing_enabled() {
return isset($this->settings['marketing']['enable_marketing_features'])
&& $this->settings['marketing']['enable_marketing_features'] === 'yes';
}

/**
* 清理临时数据
*/
private function cleanup_temp_data() {
global $wpdb;
$wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE 'bdfg_temp_%'");
}

/**
* 添加插件操作链接
*
* @param array $links
* @return array
*/
public function add_plugin_action_links($links) {
$plugin_links = array(
'<a href="' . admin_url('admin.php?page=bdfg-dynamic-pricing') . '">' .
__('Settings', 'bdfg-dynamic-pricing') . '</a>',
'<a href="https://beiduofengou.net/docs/bdfg-dynamic-pricing/" target="_blank">' .
__('Documentation', 'bdfg-dynamic-pricing') . '</a>'
);
return array_merge($plugin_links, $links);
}

/**
* 显示WordPress版本提示
*/
public function wordpress_version_notice() {
$message = sprintf(
esc_html__('BDFG Dynamic Pricing requires WordPress version %s or higher. Please upgrade WordPress to continue using the plugin.', 'bdfg-dynamic-pricing'),
BDFG_MINIMUM_WP_VERSION
);
echo '<div class="error"><p>' . $message . '</p></div>';
}

/**
* 显示WooCommerce缺失提示
*/
public function woocommerce_missing_notice() {
$message = sprintf(
esc_html__('BDFG Dynamic Pricing requires WooCommerce to be installed and activated. You can download %s here.', 'bdfg-dynamic-pricing'),
'<a href="https://woocommerce.com/" target="_blank">WooCommerce</a>'
);
echo '<div class="error"><p>' . $message . '</p></div>';
}

/**
* 显示WooCommerce版本提示
*/
public function woocommerce_version_notice() {
$message = sprintf(
esc_html__('BDFG Dynamic Pricing requires WooCommerce version %s or higher. Please upgrade WooCommerce to continue using the plugin.', 'bdfg-dynamic-pricing'),
BDFG_MINIMUM_WC_VERSION
);
echo '<div class="error"><p>' . $message . '</p></div>';
}
}

/**
* 返回主插件实例
*
* @return BDFG_Dynamic_Pricing
*/
function BDFG() {
return BDFG_Dynamic_Pricing::get_instance();
}

// 初始化插件
add_action('plugins_loaded', 'BDFG');

includes/class-bdfg-dynamic-pricing-extended.php

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

<?php
/**
* BDFG Dynamic Pricing - Extended Features
*
* 提供高级功能扩展,包括数据导入导出、统计报告和批量操作
*
* @package BDFG_Dynamic_Pricing
* @subpackage Extensions
* @version 2.3.0
* @since 2.0.0
* @author BeiDuoFengOu
* @last_modified 2024-10-16
*/

defined('ABSPATH') || exit;

class BDFG_Dynamic_Pricing_Extended {
/**
* 父插件实例
*
* @var BDFG_Dynamic_Pricing
*/
private $plugin;

/**
* 统计数据缓存
*
* @var array
*/
private $stats_cache = array();

/**
* 构造函数
*
* @param BDFG_Dynamic_Pricing $plugin
*/
public function __construct($plugin) {
$this->plugin = $plugin;
$this->init_hooks();
}

/**
* 初始化钩子
*/
private function init_hooks() {
// 添加菜单
add_action('admin_menu', array($this, 'add_admin_menus'), 20);

// 导入导出功能
add_action('admin_post_bdfg_export_rules', array($this, 'handle_export_rules'));
add_action('admin_post_bdfg_export_stats', array($this, 'handle_export_statistics'));
add_action('wp_ajax_bdfg_import_rules', array($this, 'handle_import_rules'));

// 批量处理
add_action('wp_ajax_bdfg_bulk_enable_rules', array($this, 'handle_bulk_enable_rules'));
add_action('wp_ajax_bdfg_bulk_disable_rules', array($this, 'handle_bulk_disable_rules'));

// 定时任务
add_action('bdfg_daily_maintenance', array($this, 'perform_daily_maintenance'));
add_action('bdfg_cleanup_old_statistics', array($this, 'cleanup_old_statistics'));
}

/**
* 添加管理菜单
*/
public function add_admin_menus() {
add_submenu_page(
'bdfg-dynamic-pricing',
__('Import/Export', 'bdfg-dynamic-pricing'),
__('Import/Export', 'bdfg-dynamic-pricing'),
'manage_woocommerce',
'bdfg-import-export',
array($this, 'render_import_export_page')
);

add_submenu_page(
'bdfg-dynamic-pricing',
__('Statistics', 'bdfg-dynamic-pricing'),
__('Statistics', 'bdfg-dynamic-pricing'),
'manage_woocommerce',
'bdfg-statistics',
array($this, 'render_statistics_page')
);
}

/**
* 渲染导入导出页面
*/
public function render_import_export_page() {
if (!current_user_can('manage_woocommerce')) {
wp_die(__('You do not have sufficient permissions to access this page.', 'bdfg-dynamic-pricing'));
}

?>
<div class="wrap bdfg-admin">
<h1><?php echo esc_html__('Import/Export Rules', 'bdfg-dynamic-pricing'); ?></h1>

<div class="bdfg-admin-content">
<!-- 导出部分 -->
<div class="bdfg-card">
<h2><?php echo esc_html__('Export', 'bdfg-dynamic-pricing'); ?></h2>
<p class="description">
<?php echo esc_html__('Export your pricing rules and settings for backup or transfer to another site.', 'bdfg-dynamic-pricing'); ?>
</p>
<form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>">
<?php wp_nonce_field('bdfg_export_rules', 'bdfg_export_nonce'); ?>
<input type="hidden" name="action" value="bdfg_export_rules">
<p>
<label>
<input type="checkbox" name="include_statistics" value="1">
<?php echo esc_html__('Include statistics data', 'bdfg-dynamic-pricing'); ?>
</label>
</p>
<button type="submit" class="button button-primary">
<?php echo esc_html__('Export Rules', 'bdfg-dynamic-pricing'); ?>
</button>
</form>
</div>

<!-- 导入部分 -->
<div class="bdfg-card">
<h2><?php echo esc_html__('Import', 'bdfg-dynamic-pricing'); ?></h2>
<p class="description">
<?php echo esc_html__('Import pricing rules from a JSON file.', 'bdfg-dynamic-pricing'); ?>
</p>
<form method="post" enctype="multipart/form-data" id="bdfg-import-form">
<?php wp_nonce_field('bdfg_import_rules', 'bdfg_import_nonce'); ?>
<p>
<input type="file" name="import_file" accept=".json" required>
</p>
<p>
<label>
<input type="checkbox" name="overwrite_existing" value="1">
<?php echo esc_html__('Overwrite existing rules', 'bdfg-dynamic-pricing'); ?>
</label>
</p>
<button type="submit" class="button button-primary">
<?php echo esc_html__('Import Rules', 'bdfg-dynamic-pricing'); ?>
</button>
</form>
<div id="bdfg-import-results"></div>
</div>
</div>
</div>
<?php
}

/**
* 渲染统计页面
*/
public function render_statistics_page() {
if (!current_user_can('manage_woocommerce')) {
wp_die(__('You do not have sufficient permissions to access this page.', 'bdfg-dynamic-pricing'));
}

// 获取日期范围
$start_date = isset($_GET['start_date']) ? sanitize_text_field($_GET['start_date']) : date('Y-m-d', strtotime('-30 days'));
$end_date = isset($_GET['end_date']) ? sanitize_text_field($_GET['end_date']) : date('Y-m-d');

// 获取统计数据
$stats = $this->get_statistics_data($start_date, $end_date);

?>
<div class="wrap bdfg-admin">
<h1><?php echo esc_html__('Discount Statistics', 'bdfg-dynamic-pricing'); ?></h1>

<!-- 日期筛选器 -->
<div class="bdfg-date-filter">
<form method="get">
<input type="hidden" name="page" value="bdfg-statistics">
<label>
<?php echo esc_html__('Start Date:', 'bdfg-dynamic-pricing'); ?>
<input type="date" name="start_date" value="<?php echo esc_attr($start_date); ?>">
</label>
<label>
<?php echo esc_html__('End Date:', 'bdfg-dynamic-pricing'); ?>
<input type="date" name="end_date" value="<?php echo esc_attr($end_date); ?>">
</label>
<button type="submit" class="button">
<?php echo esc_html__('Filter', 'bdfg-dynamic-pricing'); ?>
</button>
</form>
</div>

<!-- 统计概览 -->
<div class="bdfg-stats-overview">
<div class="bdfg-stat-card">
<h3><?php echo esc_html__('Total Discounts', 'bdfg-dynamic-pricing'); ?></h3>
<div class="stat-value"><?php echo wc_price($stats['total_discount']); ?></div>
</div>
<div class="bdfg-stat-card">
<h3><?php echo esc_html__('Total Orders', 'bdfg-dynamic-pricing'); ?></h3>
<div class="stat-value"><?php echo esc_html($stats['total_orders']); ?></div>
</div>
<div class="bdfg-stat-card">
<h3><?php echo esc_html__('Average Discount', 'bdfg-dynamic-pricing'); ?></h3>
<div class="stat-value"><?php echo wc_price($stats['avg_discount']); ?></div>
</div>
</div>

<!-- 详细数据表格 -->
<div class="bdfg-stats-table-wrapper">
<table class="wp-list-table widefat fixed striped">
<thead>
<tr>
<th><?php echo esc_html__('Date', 'bdfg-dynamic-pricing'); ?></th>
<th><?php echo esc_html__('Orders', 'bdfg-dynamic-pricing'); ?></th>
<th><?php echo esc_html__('Total Discount', 'bdfg-dynamic-pricing'); ?></th>
<th><?php echo esc_html__('Average Discount', 'bdfg-dynamic-pricing'); ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($stats['daily_stats'] as $day): ?>
<tr>
<td><?php echo esc_html($day->date); ?></td>
<td><?php echo esc_html($day->order_count); ?></td>
<td><?php echo wc_price($day->total_discount); ?></td>
<td><?php echo wc_price($day->avg_discount); ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
<?php
}

/**
* 处理规则导出
*/
public function handle_export_rules() {
if (!current_user_can('manage_woocommerce') || !check_admin_referer('bdfg_export_rules', 'bdfg_export_nonce')) {
wp_die(__('Permission denied', 'bdfg-dynamic-pricing'));
}

$include_stats = isset($_POST['include_statistics']) && $_POST['include_statistics'] === '1';
$data = $this->get_export_data($include_stats);

// 设置响应头
header('Content-Type: application/json');
header('Content-Disposition: attachment; filename=bdfg-rules-' . date('Y-m-d') . '.json');
header('Pragma: no-cache');
header('Expires: 0');

echo wp_json_encode($data, JSON_PRETTY_PRINT);
exit;
}

/**
* 处理规则导入
*/
public function handle_import_rules() {
check_ajax_referer('bdfg_import_rules', 'nonce');

if (!current_user_can('manage_woocommerce')) {
wp_send_json_error(__('Permission denied', 'bdfg-dynamic-pricing'));
}

$file = $_FILES['import_file'];
if ($file['error'] || !is_uploaded_file($file['tmp_name'])) {
wp_send_json_error(__('Error uploading file', 'bdfg-dynamic-pricing'));
}

$content = file_get_contents($file['tmp_name']);
$data = json_decode($content, true);

if (json_last_error() !== JSON_ERROR_NONE) {
wp_send_json_error(__('Invalid JSON file', 'bdfg-dynamic-pricing'));
}

try {
$this->process_import_data($data);
wp_send_json_success(__('Rules imported successfully', 'bdfg-dynamic-pricing'));
} catch (Exception $e) {
wp_send_json_error($e->getMessage());
}
}

/**
* 获取统计数据
*
* @param string $start_date
* @param string $end_date
* @return array
*/
private function get_statistics_data($start_date, $end_date) {
global $wpdb;

$cache_key = md5("stats_{$start_date}_{$end_date}");

if (isset($this->stats_cache[$cache_key])) {
return $this->stats_cache[$cache_key];
}

$daily_stats = $wpdb->get_results($wpdb->prepare(
"SELECT
DATE(applied_date) as date,
COUNT(DISTINCT order_id) as order_count,
SUM(discount_amount) as total_discount,
AVG(discount_amount) as avg_discount
FROM {$wpdb->prefix}bdfg_statistics
WHERE applied_date BETWEEN %s AND %s
GROUP BY DATE(applied_date)
ORDER BY date DESC",
$start_date,
$end_date
));

$total_stats = $wpdb->get_row($wpdb->prepare(
"SELECT
COUNT(DISTINCT order_id) as total_orders,
SUM(discount_amount) as total_discount,
AVG(discount_amount) as avg_discount
FROM {$wpdb->prefix}bdfg_statistics
WHERE applied_date BETWEEN %s AND %s",
$start_date,
$end_date
));

$stats = array(
'daily_stats' => $daily_stats,
'total_orders' => $total_stats->total_orders,
'total_discount' => $total_stats->total_discount,
'avg_discount' => $total_stats->avg_discount
);

$this->stats_cache[$cache_key] = $stats;

return $stats;
}

/**
* 清理旧统计数据
*/
public function cleanup_old_statistics() {
global $wpdb;

// 默认保留90天的数据
$days_to_keep = apply_filters('bdfg_statistics_retention_days', 90);

$wpdb->query($wpdb->prepare(
"DELETE FROM {$wpdb->prefix}bdfg_statistics
WHERE applied_date < DATE_SUB(NOW(), INTERVAL %d DAY)",
$days_to_keep
));
}

/**
* 获取导出数据
*
* @param bool $include_stats
* @return array
*/
private function get_export_data($include_stats = false) {
global $wpdb;

// 获取规则
$rules = $wpdb->get_results(
"SELECT * FROM {$wpdb->prefix}bdfg_discount_rules
ORDER BY priority ASC"
);

$export_data = array(
'version' => BDFG_VERSION,
'generated_at' => current_time('mysql'),
'site_url' => get_site_url(),
'rules' => $rules,
'settings' => get_option('bdfg_settings')
);

// 如果包含统计数据
if ($include_stats) {
$stats = $wpdb->get_results(
"SELECT * FROM {$wpdb->prefix}bdfg_statistics
WHERE applied_date >= DATE_SUB(NOW(), INTERVAL 30 DAY)"
);
$export_data['statistics'] = $stats;
}

return $export_data;
}

/**
* 处理导入数据
*
* @param array $data
* @throws Exception
*/
private function process_import_data($data) {
global $wpdb;

// 验证数据格式
if (!isset($data['version']) || !isset($data['rules'])) {
throw new Exception(__('Invalid import file format', 'bdfg-dynamic-pricing'));
}

// 开始事务
$wpdb->query('START TRANSACTION');

try {
// 是否覆盖现有规则
$overwrite = isset($_POST['overwrite_existing']) && $_POST['overwrite_existing'] === '1';

if ($overwrite) {
$wpdb->query("TRUNCATE TABLE {$wpdb->prefix}bdfg_discount_rules");
}

// 导入规则
foreach ($data['rules'] as $rule) {
$rule = (array) $rule;
unset($rule['rule_id']); // 移除原始ID

$wpdb->insert(
$wpdb->prefix . 'bdfg_discount_rules',
array_merge($rule, array(
'updated_at' => current_time('mysql')
)),
array(
'%s', '%s', '%s', '%f', '%s', '%s', '%s',
'%d', '%s', '%s', '%s'
)
);
}

// 导入设置
if (isset($data['settings'])) {
update_option('bdfg_settings', $data['settings']);
}

$wpdb->query('COMMIT');

// 清理缓存
wp_cache_flush();

// 记录导入日志
$this->log_import_activity($data);

} catch (Exception $e) {
$wpdb->query('ROLLBACK');
throw $e;
}
}

/**
* 记录导入活动
*
* @param array $data
*/
private function log_import_activity($data) {
$log = array(
'type' => 'import',
'rules_count' => count($data['rules']),
'source_site' => isset($data['site_url']) ? $data['site_url'] : 'unknown',
'source_version' => isset($data['version']) ? $data['version'] : 'unknown',
'imported_at' => current_time('mysql'),
'imported_by' => get_current_user_id()
);

$this->add_activity_log($log);
}

/**
* 添加活动日志
*
* @param array $log
*/
private function add_activity_log($log) {
global $wpdb;

$wpdb->insert(
$wpdb->prefix . 'bdfg_activity_log',
$log,
array('%s', '%d', '%s', '%s', '%s', '%d')
);
}

/**
* 处理批量启用规则
*/
public function handle_bulk_enable_rules() {
check_ajax_referer('bdfg_bulk_action', 'nonce');

if (!current_user_can('manage_woocommerce')) {
wp_send_json_error(__('Permission denied', 'bdfg-dynamic-pricing'));
}

$rule_ids = isset($_POST['rule_ids']) ? array_map('intval', $_POST['rule_ids']) : array();

if (empty($rule_ids)) {
wp_send_json_error(__('No rules selected', 'bdfg-dynamic-pricing'));
}

global $wpdb;

$updated = $wpdb->query($wpdb->prepare(
"UPDATE {$wpdb->prefix}bdfg_discount_rules
SET status = 'active', updated_at = %s
WHERE rule_id IN (" . implode(',', $rule_ids) . ")",
current_time('mysql')
));

if ($updated !== false) {
wp_send_json_success(array(
'message' => sprintf(
__('%d rules enabled successfully', 'bdfg-dynamic-pricing'),
$updated
)
));
} else {
wp_send_json_error(__('Error enabling rules', 'bdfg-dynamic-pricing'));
}
}

/**
* 处理批量禁用规则
*/
public function handle_bulk_disable_rules() {
check_ajax_referer('bdfg_bulk_action', 'nonce');

if (!current_user_can('manage_woocommerce')) {
wp_send_json_error(__('Permission denied', 'bdfg-dynamic-pricing'));
}

$rule_ids = isset($_POST['rule_ids']) ? array_map('intval', $_POST['rule_ids']) : array();

if (empty($rule_ids)) {
wp_send_json_error(__('No rules selected', 'bdfg-dynamic-pricing'));
}

global $wpdb;

$updated = $wpdb->query($wpdb->prepare(
"UPDATE {$wpdb->prefix}bdfg_discount_rules
SET status = 'inactive', updated_at = %s
WHERE rule_id IN (" . implode(',', $rule_ids) . ")",
current_time('mysql')
));

if ($updated !== false) {
wp_send_json_success(array(
'message' => sprintf(
__('%d rules disabled successfully', 'bdfg-dynamic-pricing'),
$updated
)
));
} else {
wp_send_json_error(__('Error disabling rules', 'bdfg-dynamic-pricing'));
}
}

/**
* 执行每日维护任务
*/
public function perform_daily_maintenance() {
// 清理过期规则
$this->cleanup_expired_rules();

// 更新规则统计
$this->update_rules_statistics();

// 优化数据表
$this->optimize_tables();

do_action('bdfg_after_daily_maintenance');
}

/**
* 清理过期规则
*/
private function cleanup_expired_rules() {
global $wpdb;

$wpdb->query($wpdb->prepare(
"UPDATE {$wpdb->prefix}bdfg_discount_rules
SET status = 'expired', updated_at = %s
WHERE end_date < %s
AND status = 'active'",
current_time('mysql'),
current_time('mysql')
));
}

/**
* 更新规则统计
*/
private function update_rules_statistics() {
global $wpdb;

$rules = $wpdb->get_results(
"SELECT rule_id FROM {$wpdb->prefix}bdfg_discount_rules
WHERE status = 'active'"
);

foreach ($rules as $rule) {
$stats = $this->calculate_rule_statistics($rule->rule_id);
$this->update_rule_meta($rule->rule_id, 'statistics', $stats);
}
}

/**
* 优化数据表
*/
private function optimize_tables() {
global $wpdb;

$tables = array(
$wpdb->prefix . 'bdfg_discount_rules',
$wpdb->prefix . 'bdfg_statistics',
$wpdb->prefix . 'bdfg_activity_log'
);

foreach ($tables as $table) {
$wpdb->query("OPTIMIZE TABLE $table");
}
}
}

includes/class-bdfg-marketing-notification-extension.php

<?php
/**
* BDFG Dynamic Pricing - Marketing & Notifications Extension
*
* 提供营销功能和客户通知系统
*
* @package BDFG_Dynamic_Pricing
* @subpackage Marketing
* @version 2.3.0
* @since 2.0.0
* @author BeiDuoFengOu
* @last_modified 2024-10-16
*/

defined('ABSPATH') || exit;

class BDFG_Marketing_Notification_Extension {
/**
* 父插件实例
*
* @var BDFG_Dynamic_Pricing
*/
private $plugin;

/**
* 营销设置
*
* @var array
*/
private $settings;

/**
* 通知队列
*
* @var array
*/
private $notification_queue = array();

/**
* 营销统计缓存
*
* @var array
*/
private $stats_cache = array();

/**
* 构造函数
*
* @param BDFG_Dynamic_Pricing $plugin
*/
public function __construct($plugin) {
$this->plugin = $plugin;
$this->settings = get_option('bdfg_marketing_settings', array());
$this->init_hooks();
}

/**
* 初始化钩子
*/
private function init_hooks() {
// 前端显示
add_action('wp_enqueue_scripts', array($this, 'enqueue_marketing_assets'));
add_action('woocommerce_before_single_product', array($this, 'display_countdown_timer'));
add_action('woocommerce_before_add_to_cart_form', array($this, 'display_stock_countdown'));
add_filter('woocommerce_get_price_html', array($this, 'add_social_share_discount_notice'), 10, 2);

// AJAX处理
add_action('wp_ajax_bdfg_subscribe_discount', array($this, 'handle_subscription_discount'));
add_action('wp_ajax_nopriv_bdfg_subscribe_discount', array($this, 'handle_subscription_discount'));
add_action('wp_ajax_bdfg_record_share', array($this, 'handle_social_share'));
add_action('wp_ajax_nopriv_bdfg_record_share', array($this, 'handle_social_share'));

// 通知系统
add_action('init', array($this, 'schedule_notification_events'));
add_action('bdfg_process_notifications', array($this, 'process_notification_queue'));
add_action('bdfg_daily_cleanup', array($this, 'cleanup_old_notifications'));

// 管理界面
if (is_admin()) {
add_action('admin_menu', array($this, 'add_marketing_menu'));
add_action('admin_init', array($this, 'register_marketing_settings'));
}
}

/**
* 加载营销相关资源
*/
public function enqueue_marketing_assets() {
if (!$this->should_load_assets()) {
return;
}

wp_enqueue_style(
'bdfg-marketing',
BDFG_PLUGIN_URL . 'assets/css/marketing.css',
array(),
BDFG_VERSION
);

wp_enqueue_script(
'bdfg-marketing',
BDFG_PLUGIN_URL . 'assets/js/marketing.js',
array('jquery'),
BDFG_VERSION,
true
);

wp_localize_script('bdfg-marketing', 'bdfgMarketing', array(
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('bdfg-marketing-nonce'),
'i18n' => $this->get_js_translations()
));
}

/**
* 显示倒计时计时器
*/
public function display_countdown_timer() {
if (!$this->is_countdown_enabled()) {
return;
}

global $product;
if (!$product) {
return;
}

$discount_rules = $this->get_active_discount_rules($product->get_id());
if (empty($discount_rules)) {
return;
}

foreach ($discount_rules as $rule) {
if (!empty($rule->end_date) && strtotime($rule->end_date) > current_time('timestamp')) {
$this->render_countdown_timer($rule);
break; // 只显示第一个有效的倒计时
}
}
}

/**
* 渲染倒计时计时器
*
* @param object $rule
*/
private function render_countdown_timer($rule) {
$template = $this->get_template('countdown-timer.php');
if ($template) {
include $template;
} else {
// 备用内联模板
?>
<div class="bdfg-countdown-timer"
data-end="<?php echo esc_attr($rule->end_date); ?>"
data-discount="<?php echo esc_attr($rule->discount_amount); ?>"
data-type="<?php echo esc_attr($rule->discount_type); ?>">
<div class="timer-title">
<?php esc_html_e('Limited Time Offer!', 'bdfg-dynamic-pricing'); ?>
</div>
<div class="timer-blocks"></div>
</div>
<?php
}
}

/**
* 显示库存倒计时
*/
public function display_stock_countdown() {
if (!$this->is_stock_countdown_enabled()) {
return;
}

global $product;
if (!$product || !$product->managing_stock()) {
return;
}

$stock = $product->get_stock_quantity();
$threshold = $this->get_stock_threshold();

if ($stock <= $threshold) {
$this->render_stock_countdown($stock, $threshold);
}
}

/**
* 处理订阅折扣
*/
public function handle_subscription_discount() {
check_ajax_referer('bdfg-marketing-nonce', 'nonce');

$email = isset($_POST['email']) ? sanitize_email($_POST['email']) : '';

if (!is_email($email)) {
wp_send_json_error(array(
'message' => __('Invalid email address.', 'bdfg-dynamic-pricing')
));
}

// 检查是否已订阅
if ($this->is_email_subscribed($email)) {
wp_send_json_error(array(
'message' => __('This email is already subscribed.', 'bdfg-dynamic-pricing')
));
}

// 生成优惠券
$coupon_code = $this->generate_subscription_coupon($email);

if (!$coupon_code) {
wp_send_json_error(array(
'message' => __('Error generating coupon.', 'bdfg-dynamic-pricing')
));
}

// 保存订阅者信息
$this->save_subscriber($email, $coupon_code);

// 发送欢迎邮件
$this->send_welcome_email($email, $coupon_code);

wp_send_json_success(array(
'message' => __('Thank you for subscribing! Check your email for your discount code.', 'bdfg-dynamic-pricing'),
'coupon_code' => $coupon_code
));
}

/**
* 处理社交分享
*/
public function handle_social_share() {
check_ajax_referer('bdfg-marketing-nonce', 'nonce');

$product_id = isset($_POST['product_id']) ? absint($_POST['product_id']) : 0;
$network = isset($_POST['network']) ? sanitize_text_field($_POST['network']) : '';

if (!$product_id || !$network) {
wp_send_json_error(__('Invalid request.', 'bdfg-dynamic-pricing'));
}

// 记录分享
$this->record_social_share($product_id, $network);

// 获取分享折扣
$discount = $this->get_share_discount($product_id);

wp_send_json_success(array(
'message' => sprintf(
__('Thanks for sharing! Use code %s for %s off.', 'bdfg-dynamic-pricing'),
$discount['code'],
$discount['amount']
),
'discount' => $discount
));
}

/**
* 生成订阅优惠券
*
* @param string $email
* @return string|bool
*/
private function generate_subscription_coupon($email) {
$coupon_code = 'BDFG_' . strtoupper(substr(md5($email . time()), 0, 8));

$coupon = array(
'post_title' => $coupon_code,
'post_content' => '',
'post_status' => 'publish',
'post_author' => 1,
'post_type' => 'shop_coupon'
);

$coupon_id = wp_insert_post($coupon);

if (!$coupon_id) {
return false;
}

// 设置优惠券元数据
update_post_meta($coupon_id, 'discount_type', 'percent');
update_post_meta($coupon_id, 'coupon_amount', $this->get_subscription_discount_amount());
update_post_meta($coupon_id, 'individual_use', 'yes');
update_post_meta($coupon_id, 'usage_limit', 1);
update_post_meta($coupon_id, 'expiry_date', date('Y-m-d', strtotime('+30 days')));
update_post_meta($coupon_id, 'email', $email);

return $coupon_code;
}

/**
* 发送欢迎邮件
*
* @param string $email
* @param string $coupon_code
*/
private function send_welcome_email($email, $coupon_code) {
$template = $this->get_email_template('welcome.php', array(
'coupon_code' => $coupon_code,
'expiry_date' => date('Y-m-d', strtotime('+30 days'))
));

$subject = sprintf(
__('Welcome to %s - Here\'s Your Discount Code!', 'bdfg-dynamic-pricing'),
get_bloginfo('name')
);

$headers = array('Content-Type: text/html; charset=UTF-8');

wp_mail($email, $subject, $template, $headers);
}

/**
* 保存订阅者信息
*
* @param string $email
* @param string $coupon_code
*/
private function save_subscriber($email, $coupon_code) {
global $wpdb;

$wpdb->insert(
$wpdb->prefix . 'bdfg_subscribers',
array(
'email' => $email,
'coupon_code' => $coupon_code,
'subscribed_date' => current_time('mysql'),
'status' => 'active'
),
array('%s', '%s', '%s', '%s')
);
}

/**
* 获取JavaScript翻译
*
* @return array
*/
private function get_js_translations() {
return array(
'days' => __('Days', 'bdfg-dynamic-pricing'),
'hours' => __('Hours', 'bdfg-dynamic-pricing'),
'minutes' => __('Minutes', 'bdfg-dynamic-pricing'),
'seconds' => __('Seconds', 'bdfg-dynamic-pricing'),
'share_discount' => __('Share to get %s off!', 'bdfg-dynamic-pricing'),
'subscribe_success' => __('Thank you for subscribing!', 'bdfg-dynamic-pricing'),
'error_occurred' => __('An error occurred. Please try again.', 'bdfg-dynamic-pricing')
);
}

/**
* 检查是否应该加载营销资源
*
* @return bool
*/
private function should_load_assets() {
return is_product() ||
is_shop() ||
is_product_category() ||
is_cart() ||
is_checkout();
}

/**
* 获取模板文件路径
*
* @param string $template
* @return string
*/
private function get_template($template) {
$template_path = locate_template('bdfg/' . $template);

if (!$template_path) {
$template_path = BDFG_PLUGIN_DIR . 'templates/' . $template;
}

return file_exists($template_path) ? $template_path : false;
}

/**
* 清理旧通知
*/
public function cleanup_old_notifications() {
global $wpdb;

$wpdb->query($wpdb->prepare(
"DELETE FROM {$wpdb->prefix}bdfg_notifications
WHERE created_at < DATE_SUB(%s, INTERVAL 30 DAY)",
current_time('mysql')
));
}
}

includes/class-bdfg-autoloader.php

相关文章: WooCommerce 产品比较工具

<?php
/**
* BDFG Dynamic Pricing - Autoloader
*
* 自动加载插件类文件
*
* @package BDFG_Dynamic_Pricing
* @since 2.0.0
*/

defined('ABSPATH') || exit;

class BDFG_Autoloader {
/**
* 类映射缓存
*
* @var array
*/
private static $class_map = array();

/**
* 注册自动加载器
*/
public static function register() {
spl_autoload_register(array(__CLASS__, 'autoload'));
}

/**
* 自动加载类文件
*
* @param string $class 完整的类名
*/
public static function autoload($class) {
if (0 !== strpos($class, 'BDFG_')) {
return;
}

$file = self::get_file_name_from_class($class);

// 检查缓存
if (isset(self::$class_map[$class])) {
$file = self::$class_map[$class];
if (file_exists($file)) {
require_once $file;
return;
}
}

// 常见的类文件位置
$locations = array(
BDFG_PLUGIN_DIR . 'includes/',
BDFG_PLUGIN_DIR . 'includes/admin/',
BDFG_PLUGIN_DIR . 'includes/marketing/',
BDFG_PLUGIN_DIR . 'includes/integrations/'
);

foreach ($locations as $location) {
if (file_exists($location . $file)) {
self::$class_map[$class] = $location . $file;
require_once $location . $file;
return;
}
}
}

/**
* 从类名生成文件名
*
* @param string $class 类名
* @return string
*/
private static function get_file_name_from_class($class) {
return 'class-' . str_replace('_', '-', strtolower($class)) . '.php';
}
}

BDFG_Autoloader::register();

includes/class-bdfg-installer.php

<?php
/**
* BDFG Dynamic Pricing - Installer
*
* 处理插件的安装和更新
*
* @package BDFG_Dynamic_Pricing
* @since 2.0.0
*/

defined('ABSPATH') || exit;

class BDFG_Installer {
/**
* 数据库版本选项名
*/
const DB_VERSION_OPTION = 'bdfg_db_version';

/**
* 安装插件
*/
public static function install() {
if (!is_blog_installed()) {
return;
}

// 检查权限
if (!current_user_can('activate_plugins')) {
return;
}

// 获取当前数据库版本
$current_db_version = get_option(self::DB_VERSION_OPTION, '0.0.0');

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

// 安装默认数据
self::install_default_data();

// 添加定时任务
self::schedule_tasks();

// 更新数据库版本
update_option(self::DB_VERSION_OPTION, BDFG_VERSION);

// 清理缓存
wp_cache_flush();
}

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

$wpdb->hide_errors();

require_once ABSPATH . 'wp-admin/includes/upgrade.php';

// 折扣规则表
$sql = "CREATE TABLE IF NOT EXISTS {$wpdb->prefix}bdfg_discount_rules (
rule_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
rule_name VARCHAR(255) NOT NULL,
rule_type VARCHAR(50) NOT NULL,
discount_type VARCHAR(50) NOT NULL,
discount_amount DECIMAL(10,2) NOT NULL,
start_date DATETIME NULL,
end_date DATETIME NULL,
conditions LONGTEXT NULL,
priority INT UNSIGNED DEFAULT 10,
status VARCHAR(20) DEFAULT 'active',
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
PRIMARY KEY (rule_id),
KEY rule_status (status),
KEY rule_dates (start_date, end_date)
) {$wpdb->get_charset_collate()};";

// 统计数据表
$sql .= "CREATE TABLE IF NOT EXISTS {$wpdb->prefix}bdfg_statistics (
stat_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
rule_id BIGINT UNSIGNED NOT NULL,
product_id BIGINT UNSIGNED NOT NULL,
order_id BIGINT UNSIGNED NOT NULL,
discount_amount DECIMAL(10,2) NOT NULL,
customer_id BIGINT UNSIGNED NULL,
applied_date DATETIME NOT NULL,
PRIMARY KEY (stat_id),
KEY rule_id (rule_id),
KEY product_id (product_id),
KEY order_id (order_id)
) {$wpdb->get_charset_collate()};";

// 订阅者表
$sql .= "CREATE TABLE IF NOT EXISTS {$wpdb->prefix}bdfg_subscribers (
subscriber_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
email VARCHAR(255) NOT NULL,
status VARCHAR(20) NOT NULL DEFAULT 'active',
subscribed_date DATETIME NOT NULL,
preferences TEXT NULL,
PRIMARY KEY (subscriber_id),
UNIQUE KEY email (email)
) {$wpdb->get_charset_collate()};";

dbDelta($sql);
}

/**
* 安装默认数据
*/
private static function install_default_data() {
// 添加默认设置
$default_settings = array(
'general' => array(
'enable_dynamic_pricing' => 'yes',
'price_display_format' => 'both_prices',
'sale_badge_text' => __('Sale!', 'bdfg-dynamic-pricing'),
),
'marketing' => array(
'enable_marketing_features' => 'yes',
'countdown_timer' => 'yes',
'stock_countdown' => 'yes',
'social_share_discount' => 'yes',
),
'advanced' => array(
'cache_duration' => 3600,
'debug_mode' => 'no',
'clean_on_uninstall' => 'no',
),
);

update_option('bdfg_settings', $default_settings);

// 添加默认折扣规则
$default_rule = array(
'rule_name' => __('Welcome Discount', 'bdfg-dynamic-pricing'),
'rule_type' => 'cart',
'discount_type' => 'percentage',
'discount_amount' => 10.00,
'status' => 'active',
'created_at' => current_time('mysql'),
'updated_at' => current_time('mysql'),
);

self::add_default_rule($default_rule);
}

/**
* 添加默认规则
*
* @param array $rule
*/
private static function add_default_rule($rule) {
global $wpdb;

$wpdb->insert(
$wpdb->prefix . 'bdfg_discount_rules',
$rule,
array(
'%s', '%s', '%s', '%f', '%s', '%s', '%s'
)
);
}

/**
* 设置定时任务
*/
private static function schedule_tasks() {
if (!wp_next_scheduled('bdfg_daily_maintenance')) {
wp_schedule_event(time(), 'daily', 'bdfg_daily_maintenance');
}

if (!wp_next_scheduled('bdfg_cleanup_old_statistics')) {
wp_schedule_event(time(), 'weekly', 'bdfg_cleanup_old_statistics');
}
}

/**
* 更新插件
*/
public static function update() {
$current_version = get_option(self::DB_VERSION_OPTION, '0.0.0');

if (version_compare($current_version, '2.0.0', '<')) {
self::update_to_2_0_0();
}

if (version_compare($current_version, '2.1.0', '<')) {
self::update_to_2_1_0();
}

// 更新数据库版本
update_option(self::DB_VERSION_OPTION, BDFG_VERSION);
}

/**
* 更新到2.0.0版本
*/
private static function update_to_2_0_0() {
global $wpdb;

// 添加新的数据库字段
$wpdb->query("ALTER TABLE {$wpdb->prefix}bdfg_discount_rules
ADD COLUMN conditions LONGTEXT NULL AFTER discount_amount");
}

/**
* 更新到2.1.0版本
*/
private static function update_to_2_1_0() {
global $wpdb;

// 添加优先级字段
$wpdb->query("ALTER TABLE {$wpdb->prefix}bdfg_discount_rules
ADD COLUMN priority INT UNSIGNED DEFAULT 10 AFTER conditions");
}
}

includes/admin/class-bdfg-admin.php

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

<?php
/**
* BDFG Dynamic Pricing - Admin
*
* 处理后台管理界面
*
* @package BDFG_Dynamic_Pricing
* @subpackage Admin
* @since 2.0.0
*/

defined('ABSPATH') || exit;

class BDFG_Admin {
/**
* 父插件实例
*
* @var BDFG_Dynamic_Pricing
*/
private $plugin;

/**
* 当前活动的选项卡
*
* @var string
*/
private $active_tab = '';

/**
* 构造函数
*
* @param BDFG_Dynamic_Pricing $plugin
*/
public function __construct($plugin) {
$this->plugin = $plugin;

// 添加菜单
add_action('admin_menu', array($this, 'add_admin_menu'));

// 注册设置
add_action('admin_init', array($this, 'register_settings'));

// 添加插件操作链接
add_filter('plugin_action_links_' . BDFG_PLUGIN_BASENAME, array($this, 'add_plugin_action_links'));

// 加载管理界面资源
add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_assets'));
}

/**
* 添加管理菜单
*/
public function add_admin_menu() {
add_menu_page(
__('BDFG Dynamic Pricing', 'bdfg-dynamic-pricing'),
__('Dynamic Pricing', 'bdfg-dynamic-pricing'),
'manage_woocommerce',
'bdfg-dynamic-pricing',
array($this, 'render_admin_page'),
'dashicons-tag',
58
);

add_submenu_page(
'bdfg-dynamic-pricing',
__('Settings', 'bdfg-dynamic-pricing'),
__('Settings', 'bdfg-dynamic-pricing'),
'manage_woocommerce',
'bdfg-settings',
array($this, 'render_settings_page')
);

add_submenu_page(
'bdfg-dynamic-pricing',
__('Pricing Rules', 'bdfg-dynamic-pricing'),
__('Pricing Rules', 'bdfg-dynamic-pricing'),
'manage_woocommerce',
'bdfg-pricing-rules',
array($this, 'render_pricing_rules_page')
);
}

/**
* 注册插件设置
*/
public function register_settings() {
register_setting(
'bdfg_settings',
'bdfg_settings',
array($this, 'validate_settings')
);

// 常规设置
add_settings_section(
'bdfg_general_settings',
__('General Settings', 'bdfg-dynamic-pricing'),
array($this, 'render_general_settings_section'),
'bdfg-settings'
);

// 营销设置
add_settings_section(
'bdfg_marketing_settings',
__('Marketing Settings', 'bdfg-dynamic-pricing'),
array($this, 'render_marketing_settings_section'),
'bdfg-settings'
);

// 高级设置
add_settings_section(
'bdfg_advanced_settings',
__('Advanced Settings', 'bdfg-dynamic-pricing'),
array($this, 'render_advanced_settings_section'),
'bdfg-settings'
);
}

/**
* 加载管理界面资源
*/
public function enqueue_admin_assets($hook) {
if (!$this->is_plugin_page($hook)) {
return;
}

wp_enqueue_style(
'bdfg-admin-style',
BDFG_PLUGIN_URL . 'assets/css/admin.css',
array(),
BDFG_VERSION
);

wp_enqueue_script(
'bdfg-admin-script',
BDFG_PLUGIN_URL . 'assets/js/admin.js',
array('jquery', 'jquery-ui-datepicker', 'wp-util'),
BDFG_VERSION,
true
);

wp_localize_script('bdfg-admin-script', 'bdfgAdmin', array(
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('bdfg-admin-nonce'),
'i18n' => $this->get_admin_translations()
));
}

/**
* 获取管理界面翻译
*
* @return array
*/
private function get_admin_translations() {
return array(
'confirm_delete' => __('Are you sure you want to delete this rule?', 'bdfg-dynamic-pricing'),
'changes_saved' => __('Changes saved successfully.', 'bdfg-dynamic-pricing'),
'error_saving' => __('Error saving changes.', 'bdfg-dynamic-pricing'),
'loading' => __('Loading...', 'bdfg-dynamic-pricing'),
'no_rules' => __('No pricing rules found.', 'bdfg-dynamic-pricing'),
);
}

/**
* 检查是否在插件页面
*
* @param string $hook
* @return bool
*/
private function is_plugin_page($hook) {
$plugin_pages = array(
'toplevel_page_bdfg-dynamic-pricing',
'dynamic-pricing_page_bdfg-settings',
'dynamic-pricing_page_bdfg-pricing-rules'
);

return in_array($hook, $plugin_pages);
}

/**
* 渲染管理主页
*/
public function render_admin_page() {
$this->active_tab = isset($_GET['tab']) ? sanitize_text_field($_GET['tab']) : 'dashboard';
?>
<div class="wrap bdfg-admin">
<h1>
<?php echo esc_html__('BDFG Dynamic Pricing', 'bdfg-dynamic-pricing'); ?>
<a href="<?php echo esc_url(admin_url('admin.php?page=bdfg-pricing-rules&action=new')); ?>"
class="page-title-action">
<?php echo esc_html__('Add New Rule', 'bdfg-dynamic-pricing'); ?>
</a>
</h1>

<?php $this->render_tabs(); ?>

<div class="bdfg-admin-content">
<?php
switch ($this->active_tab) {
case 'dashboard':
$this->render_dashboard();
break;
case 'reports':
$this->render_reports();
break;
default:
do_action('bdfg_admin_tab_content_' . $this->active_tab);
break;
}
?>
</div>
</div>
<?php
}

/**
* 渲染管理标签页
*/
private function render_tabs() {
$tabs = array(
'dashboard' => __('Dashboard', 'bdfg-dynamic-pricing'),
'reports' => __('Reports', 'bdfg-dynamic-pricing'),
);

$tabs = apply_filters('bdfg_admin_tabs', $tabs);
?>
<h2 class="nav-tab-wrapper">
<?php
foreach ($tabs as $tab => $label) {
$active_class = ($this->active_tab === $tab) ? 'nav-tab-active' : '';
$url = add_query_arg('tab', $tab);
?>
<a href="<?php echo esc_url($url); ?>"
class="nav-tab <?php echo esc_attr($active_class); ?>">
<?php echo esc_html($label); ?>
</a>
<?php
}
?>
</h2>
<?php
}

/**
* 渲染仪表盘
*/
private function render_dashboard() {
$active_rules = $this->get_active_rules_count();
$total_savings = $this->get_total_savings_this_month();
$popular_rules = $this->get_popular_rules();
?>
<div class="bdfg-dashboard-widgets">
<div class="bdfg-widget">
<h3><?php esc_html_e('Active Rules', 'bdfg-dynamic-pricing'); ?></h3>
<div class="bdfg-widget-content">
<span class="bdfg-big-number"><?php echo esc_html($active_rules); ?></span>
</div>
</div>

<div class="bdfg-widget">
<h3><?php esc_html_e('Total Savings This Month', 'bdfg-dynamic-pricing'); ?></h3>
<div class="bdfg-widget-content">
<span class="bdfg-big-number"><?php echo wc_price($total_savings); ?></span>
</div>
</div>

<div class="bdfg-widget bdfg-widget-full">
<h3><?php esc_html_e('Popular Rules', 'bdfg-dynamic-pricing'); ?></h3>
<div class="bdfg-widget-content">
<?php if ($popular_rules) : ?>
<table class="widefat">
<thead>
<tr>
<th><?php esc_html_e('Rule', 'bdfg-dynamic-pricing'); ?></th>
<th><?php esc_html_e('Uses', 'bdfg-dynamic-pricing'); ?></th>
<th><?php esc_html_e('Total Savings', 'bdfg-dynamic-pricing'); ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($popular_rules as $rule) : ?>
<tr>
<td><?php echo esc_html($rule->rule_name); ?></td>
<td><?php echo esc_html($rule->uses); ?></td>
<td><?php echo wc_price($rule->total_savings); ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php else : ?>
<p><?php esc_html_e('No data available yet.', 'bdfg-dynamic-pricing'); ?></p>
<?php endif; ?>
</div>
</div>
</div>
<?php
}

/**
* 获取活动规则数量
*
* @return int
*/
private function get_active_rules_count() {
global $wpdb;
return (int) $wpdb->get_var(
"SELECT COUNT(*) FROM {$wpdb->prefix}bdfg_discount_rules WHERE status = 'active'"
);
}

/**
* 获取本月总节省金额
*
* @return float
*/
private function get_total_savings_this_month() {
global $wpdb;
$first_day = date('Y-m-01 00:00:00');
$last_day = date('Y-m-t 23:59:59');

return (float) $wpdb->get_var($wpdb->prepare(
"SELECT SUM(discount_amount) FROM {$wpdb->prefix}bdfg_statistics
WHERE applied_date BETWEEN %s AND %s",
$first_day,
$last_day
));
}

/**
* 获取最受欢迎的规则
*
* @return array
*/
private function get_popular_rules() {
global $wpdb;
return $wpdb->get_results(
"SELECT r.rule_name,
COUNT(s.stat_id) as uses,
SUM(s.discount_amount) as total_savings
FROM {$wpdb->prefix}bdfg_discount_rules r
LEFT JOIN {$wpdb->prefix}bdfg_statistics s ON r.rule_id = s.rule_id
GROUP BY r.rule_id
ORDER BY uses DESC
LIMIT 5"
);
}
}

assets/css/marketing.css

/* BDFG Dynamic Pricing Marketing Styles */

.bdfg-countdown-timer {
background: #f7f7f7;
padding: 15px;
border-radius: 4px;
margin-bottom: 20px;
text-align: center;
border: 1px solid #e5e5e5;
}

.bdfg-countdown-timer .timer-block {
display: inline-block;
margin: 0 10px;
text-align: center;
min-width: 60px;
}

.bdfg-countdown-timer .timer-number {
font-size: 24px;
font-weight: bold;
color: #e94444;
display: block;
}

.bdfg-countdown-timer .timer-label {
font-size: 12px;
color: #666;
text-transform: uppercase;
}

.bdfg-stock-countdown {
margin: 15px 0;
padding: 10px;
background: #fff8e5;
border: 1px solid #ffe5b2;
border-radius: 3px;
}

.bdfg-stock-countdown .stock-count {
color: #d63638;
font-weight: bold;
}

.bdfg-stock-countdown .progress-bar {
height: 10px;
background: #f0f0f0;
border-radius: 5px;
margin-top: 8px;
overflow: hidden;
}

.bdfg-stock-countdown .progress {
height: 100%;
background: #4caf50;
border-radius: 5px;
transition: width 0.3s ease;
}

.bdfg-social-share {
margin: 20px 0;
padding: 15px;
background: #e9f7ff;
border: 1px solid #b3e0ff;
border-radius: 4px;
text-align: center;
}

.bdfg-social-share .share-buttons {
margin-top: 10px;
}

.bdfg-social-share .share-button {
display: inline-block;
padding: 8px 15px;
margin: 0 5px;
border-radius: 3px;
color: #fff;
text-decoration: none;
font-size: 14px;
}

.bdfg-social-share .share-facebook {
background: #3b5998;
}

.bdfg-social-share .share-twitter {
background: #1da1f2;
}

.bdfg-notification {
position: fixed;
bottom: 20px;
right: 20px;
padding: 15px 20px;
background: #fff;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
border-left: 4px solid #4caf50;
border-radius: 3px;
z-index: 9999;
animation: slideIn 0.3s ease;
}

@keyframes slideIn {
from {
transform: translateX(100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}

/* 响应式设计 */
@media screen and (max-width: 768px) {
.bdfg-countdown-timer .timer-block {
margin: 5px;
min-width: 50px;
}

.bdfg-countdown-timer .timer-number {
font-size: 20px;
}

.bdfg-social-share .share-button {
display: block;
margin: 5px 0;
}
}

assets/js/marketing.js

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

/**
* BDFG Dynamic Pricing Marketing Scripts
*
* @package BDFG_Dynamic_Pricing
*/

(function($) {
'use strict';

var BDFG_Marketing = {
/**
* 初始化
*/
init: function() {
this.initCountdownTimers();
this.initStockCountdown();
this.initSocialShare();
this.initSubscriptionForm();
},

/**
* 初始化倒计时计时器
*/
initCountdownTimers: function() {
$('.bdfg-countdown-timer').each(function() {
var $timer = $(this);
var endDate = new Date($timer.data('end')).getTime();

var updateTimer = function() {
var now = new Date().getTime();
var distance = endDate - now;

if (distance < 0) {
clearInterval(interval);
$timer.html(bdfgMarketing.i18n.expired);
return;
}

var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);

$timer.html(
'<div class="timer-block">' +
'<span class="timer-number">' + days + '</span>' +
'<span class="timer-label">' + bdfgMarketing.i18n.days + '</span>' +
'</div>' +
'<div class="timer-block">' +
'<span class="timer-number">' + hours + '</span>' +
'<span class="timer-label">' + bdfgMarketing.i18n.hours + '</span>' +
'</div>' +
'<div class="timer-block">' +
'<span class="timer-number">' + minutes + '</span>' +
'<span class="timer-label">' + bdfgMarketing.i18n.minutes + '</span>' +
'</div>' +
'<div class="timer-block">' +
'<span class="timer-number">' + seconds + '</span>' +
'<span class="timer-label">' + bdfgMarketing.i18n.seconds + '</span>' +
'</div>'
);
};

updateTimer();
var interval = setInterval(updateTimer, 1000);
});
},

/**
* 初始化库存倒计时
*/
initStockCountdown: function() {
$('.bdfg-stock-countdown').each(function() {
var $container = $(this);
var stock = parseInt($container.data('stock'), 10);
var threshold = parseInt($container.data('threshold'), 10);
var percentage = Math.min((stock / threshold) * 100, 100);

$container.find('.progress').css('width', percentage + '%');
});
},

/**
* 初始化社交分享
*/
initSocialShare: function() {
$('.bdfg-share-button').on('click', function(e) {
e.preventDefault();
var url = $(this).data('share-url');
var network = $(this).data('network');
var width = 600;
var height = 400;
var left = (screen.width/2)-(width/2);
var top = (screen.height/2)-(height/2);

window.open(url, network + '_share',
'toolbar=no, location=no, directories=no, status=no, menubar=no, ' +
'scrollbars=no, resizable=no, copyhistory=no, width=' + width +
', height=' + height + ', top=' + top + ', left=' + left
);

// 记录分享
$.post(bdfgMarketing.ajax_url, {
action: 'bdfg_record_share',nonce: bdfgMarketing.nonce,
network: network,
product_id: $(this).data('product-id')
}, function(response) {
if (response.success) {
BDFG_Marketing.showNotification(response.data.message);
}
});
});
},

/**
* 初始化订阅表单
*/
initSubscriptionForm: function() {
$('#bdfg-subscription-form').on('submit', function(e) {
e.preventDefault();
var $form = $(this);
var $submit = $form.find('button[type="submit"]');
var originalText = $submit.text();

$submit.prop('disabled', true).text(bdfgMarketing.i18n.processing);

$.post(bdfgMarketing.ajax_url, {
action: 'bdfg_subscribe_discount',
nonce: bdfgMarketing.nonce,
email: $form.find('input[name="email"]').val()
}, function(response) {
if (response.success) {
BDFG_Marketing.showNotification(response.data.message);
$form.find('.bdfg-coupon-code').text(response.data.coupon_code).show();
$form[0].reset();
} else {
BDFG_Marketing.showNotification(response.data.message, 'error');
}
$submit.prop('disabled', false).text(originalText);
});
});
},

/**
* 显示通知
*
* @param {string} message 消息内容
* @param {string} type 通知类型 (success|error)
*/
showNotification: function(message, type) {
type = type || 'success';
var $notification = $('<div/>', {
'class': 'bdfg-notification bdfg-notification-' + type,
'text': message
});

$('body').append($notification);

setTimeout(function() {
$notification.fadeOut(300, function() {
$(this).remove();
});
}, 3000);
}
};

// DOM 加载完成后初始化
$(function() {
BDFG_Marketing.init();
});

})(jQuery);

assets/css/admin.css

/* BDFG Dynamic Pricing Admin Styles */

.bdfg-admin {
margin: 20px 0;
}

.bdfg-admin .bdfg-header {
background: #fff;
padding: 20px;
margin-bottom: 20px;
border: 1px solid #e5e5e5;
border-radius: 3px;
display: flex;
align-items: center;
justify-content: space-between;
}

.bdfg-admin .bdfg-logo {
max-width: 200px;
height: auto;
}

.bdfg-dashboard-widgets {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 20px;
margin-top: 20px;
}

.bdfg-widget {
background: #fff;
border: 1px solid #e5e5e5;
border-radius: 3px;
padding: 20px;
}

.bdfg-widget-full {
grid-column: 1 / -1;
}

.bdfg-widget h3 {
margin: 0 0 15px;
padding-bottom: 10px;
border-bottom: 1px solid #eee;
color: #23282d;
}

.bdfg-big-number {
font-size: 36px;
font-weight: bold;
color: #2271b1;
}

.bdfg-rules-table {
width: 100%;
border-spacing: 0;
}

.bdfg-rules-table th {
text-align: left;
padding: 10px;
background: #f8f9fa;
border-bottom: 2px solid #e5e5e5;
}

.bdfg-rules-table td {
padding: 12px 10px;
border-bottom: 1px solid #e5e5e5;
}

.bdfg-rules-table tr:hover {
background: #f8f9fa;
}

.bdfg-status-badge {
display: inline-block;
padding: 3px 8px;
border-radius: 3px;
font-size: 12px;
font-weight: 500;
}

.bdfg-status-active {
background: #edf7ed;
color: #2e7d32;
}

.bdfg-status-inactive {
background: #fef6f6;
color: #d32f2f;
}

.bdfg-form-row {
margin-bottom: 20px;
}

.bdfg-form-row label {
display: block;
margin-bottom: 5px;
font-weight: 500;
}

.bdfg-form-row input[type="text"],
.bdfg-form-row input[type="number"],
.bdfg-form-row select,
.bdfg-form-row textarea {
width: 100%;
max-width: 400px;
}

.bdfg-help-tip {
color: #666;
font-size: 13px;
font-style: italic;
margin-top: 5px;
}

/* 响应式设计 */
@media screen and (max-width: 782px) {
.bdfg-dashboard-widgets {
grid-template-columns: 1fr;
}

.bdfg-rules-table {
display: block;
overflow-x: auto;
}
}

templates/emails/welcome.php

<?php
/**
* 订阅欢迎邮件模板
*
* @package BDFG_Dynamic_Pricing
* @version 2.3.0
*/

defined('ABSPATH') || exit;

?>
<!DOCTYPE html>
<html lang="<?php echo get_locale(); ?>">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo get_bloginfo('name'); ?></title>
</head>
<body style="background-color: #f7f7f7; margin: 0; padding: 0; font-family: Arial, sans-serif;">
<table width="100%" cellpadding="0" cellspacing="0" style="max-width: 600px; margin: 0 auto; background-color: #ffffff;">
<tr>
<td style="padding: 40px 30px; text-align: center;">
<img src="<?php echo BDFG_PLUGIN_URL; ?>assets/images/logo.png" alt="<?php echo get_bloginfo('name'); ?>" style="max-width: 200px;">
</td>
</tr>
<tr>
<td style="padding: 0 30px 30px;">
<h1 style="color: #333333; font-size: 24px; margin-bottom: 20px;">
<?php esc_html_e('Welcome to our community!', 'bdfg-dynamic-pricing'); ?>
</h1>

<p style="color: #666666; font-size: 16px; line-height: 1.5;">
<?php esc_html_e('Thank you for subscribing to our newsletter. As a welcome gift, here\'s your exclusive discount code:', 'bdfg-dynamic-pricing'); ?>
</p>

<div style="background-color: #f5f5f5; padding: 20px; text-align: center; margin: 20px 0;">
<span style="font-size: 24px; font-weight: bold; color: #e94444;">
<?php echo esc_html($coupon_code); ?>
</span>
</div>

<p style="color: #666666; font-size: 16px; line-height: 1.5;">
<?php esc_html_e('Use this code during checkout to get 10% off your first order. This code will expire in 30 days.', 'bdfg-dynamic-pricing'); ?>
</p>

<div style="text-align: center; margin-top: 30px;">
<a href="<?php echo esc_url(wc_get_page_permalink('shop')); ?>"
style="display: inline-block; padding: 15px 25px; background-color: #2271b1; color: #ffffff; text-decoration: none; border-radius: 3px;">
<?php esc_html_e('Start Shopping', 'bdfg-dynamic-pricing'); ?>
</a>
</div>
</td>
</tr>
<tr>
<td style="background-color: #f7f7f7; padding: 20px 30px; text-align: center; color: #666666; font-size: 14px;">
<p>
<?php echo sprintf(
esc_html__('Follow us on %1$s and %2$s for more updates and special offers!', 'bdfg-dynamic-pricing'),
'<a href="https://facebook.com/beiduofengou" style="color: #2271b1; text-decoration: none;">Facebook</a>',
'<a href="https://twitter.com/beiduofengou" style="color: #2271b1; text-decoration: none;">Twitter</a>'
); ?>
</p>
<p style="margin-top: 10px;">
&copy; <?php echo date('Y'); ?> <?php echo get_bloginfo('name'); ?>.
<?php esc_html_e('All rights reserved.', 'bdfg-dynamic-pricing'); ?>
</p>
</td>
</tr>
</table>
</body>
</html>

includes/api/class-bdfg-api.php

<?php
/**
* BDFG Dynamic Pricing - API
*
* 处理REST API请求和外部集成
*
* @package BDFG_Dynamic_Pricing
* @subpackage API
* @since 2.3.0
* @author BeiDuoFengOu
*/

defined('ABSPATH') || exit;

class BDFG_API {
/**
* API版本
*/
const VERSION = 'v1';

/**
* API命名空间
*/
const NAMESPACE = 'bdfg/v1';

/**
* 构造函数
*/
public function __construct() {
add_action('rest_api_init', array($this, 'register_routes'));
}

/**
* 注册API路由
*/
public function register_routes() {
register_rest_route(self::NAMESPACE, '/rules', array(
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array($this, 'get_rules'),
'permission_callback' => array($this, 'check_permission'),
),
array(
'methods' => WP_REST_Server::CREATABLE,
'callback' => array($this, 'create_rule'),
'permission_callback' => array($this, 'check_permission'),
'args' => $this->get_rule_schema(),
),
));

register_rest_route(self::NAMESPACE, '/rules/(?P<id>\d+)', array(
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array($this, 'get_rule'),
'permission_callback' => array($this, 'check_permission'),
),
array(
'methods' => WP_REST_Server::EDITABLE,
'callback' => array($this, 'update_rule'),
'permission_callback' => array($this, 'check_permission'),
'args' => $this->get_rule_schema(),
),
array(
'methods' => WP_REST_Server::DELETABLE,
'callback' => array($this, 'delete_rule'),
'permission_callback' => array($this, 'check_permission'),
),
));

register_rest_route(self::NAMESPACE, '/statistics', array(
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array($this, 'get_statistics'),
'permission_callback' => array($this, 'check_permission'),
),
));
}

/**
* 检查API权限
*
* @param WP_REST_Request $request
* @return bool|WP_Error
*/
public function check_permission($request) {
if (!current_user_can('manage_woocommerce')) {
return new WP_Error(
'bdfg_rest_forbidden',
__('Sorry, you are not allowed to access this endpoint.', 'bdfg-dynamic-pricing'),
array('status' => rest_authorization_required_code())
);
}
return true;
}

/**
* 获取所有规则
*
* @param WP_REST_Request $request
* @return WP_REST_Response
*/
public function get_rules($request) {
global $wpdb;

$page = $request->get_param('page') ?: 1;
$per_page = $request->get_param('per_page') ?: 10;
$offset = ($page - 1) * $per_page;

$rules = $wpdb->get_results($wpdb->prepare(
"SELECT * FROM {$wpdb->prefix}bdfg_discount_rules
ORDER BY priority ASC
LIMIT %d OFFSET %d",
$per_page,
$offset
));

$total = $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->prefix}bdfg_discount_rules");

$response = new WP_REST_Response($rules);
$response->header('X-WP-Total', $total);
$response->header('X-WP-TotalPages', ceil($total / $per_page));

return $response;
}

/**
* 获取单个规则
*
* @param WP_REST_Request $request
* @return WP_REST_Response|WP_Error
*/
public function get_rule($request) {
global $wpdb;

$rule_id = $request->get_param('id');

$rule = $wpdb->get_row($wpdb->prepare(
"SELECT * FROM {$wpdb->prefix}bdfg_discount_rules WHERE rule_id = %d",
$rule_id
));

if (!$rule) {
return new WP_Error(
'bdfg_rule_not_found',
__('Rule not found.', 'bdfg-dynamic-pricing'),
array('status' => 404)
);
}

return new WP_REST_Response($rule);
}

/**
* 创建新规则
*
* @param WP_REST_Request $request
* @return WP_REST_Response|WP_Error
*/
public function create_rule($request) {
global $wpdb;

$data = $this->prepare_rule_for_database($request);

$result = $wpdb->insert(
$wpdb->prefix . 'bdfg_discount_rules',
$data,
array('%s', '%s', '%s', '%f', '%s', '%s', '%s', '%d')
);

if (!$result) {
return new WP_Error(
'bdfg_db_error',
__('Could not create rule.', 'bdfg-dynamic-pricing'),
array('status' => 500)
);
}

$rule_id = $wpdb->insert_id;
$rule = $this->get_rule(new WP_REST_Request('GET', array('id' => $rule_id)));

return new WP_REST_Response($rule, 201);
}

/**
* 更新规则
*
* @param WP_REST_Request $request
* @return WP_REST_Response|WP_Error
*/
public function update_rule($request) {
global $wpdb;

$rule_id = $request->get_param('id');
$data = $this->prepare_rule_for_database($request);

$result = $wpdb->update(
$wpdb->prefix . 'bdfg_discount_rules',
$data,
array('rule_id' => $rule_id),
array('%s', '%s', '%s', '%f', '%s', '%s', '%s', '%d'),
array('%d')
);

if ($result === false) {
return new WP_Error(
'bdfg_db_error',
__('Could not update rule.', 'bdfg-dynamic-pricing'),
array('status' => 500)
);
}

$rule = $this->get_rule($request);
return new WP_REST_Response($rule);
}

/**
* 删除规则
*
* @param WP_REST_Request $request
* @return WP_REST_Response|WP_Error
*/
public function delete_rule($request) {
global $wpdb;

$rule_id = $request->get_param('id');

$result = $wpdb->delete(
$wpdb->prefix . 'bdfg_discount_rules',
array('rule_id' => $rule_id),
array('%d')
);

if (!$result) {
return new WP_Error(
'bdfg_db_error',
__('Could not delete rule.', 'bdfg-dynamic-pricing'),
array('status' => 500)
);
}

return new WP_REST_Response(null, 204);
}

/**
* 获取统计数据
*
* @param WP_REST_Request $request
* @return WP_REST_Response
*/
public function get_statistics($request) {
global $wpdb;

$start_date = $request->get_param('start_date') ?: date('Y-m-d', strtotime('-30 days'));
$end_date = $request->get_param('end_date') ?: date('Y-m-d');

$stats = $wpdb->get_results($wpdb->prepare(
"SELECT
DATE(applied_date) as date,
COUNT(DISTINCT order_id) as order_count,
SUM(discount_amount) as total_discount,
AVG(discount_amount) as avg_discount
FROM {$wpdb->prefix}bdfg_statistics
WHERE applied_date BETWEEN %s AND %s
GROUP BY DATE(applied_date)
ORDER BY date DESC",
$start_date,
$end_date
));

return new WP_REST_Response($stats);
}

/**
* 获取规则模式
*
* @return array
*/
private function get_rule_schema() {
return array(
'rule_name' => array(
'required' => true,
'type' => 'string',
'sanitize_callback' => 'sanitize_text_field',
),
'rule_type' => array(
'required' => true,
'type' => 'string',
'enum' => array('product', 'cart', 'category'),
),
'discount_type' => array(
'required' => true,
'type' => 'string',
'enum' => array('percentage', 'fixed', 'bogo'),
),
'discount_amount' => array(
'required' => true,
'type' => 'number',
),
'start_date' => array(
'type' => 'string',
'format' => 'date-time',
),
'end_date' => array(
'type' => 'string',
'format' => 'date-time',
),
'conditions' => array(
'type' => 'object',
),
'priority' => array(
'type' => 'integer',
'default' => 10,
),
);
}

/**
* 准备规则数据用于数据库操作
*
* @param WP_REST_Request $request
* @return array
*/
private function prepare_rule_for_database($request) {
return array(
'rule_name' => $request->get_param('rule_name'),
'rule_type' => $request->get_param('rule_type'),
'discount_type' => $request->get_param('discount_type'),
'discount_amount' => $request->get_param('discount_amount'),
'start_date' => $request->get_param('start_date'),
'end_date' => $request->get_param('end_date'),
'conditions' => json_encode($request->get_param('conditions')),
'priority' => $request->get_param('priority'),
'updated_at' => current_time('mysql'),
);
}
}

includes/integrations/class-bdfg-woocommerce.php

<?php
/**
* BDFG Dynamic Pricing - WooCommerce Integration
*
* 处理与WooCommerce的集成
*
* @package BDFG_Dynamic_Pricing
* @subpackage Integrations
* @since 2.3.0
* @author BeiDuoFengOu
*/

defined('ABSPATH') || exit;

class BDFG_WooCommerce {
/**
* 父插件实例
*
* @var BDFG_Dynamic_Pricing
*/
private $plugin;

/**
* 构造函数
*
* @param BDFG_Dynamic_Pricing $plugin
*/
public function __construct($plugin) {
$this->plugin = $plugin;
$this->init_hooks();
}

/**
* 初始化钩子
*/
private function init_hooks() {
// 产品价格过滤器
add_filter('woocommerce_product_get_price', array($this, 'filter_product_price'), 10, 2);
add_filter('woocommerce_product_get_regular_price', array($this, 'filter_product_regular_price'), 10, 2);
add_filter('woocommerce_product_variation_get_price', array($this, 'filter_product_price'), 10, 2);

// 购物车相关
add_action('woocommerce_before_calculate_totals', array($this, 'calculate_cart_discounts'));
add_action('woocommerce_cart_item_price', array($this, 'show_cart_item_discount'), 10, 3);

// 订单相关
add_action('woocommerce_checkout_order_processed', array($this, 'save_order_discounts'), 10, 3);
add_action('woocommerce_order_status_completed', array($this, 'record_completed_order_stats'));

// 管理界面
if (is_admin()) {
add_action('woocommerce_product_options_pricing', array($this, 'add_product_pricing_fields'));
add_action('woocommerce_process_product_meta', array($this, 'save_product_pricing_fields'));
}
}

/**
* 过滤产品价格
*
* @param string $price
* @param WC_Product $product
* @return string
*/
public function filter_product_price($price, $product) {
if (!$this->should_apply_pricing($product)) {
return $price;
}

$discounted_price = $this->calculate_product_discount($price, $product);

// 记录价格变化
$this->log_price_change($product->get_id(), $price, $discounted_price);

return $discounted_price;
}

/**
* 计算产品折扣
*
* @param float $price
* @param WC_Product $product
* @return float
*/
private function calculate_product_discount($price, $product) {
$rules = $this->get_applicable_rules($product);
$final_price = $price;

foreach ($rules as $rule) {
switch ($rule['discount_type']) {
case 'percentage':
$discount = ($price * $rule['discount_amount']) / 100;
$final_price = $price - $discount;
break;

case 'fixed':
$final_price = $price - $rule['discount_amount'];
break;

case 'bogo':
// BOGO逻辑在购物车中处理
break;

default:
$final_price = apply_filters('bdfg_custom_discount_calculation',
$final_price,
$price,
$rule,$product
);
break;
}
}

return max(0, $final_price);
}

/**
* 计算购物车折扣
*
* @param WC_Cart $cart
*/
public function calculate_cart_discounts($cart) {
if (!$cart || $cart->is_empty()) {
return;
}

$cart_rules = $this->get_applicable_cart_rules();

foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
$product = $cart_item['data'];
$original_price = $product->get_price();

// 应用产品级别的折扣
$discounted_price = $this->calculate_product_discount($original_price, $product);

// 应用购物车级别的折扣
foreach ($cart_rules as $rule) {
$discounted_price = $this->apply_cart_rule($discounted_price, $rule, $cart_item);
}

$cart_item['data']->set_price($discounted_price);
}

// 处理BOGO优惠
$this->process_bogo_discounts($cart);
}

/**
* 显示购物车项目折扣
*
* @param string $price_html
* @param array $cart_item
* @param string $cart_item_key
* @return string
*/
public function show_cart_item_discount($price_html, $cart_item, $cart_item_key) {
$product = $cart_item['data'];
$original_price = $product->get_regular_price();
$current_price = $product->get_price();

if ($original_price > $current_price) {
$price_html = sprintf(
'<del>%s</del> <ins>%s</ins>',
wc_price($original_price),
wc_price($current_price)
);
}

return $price_html;
}

/**
* 保存订单折扣信息
*
* @param int $order_id
* @param array $posted_data
* @param WC_Order $order
*/
public function save_order_discounts($order_id, $posted_data, $order) {
$discounts = array();

foreach ($order->get_items() as $item) {
$product = $item->get_product();
$original_price = $product->get_regular_price();
$discounted_price = $item->get_total() / $item->get_quantity();

if ($original_price > $discounted_price) {
$discounts[] = array(
'product_id' => $product->get_id(),
'order_id' => $order_id,
'discount_amount' => $original_price - $discounted_price,
'rule_id' => $this->get_applied_rule_id($product->get_id()),
'applied_date' => current_time('mysql')
);
}
}

if (!empty($discounts)) {
$this->save_discount_records($discounts);
}
}

/**
* 记录已完成订单的统计数据
*
* @param int $order_id
*/
public function record_completed_order_stats($order_id) {
global $wpdb;
$order = wc_get_order($order_id);

if (!$order) {
return;
}

$stats = array(
'order_id' => $order_id,
'total_discount' => $order->get_total_discount(),
'items_count' => $order->get_item_count(),
'customer_id' => $order->get_customer_id(),
'completed_date' => current_time('mysql')
);

$wpdb->insert(
$wpdb->prefix . 'bdfg_order_statistics',
$stats,
array('%d', '%f', '%d', '%d', '%s')
);
}

/**
* 添加产品定价字段
*/
public function add_product_pricing_fields() {
global $product_object;

echo '<div class="options_group pricing bdfg-pricing-options">';

woocommerce_wp_select(array(
'id' => '_bdfg_pricing_rule',
'label' => __('BDFG Pricing Rule', 'bdfg-dynamic-pricing'),
'options' => $this->get_pricing_rules_options(),
'desc_tip' => true,
'description' => __('Select a dynamic pricing rule to apply to this product.', 'bdfg-dynamic-pricing')
));

woocommerce_wp_text_input(array(
'id' => '_bdfg_min_quantity',
'label' => __('Minimum Quantity', 'bdfg-dynamic-pricing'),
'type' => 'number',
'custom_attributes' => array(
'step' => '1',
'min' => '0'
),
'desc_tip' => true,
'description' => __('Minimum quantity required for the pricing rule to apply.', 'bdfg-dynamic-pricing')
));

echo '</div>';
}

/**
* 保存产品定价字段
*
* @param int $post_id
*/
public function save_product_pricing_fields($post_id) {
$rule_id = isset($_POST['_bdfg_pricing_rule']) ? absint($_POST['_bdfg_pricing_rule']) : '';
$min_quantity = isset($_POST['_bdfg_min_quantity']) ? absint($_POST['_bdfg_min_quantity']) : '';

update_post_meta($post_id, '_bdfg_pricing_rule', $rule_id);
update_post_meta($post_id, '_bdfg_min_quantity', $min_quantity);
}

/**
* 获取定价规则选项
*
* @return array
*/
private function get_pricing_rules_options() {
global $wpdb;

$rules = $wpdb->get_results(
"SELECT rule_id, rule_name FROM {$wpdb->prefix}bdfg_discount_rules
WHERE status = 'active'
ORDER BY priority ASC"
);

$options = array('' => __('Select a rule', 'bdfg-dynamic-pricing'));

foreach ($rules as $rule) {
$options[$rule->rule_id] = $rule->rule_name;
}

return $options;
}

/**
* 保存折扣记录
*
* @param array $discounts
*/
private function save_discount_records($discounts) {
global $wpdb;

foreach ($discounts as $discount) {
$wpdb->insert(
$wpdb->prefix . 'bdfg_statistics',
$discount,
array('%d', '%d', '%f', '%d', '%s')
);
}
}

/**
* 处理BOGO折扣
*
* @param WC_Cart $cart
*/
private function process_bogo_discounts($cart) {
$bogo_rules = $this->get_bogo_rules();

foreach ($bogo_rules as $rule) {
$qualifying_items = $this->get_qualifying_items($cart, $rule);

if (!empty($qualifying_items)) {
$this->apply_bogo_discount($cart, $qualifying_items, $rule);
}
}
}

/**
* 记录价格变化
*
* @param int $product_id
* @param float $old_price
* @param float $new_price
*/
private function log_price_change($product_id, $old_price, $new_price) {
if (!$this->is_logging_enabled()) {
return;
}

global $wpdb;

$wpdb->insert(
$wpdb->prefix . 'bdfg_price_history',
array(
'product_id' => $product_id,
'old_price' => $old_price,
'new_price' => $new_price,
'change_date' => current_time('mysql')
),
array('%d', '%f', '%f', '%s')
);
}

/**
* 检查是否启用了日志记录
*
* @return bool
*/
private function is_logging_enabled() {
$settings = get_option('bdfg_settings');
return isset($settings['general']['enable_logging'])
&& $settings['general']['enable_logging'] === 'yes';
}
}

templates/discount-badge.php

<?php
/**
* 折扣标签模板
*
* @package BDFG_Dynamic_Pricing
* @version 2.3.0
*/

defined('ABSPATH') || exit;
?>

<div class="bdfg-discount-badge <?php echo esc_attr($badge_class); ?>">
<?php if ($discount_type === 'percentage'): ?>
<span class="discount-amount">
<?php echo sprintf(
esc_html__('Save %s%%', 'bdfg-dynamic-pricing'),
number_format($discount_amount, 0)
); ?>
</span>
<?php else: ?>
<span class="discount-amount">
<?php echo sprintf(
esc_html__('Save %s', 'bdfg-dynamic-pricing'),
wc_price($discount_amount)
); ?>
</span>
<?php endif; ?>

<?php if (!empty($end_date)): ?>
<span class="discount-timer" data-end="<?php echo esc_attr($end_date); ?>">
<?php esc_html_e('Ends in:', 'bdfg-dynamic-pricing'); ?>
<span class="timer-content"></span>
</span>
<?php endif; ?>
</div>

includes/class-bdfg-cache-manager.php

<?php
/**
* BDFG Dynamic Pricing - Cache Manager
*
* 处理缓存和性能优化
*
* @package BDFG_Dynamic_Pricing
* @since 2.3.0
* @author BeiDuoFengOu
*/

defined('ABSPATH') || exit;

class BDFG_Cache_Manager {
/**
* 缓存组
*/
const CACHE_GROUP = 'bdfg_dynamic_pricing';

/**
* 缓存生命周期(秒)
*/
private $cache_ttl;

/**
* 构造函数
*/
public function __construct() {
$settings = get_option('bdfg_settings');
$this->cache_ttl = isset($settings['advanced']['cache_duration'])
? (int) $settings['advanced']['cache_duration']
: 3600;

add_action('save_post_product', array($this, 'clear_product_cache'), 10, 2);
add_action('woocommerce_update_product', array($this, 'clear_product_cache'), 10, 2);
add_action('bdfg_rule_updated', array($this, 'clear_all_cache'));
}

/**
* 获取缓存的数据
*
* @param string $key
* @return mixed
*/
public function get($key) {
return wp_cache_get($key, self::CACHE_GROUP);
}

/**
* 设置缓存数据
*
* @param string $key
* @param mixed $data
* @return bool
*/
public function set($key, $data) {
return wp_cache_set($key, $data, self::CACHE_GROUP, $this->cache_ttl);
}

/**
* 清除特定产品的缓存
*
* @param int $product_id
* @param WP_Post $post
*/
public function clear_product_cache($product_id, $post) {
wp_cache_delete('product_' . $product_id, self::CACHE_GROUP);
wp_cache_delete('price_' . $product_id, self::CACHE_GROUP);
wp_cache_delete('rules_' . $product_id, self::CACHE_GROUP);
}

/**
* 清除所有缓存
*/
public function clear_all_cache() {
wp_cache_flush();
}

/**
* 生成缓存键
*
* @param string $prefix
* @param mixed $identifier
* @return string
*/
public function generate_key($prefix, $identifier) {
return sprintf('%s_%s', $prefix, md5(serialize($identifier)));
}
}

Leave a Comment