WordPress集成教程:连接主流电商平台与库存管理,通过代码二次开发实现常用互联网小工具功能
引言:WordPress的无限潜能
在当今数字化浪潮中,企业对于在线业务的需求日益复杂和多样化。从简单的展示型网站到功能齐全的电商平台,从内容管理系统到集成多种互联网工具的综合门户,市场对网站的要求越来越高。在这一背景下,WordPress作为全球最受欢迎的内容管理系统,凭借其开源、灵活、可扩展的特性,正成为越来越多企业和开发者的首选平台。
WordPress最初只是一个博客系统,但经过近二十年的发展,它已经演变成一个功能强大的网站构建框架。根据最新统计数据,全球超过43%的网站使用WordPress构建,这一数字在内容管理系统中占据了绝对主导地位。然而,许多用户仅仅利用了WordPress的基础功能,未能充分挖掘其深度集成的潜力。
本教程将深入探讨如何通过WordPress的代码二次开发,实现与主流电商平台的深度集成、高效的库存管理系统,以及常用互联网小工具的定制化功能。无论您是WordPress开发者、电商运营者还是企业技术负责人,都能从本文中找到将您的WordPress网站提升到新水平的方法和思路。
第一部分:WordPress开发基础与环境配置
1.1 WordPress架构概述
要充分发挥WordPress的集成潜力,首先需要理解其核心架构。WordPress采用MVC(模型-视图-控制器)的变体架构,主要由以下几个部分组成:
- 核心文件:WordPress的核心功能文件,通常不应直接修改
- 主题系统:控制网站外观和前端展示
- 插件系统:扩展WordPress功能的模块化组件
- 数据库结构:存储网站内容、设置和用户数据的MySQL/MariaDB数据库
- API系统:包括REST API、XML-RPC等,用于外部系统集成
理解这一架构是进行有效二次开发的基础。WordPress的钩子(Hooks)系统是其扩展性的核心,包括动作(Actions)和过滤器(Filters),允许开发者在特定点插入自定义代码,修改默认行为。
1.2 开发环境搭建
在进行WordPress二次开发前,需要配置合适的开发环境:
- 本地开发环境:推荐使用Local by Flywheel、XAMPP或Docker WordPress开发环境
- 代码编辑器:VS Code、PHPStorm等,配备WordPress代码片段和调试工具
- 版本控制:Git是必须的,配合GitHub、GitLab或Bitbucket
- 调试工具:启用WP_DEBUG、安装Query Monitor插件、使用Xdebug进行PHP调试
- 浏览器开发工具:Chrome DevTools或Firefox Developer Tools
一个典型的本地开发环境配置如下:
# 使用Docker配置WordPress开发环境
docker-compose.yml配置示例:
version: '3.3'
services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: your_password
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
ports:
- "8000:80"
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
volumes:
- ./wp-content:/var/www/html/wp-content
- ./themes/my-theme:/var/www/html/wp-content/themes/my-theme
- ./plugins/my-plugin:/var/www/html/wp-content/plugins/my-plugin
1.3 子主题与自定义插件开发
为了避免主题更新覆盖自定义修改,最佳实践是创建子主题或自定义插件:
创建子主题:
- 在wp-content/themes/目录下创建新文件夹,如my-child-theme
- 创建style.css文件,包含必要的主题信息头
- 创建functions.php文件,用于添加自定义功能
- 通过@import或wp_enqueue_style()引入父主题样式
创建自定义插件:
- 在wp-content/plugins/目录下创建插件文件夹
- 创建主插件文件,包含插件信息头
- 使用面向对象编程(OOP)结构组织代码
- 遵循WordPress编码标准
第二部分:连接主流电商平台
2.1 WooCommerce深度集成
WooCommerce是WordPress最流行的电商插件,但默认功能可能无法满足特定需求。以下是如何通过代码扩展WooCommerce功能的示例:
自定义产品类型:
// 注册新的产品类型
add_action('init', 'register_custom_product_type');
function register_custom_product_type() {
class WC_Product_Custom extends WC_Product {
public function __construct($product) {
$this->product_type = 'custom';
parent::__construct($product);
}
public function get_type() {
return 'custom';
}
// 添加自定义方法
public function get_custom_price() {
return get_post_meta($this->id, '_custom_price', true);
}
}
}
// 在产品类型选择中添加自定义类型
add_filter('product_type_selector', 'add_custom_product_type');
function add_custom_product_type($types) {
$types['custom'] = __('自定义产品', 'text-domain');
return $types;
}
与第三方支付网关集成:
// 创建自定义支付网关
add_filter('woocommerce_payment_gateways', 'add_custom_gateway');
function add_custom_gateway($gateways) {
$gateways[] = 'WC_Custom_Gateway';
return $gateways;
}
// 自定义支付网关类
class WC_Custom_Gateway extends WC_Payment_Gateway {
public function __construct() {
$this->id = 'custom_gateway';
$this->method_title = '自定义支付网关';
$this->method_description = '通过自定义API接口处理支付';
$this->has_fields = true;
$this->init_form_fields();
$this->init_settings();
$this->title = $this->get_option('title');
$this->description = $this->get_option('description');
$this->api_key = $this->get_option('api_key');
add_action('woocommerce_update_options_payment_gateways_' . $this->id, array($this, 'process_admin_options'));
}
public function process_payment($order_id) {
$order = wc_get_order($order_id);
// 调用第三方支付API
$api_response = $this->call_payment_api($order);
if ($api_response['success']) {
// 支付成功
$order->payment_complete();
wc_reduce_stock_levels($order_id);
return array(
'result' => 'success',
'redirect' => $this->get_return_url($order)
);
} else {
// 支付失败
wc_add_notice('支付失败: ' . $api_response['message'], 'error');
return;
}
}
private function call_payment_api($order) {
// 实现与第三方支付API的通信逻辑
// 返回包含success和message的数组
}
}
2.2 与Shopify、Magento等平台的数据同步
对于多平台运营的企业,保持数据同步至关重要。以下是实现WordPress与Shopify数据同步的示例:
产品数据同步:
// Shopify产品同步类
class Shopify_Product_Sync {
private $api_key;
private $api_secret;
private $store_url;
public function __construct($api_key, $api_secret, $store_url) {
$this->api_key = $api_key;
$this->api_secret = $api_secret;
$this->store_url = $store_url;
}
// 从Shopify获取产品
public function fetch_products_from_shopify() {
$url = "https://{$this->api_key}:{$this->api_secret}@{$this->store_url}/admin/api/2023-01/products.json";
$response = wp_remote_get($url, array(
'timeout' => 30,
'headers' => array(
'Content-Type' => 'application/json',
)
));
if (is_wp_error($response)) {
error_log('Shopify API错误: ' . $response->get_error_message());
return false;
}
$body = wp_remote_retrieve_body($response);
$products = json_decode($body, true);
return $products['products'] ?? array();
}
// 同步产品到WooCommerce
public function sync_to_woocommerce($shopify_products) {
foreach ($shopify_products as $shopify_product) {
// 检查产品是否已存在
$existing_product_id = $this->find_existing_product($shopify_product['id'], 'shopify');
if ($existing_product_id) {
// 更新现有产品
$this->update_woocommerce_product($existing_product_id, $shopify_product);
} else {
// 创建新产品
$this->create_woocommerce_product($shopify_product);
}
}
}
private function create_woocommerce_product($shopify_product) {
$product = new WC_Product();
$product->set_name($shopify_product['title']);
$product->set_description($shopify_product['body_html']);
$product->set_short_description($this->extract_excerpt($shopify_product['body_html']));
$product->set_regular_price($shopify_product['variants'][0]['price']);
$product->set_sku($shopify_product['variants'][0]['sku']);
$product->set_stock_quantity($shopify_product['variants'][0]['inventory_quantity']);
// 保存Shopify ID作为元数据,用于后续同步
$product_id = $product->save();
update_post_meta($product_id, '_shopify_product_id', $shopify_product['id']);
update_post_meta($product_id, '_shopify_variant_id', $shopify_product['variants'][0]['id']);
// 处理产品图片
$this->process_product_images($product_id, $shopify_product['images']);
return $product_id;
}
}
订单数据同步:
// 双向订单同步
class Order_Sync_Manager {
public function sync_new_orders() {
// 从WooCommerce获取新订单
$new_orders = wc_get_orders(array(
'limit' => 50,
'status' => array('processing', 'completed'),
'meta_key' => '_synced_to_external',
'meta_compare' => 'NOT EXISTS'
));
foreach ($new_orders as $order) {
$this->sync_order_to_external($order);
update_post_meta($order->get_id(), '_synced_to_external', current_time('mysql'));
}
// 从外部平台获取新订单
$external_orders = $this->fetch_external_orders();
foreach ($external_orders as $external_order) {
$this->create_order_from_external($external_order);
}
}
private function sync_order_to_external($order) {
// 实现将订单同步到Shopify、Magento等平台的逻辑
$order_data = array(
'order_id' => $order->get_id(),
'customer_email' => $order->get_billing_email(),
'total' => $order->get_total(),
'items' => array()
);
foreach ($order->get_items() as $item) {
$order_data['items'][] = array(
'product_id' => $item->get_product_id(),
'quantity' => $item->get_quantity(),
'price' => $item->get_total()
);
}
// 发送到外部平台API
// $this->call_external_api('orders', $order_data);
}
}
2.3 使用REST API实现跨平台通信
WordPress REST API为跨平台集成提供了强大支持:
自定义REST API端点:
// 注册自定义REST API端点
add_action('rest_api_init', 'register_custom_api_endpoints');
function register_custom_api_endpoints() {
// 产品同步端点
register_rest_route('custom-api/v1', '/sync-products', array(
'methods' => 'POST',
'callback' => 'handle_product_sync',
'permission_callback' => 'validate_api_request'
));
// 库存检查端点
register_rest_route('custom-api/v1', '/check-inventory/(?P<sku>[a-zA-Z0-9-]+)', array(
'methods' => 'GET',
'callback' => 'handle_inventory_check',
'permission_callback' => 'validate_api_request'
));
// 订单状态更新端点
register_rest_route('custom-api/v1', '/update-order-status', array(
'methods' => 'PUT',
'callback' => 'handle_order_status_update',
'permission_callback' => 'validate_api_request'
));
}
// API请求验证
function validate_api_request($request) {
$api_key = $request->get_header('X-API-Key');
$valid_key = get_option('custom_api_key');
if (!$api_key || $api_key !== $valid_key) {
return new WP_Error('rest_forbidden', '无效的API密钥', array('status' => 403));
}
return true;
}
// 处理产品同步
function handle_product_sync($request) {
$parameters = $request->get_json_params();
$products = $parameters['products'] ?? array();
$results = array();
foreach ($products as $product_data) {
$result = sync_single_product($product_data);
$results[] = $result;
}
return new WP_REST_Response(array(
'success' => true,
'synced_count' => count($results),
'results' => $results
), 200);
}
// 库存检查处理
function handle_inventory_check($request) {
$sku = $request['sku'];
$product_id = wc_get_product_id_by_sku($sku);
if (!$product_id) {
return new WP_Error('not_found', '产品未找到', array('status' => 404));
}
$product = wc_get_product($product_id);
$stock_quantity = $product->get_stock_quantity();
$stock_status = $product->get_stock_status();
return new WP_REST_Response(array(
'sku' => $sku,
'product_id' => $product_id,
'stock_quantity' => $stock_quantity,
'stock_status' => $stock_status,
'in_stock' => $stock_status === 'instock'
), 200);
}
第三部分:库存管理系统集成与优化
3.1 实时库存同步机制
库存管理是电商运营的核心环节。以下是实现实时库存同步的完整方案:
库存变更监听与同步:
// 监听库存变化并同步到外部系统
class Inventory_Sync_Manager {
private $external_systems = array();
public function __construct() {
$this->init_hooks();
$this->load_external_systems();
}
private function init_hooks() {
// WooCommerce库存变化钩子
add_action('woocommerce_product_set_stock', array($this, 'on_stock_change'), 10, 1);
add_action('woocommerce_variation_set_stock', array($this, 'on_stock_change'), 10, 1);
// 订单状态变化钩子
add_action('woocommerce_order_status_changed', array($this, 'on_order_status_change'), 10, 4);
// 计划任务,定期同步库存
add_action('init', array($this, 'schedule_inventory_sync'));
add_action('daily_inventory_sync', array($this, 'full_inventory_sync'));
}
public function on_stock_change($product) {
if (!$product || !is_a($product, 'WC_Product')) {
return;
}
$product_id = $product->get_id();
$sku = $product->get_sku();
$stock_quantity = $product->get_stock_quantity();
$stock_status = $product->get_stock_status();
$inventory_data = array(
'product_id' => $product_id,
'sku' => $sku,
'quantity' => $stock_quantity,
'status' => $stock_status,
'timestamp' => current_time('mysql'),
'change_type' => 'manual_update'
);
// 记录库存变化
$this->log_inventory_change($inventory_data);
// 同步到所有外部系统
$this->sync_to_all_external_systems($inventory_data);
}
public function on_order_status_change($order_id, $old_status, $new_status, $order) {
// 订单状态影响库存的逻辑
$statuses_that_reduce_stock = array('processing', 'completed');
$statuses_that_restore_stock = array('cancelled', 'refunded');
if (in_array($new_status, $statuses_that_reduce_stock) &&
!in_array($old_status, $statuses_that_reduce_stock)) {
// 减少库存
$this->adjust_inventory_for_order($order, 'decrease');
} elseif (in_array($new_status, $statuses_that_restore_stock) &&
in_array($old_status, $statuses_that_reduce_stock)) {
// 恢复库存
$this->adjust_inventory_for_order($order, 'increase');
}
}
3.2 多仓库库存管理
对于拥有多个仓库或销售渠道的企业,需要更复杂的库存管理系统:
多仓库库存类:
class Multi_Warehouse_Inventory {
private $warehouses = array();
public function __construct() {
$this->load_warehouses();
add_action('woocommerce_product_options_inventory_product_data', array($this, 'add_warehouse_inventory_fields'));
add_action('woocommerce_process_product_meta', array($this, 'save_warehouse_inventory_data'));
add_filter('woocommerce_product_get_stock_quantity', array($this, 'get_total_stock_quantity'), 10, 2);
}
private function load_warehouses() {
// 从数据库加载仓库配置
$this->warehouses = get_option('custom_warehouses', array(
'main' => array('name' => '主仓库', 'location' => '上海'),
'north' => array('name' => '北方仓库', 'location' => '北京'),
'south' => array('name' => '南方仓库', 'location' => '广州')
));
}
public function add_warehouse_inventory_fields() {
global $product_object;
echo '<div class="options_group warehouse-inventory">';
echo '<h4>多仓库库存管理</h4>';
foreach ($this->warehouses as $warehouse_id => $warehouse) {
woocommerce_wp_text_input(array(
'id' => "_warehouse_{$warehouse_id}_stock",
'label' => $warehouse['name'] . '库存',
'desc_tip' => true,
'description' => $warehouse['location'] . '仓库的库存数量',
'type' => 'number',
'custom_attributes' => array(
'step' => '1',
'min' => '0'
),
'value' => get_post_meta($product_object->get_id(), "_warehouse_{$warehouse_id}_stock", true)
));
// 安全库存设置
woocommerce_wp_text_input(array(
'id' => "_warehouse_{$warehouse_id}_safety_stock",
'label' => $warehouse['name'] . '安全库存',
'desc_tip' => true,
'description' => '触发补货提醒的最小库存量',
'type' => 'number',
'custom_attributes' => array(
'step' => '1',
'min' => '0'
),
'value' => get_post_meta($product_object->get_id(), "_warehouse_{$warehouse_id}_safety_stock", true)
));
}
echo '</div>';
}
public function save_warehouse_inventory_data($product_id) {
foreach ($this->warehouses as $warehouse_id => $warehouse) {
if (isset($_POST["_warehouse_{$warehouse_id}_stock"])) {
$stock = intval($_POST["_warehouse_{$warehouse_id}_stock"]);
update_post_meta($product_id, "_warehouse_{$warehouse_id}_stock", $stock);
}
if (isset($_POST["_warehouse_{$warehouse_id}_safety_stock"])) {
$safety_stock = intval($_POST["_warehouse_{$warehouse_id}_safety_stock"]);
update_post_meta($product_id, "_warehouse_{$warehouse_id}_safety_stock", $safety_stock);
}
}
// 更新总库存
$this->update_total_stock($product_id);
}
public function get_total_stock_quantity($quantity, $product) {
// 计算所有仓库的总库存
$total_stock = 0;
foreach ($this->warehouses as $warehouse_id => $warehouse) {
$warehouse_stock = get_post_meta($product->get_id(), "_warehouse_{$warehouse_id}_stock", true);
$total_stock += intval($warehouse_stock);
}
return $total_stock > 0 ? $total_stock : $quantity;
}
private function update_total_stock($product_id) {
$total_stock = 0;
foreach ($this->warehouses as $warehouse_id => $warehouse) {
$warehouse_stock = get_post_meta($product_id, "_warehouse_{$warehouse_id}_stock", true);
$total_stock += intval($warehouse_stock);
}
// 更新WooCommerce库存
$product = wc_get_product($product_id);
if ($product && $product->managing_stock()) {
$product->set_stock_quantity($total_stock);
$product->save();
}
}
// 智能分配库存
public function allocate_stock_for_order($order, $product_id, $quantity) {
$warehouse_allocation = array();
$remaining_quantity = $quantity;
// 按优先级分配库存(例如:按距离、库存量等)
$priority_warehouses = $this->get_priority_warehouses($order);
foreach ($priority_warehouses as $warehouse_id) {
$available_stock = get_post_meta($product_id, "_warehouse_{$warehouse_id}_stock", true);
$allocated = min($available_stock, $remaining_quantity);
if ($allocated > 0) {
$warehouse_allocation[$warehouse_id] = $allocated;
$remaining_quantity -= $allocated;
// 更新仓库库存
$new_stock = $available_stock - $allocated;
update_post_meta($product_id, "_warehouse_{$warehouse_id}_stock", $new_stock);
// 检查是否需要补货
$this->check_reorder_point($product_id, $warehouse_id, $new_stock);
}
if ($remaining_quantity <= 0) break;
}
if ($remaining_quantity > 0) {
// 库存不足,触发缺货通知
$this->trigger_out_of_stock_notification($product_id, $remaining_quantity);
}
return $warehouse_allocation;
}
private function get_priority_warehouses($order) {
// 根据订单地址确定最优仓库
$shipping_address = $order->get_shipping_address_1();
$shipping_city = $order->get_shipping_city();
// 简化的距离计算逻辑(实际应使用地理编码API)
$warehouse_distances = array();
foreach ($this->warehouses as $warehouse_id => $warehouse) {
$distance = $this->calculate_distance($shipping_city, $warehouse['location']);
$warehouse_distances[$warehouse_id] = $distance;
}
asort($warehouse_distances); // 按距离升序排序
return array_keys($warehouse_distances);
}
}
3.3 库存预警与自动补货系统
库存监控与预警类:
class Inventory_Monitoring_System {
private $alert_thresholds = array();
public function __construct() {
$this->alert_thresholds = array(
'critical' => 0.1, // 库存低于10%时发送紧急警报
'warning' => 0.3, // 库存低于30%时发送警告
'info' => 0.5 // 库存低于50%时发送通知
);
// 设置定时任务
add_action('init', array($this, 'schedule_inventory_checks'));
add_action('hourly_inventory_check', array($this, 'check_inventory_levels'));
add_action('daily_inventory_report', array($this, 'generate_inventory_report'));
}
public function schedule_inventory_checks() {
if (!wp_next_scheduled('hourly_inventory_check')) {
wp_schedule_event(time(), 'hourly', 'hourly_inventory_check');
}
if (!wp_next_scheduled('daily_inventory_report')) {
wp_schedule_event(time(), 'daily', 'daily_inventory_report');
}
}
public function check_inventory_levels() {
$products = wc_get_products(array(
'limit' => -1,
'status' => 'publish',
'stock_status' => 'instock'
));
foreach ($products as $product) {
$this->check_single_product_inventory($product);
}
}
private function check_single_product_inventory($product) {
$product_id = $product->get_id();
$current_stock = $product->get_stock_quantity();
$max_stock = get_post_meta($product_id, '_max_stock_level', true);
if (!$max_stock) {
// 如果没有设置最大库存,使用最近30天的平均销量×2
$max_stock = $this->calculate_max_stock($product_id);
update_post_meta($product_id, '_max_stock_level', $max_stock);
}
$stock_ratio = $current_stock / $max_stock;
// 检查库存水平并触发相应警报
foreach ($this->alert_thresholds as $level => $threshold) {
if ($stock_ratio <= $threshold) {
$this->send_inventory_alert($product, $level, $stock_ratio);
break;
}
}
// 检查是否需要自动补货
if ($stock_ratio <= 0.2) { // 库存低于20%时触发补货
$this->initiate_reorder($product, $max_stock - $current_stock);
}
}
private function calculate_max_stock($product_id) {
// 计算最近30天的平均日销量
global $wpdb;
$thirty_days_ago = date('Y-m-d', strtotime('-30 days'));
$sales_data = $wpdb->get_row($wpdb->prepare("
SELECT SUM(oi.quantity) as total_sold
FROM {$wpdb->prefix}woocommerce_order_items oi
LEFT JOIN {$wpdb->prefix}woocommerce_order_itemmeta oim ON oi.order_item_id = oim.order_item_id
LEFT JOIN {$wpdb->posts} p ON oi.order_id = p.ID
WHERE oi.order_item_type = 'line_item'
AND oim.meta_key = '_product_id'
AND oim.meta_value = %d
AND p.post_date >= %s
AND p.post_status IN ('wc-completed', 'wc-processing')
", $product_id, $thirty_days_ago));
$total_sold = $sales_data->total_sold ?: 0;
$average_daily_sales = $total_sold / 30;
// 最大库存 = 平均日销量 × 补货周期(假设14天)× 安全系数(1.5)
return ceil($average_daily_sales * 14 * 1.5);
}
private function send_inventory_alert($product, $level, $stock_ratio) {
$product_name = $product->get_name();
$current_stock = $product->get_stock_quantity();
$sku = $product->get_sku();
$alert_messages = array(
'critical' => "紧急:产品 {$product_name} (SKU: {$sku}) 库存严重不足!当前库存:{$current_stock},库存率:".round($stock_ratio*100,1)."%",
'warning' => "警告:产品 {$product_name} (SKU: {$sku}) 库存偏低。当前库存:{$current_stock},库存率:".round($stock_ratio*100,1)."%",
'info' => "通知:产品 {$product_name} (SKU: {$sku}) 库存量中等。当前库存:{$current_stock},库存率:".round($stock_ratio*100,1)."%"
);
$message = $alert_messages[$level] ?? "产品 {$product_name} 库存状态异常";
// 发送邮件通知
$this->send_email_alert($message, $level);
// 发送Slack/钉钉通知
$this->send_im_alert($message, $level);
// 记录到数据库
$this->log_alert($product->get_id(), $level, $message);
}
private function initiate_reorder($product, $reorder_quantity) {
$product_id = $product->get_id();
$product_name = $product->get_name();
$sku = $product->get_sku();
// 检查是否已有待处理的补货单
$existing_reorder = get_posts(array(
'post_type' => 'reorder',
'meta_key' => '_product_id',
'meta_value' => $product_id,
'post_status' => array('pending', 'processing')
));
if (empty($existing_reorder)) {
// 创建补货单
$reorder_id = wp_insert_post(array(
'post_type' => 'reorder',
'post_title' => "补货单 - {$product_name}",
'post_status' => 'pending',
'post_content' => "自动生成的补货单,产品:{$product_name},补货数量:{$reorder_quantity}"
));
update_post_meta($reorder_id, '_product_id', $product_id);
update_post_meta($reorder_id, '_product_sku', $sku);
update_post_meta($reorder_id, '_reorder_quantity', $reorder_quantity);
update_post_meta($reorder_id, '_reorder_date', current_time('mysql'));
update_post_meta($reorder_id, '_reorder_status', 'pending');
// 通知采购部门
$this->notify_purchasing_department($reorder_id, $product, $reorder_quantity);
}
}
}
第四部分:常用互联网小工具功能实现
4.1 实时汇率计算器
汇率计算器小工具:
class Currency_Converter_Widget extends WP_Widget {
public function __construct() {
parent::__construct(
'currency_converter',
'实时汇率计算器',
array('description' => '显示实时汇率转换工具')
);
// 添加短代码支持
add_shortcode('currency_converter', array($this, 'shortcode_handler'));
// 注册AJAX处理
add_action('wp_ajax_convert_currency', array($this, 'ajax_convert_currency'));
add_action('wp_ajax_nopriv_convert_currency', array($this, 'ajax_convert_currency'));
}
public function widget($args, $instance) {
echo $args['before_widget'];
if (!empty($instance['title'])) {
echo $args['before_title'] . apply_filters('widget_title', $instance['title']) . $args['after_title'];
}
$this->render_converter_form();
echo $args['after_widget'];
}
private function render_converter_form() {
$currencies = $this->get_available_currencies();
$default_from = $instance['default_from'] ?? 'USD';
$default_to = $instance['default_to'] ?? 'CNY';
?>
<div class="currency-converter-widget">
<form id="currency-converter-form" method="post">
<div class="converter-input-group">
<input type="number"
id="amount"
name="amount"
placeholder="输入金额"
step="0.01"
min="0"
required>
<select id="from_currency" name="from_currency">
<?php foreach ($currencies as $code => $name): ?>
<option value="<?php echo esc_attr($code); ?>"
<?php selected($code, $default_from); ?>>
<?php echo esc_html("{$code} - {$name}"); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="converter-swap">
<button type="button" id="swap-currencies" class="swap-button">
<span class="dashicons dashicons-sort"></span>
</button>
</div>
<div class="converter-input-group">
<input type="text"
id="converted_amount"
name="converted_amount"
placeholder="转换结果"
readonly>
<select id="to_currency" name="to_currency">
<?php foreach ($currencies as $code => $name): ?>
<option value="<?php echo esc_attr($code); ?>"
<?php selected($code, $default_to); ?>>
<?php echo esc_html("{$code} - {$name}"); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="converter-info">
<p id="exchange-rate-info">汇率: 加载中...</p>
<p id="last-updated">最后更新: --</p>
</div>
<button type="submit" class="convert-button">转换</button>
</form>
<div id="conversion-history" class="conversion-history">
<h4>最近转换记录</h4>
<ul id="history-list"></ul>
</div>
</div>
<style>
.currency-converter-widget {
padding: 15px;
background: #f9f9f9;
border-radius: 8px;
}
.converter-input-group {
display: flex;
margin-bottom: 10px;
}
.converter-input-group input {
flex: 2;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px 0 0 4px;
