首页 / 教程文章 / WordPress文创插件实现柔性产品配置器开发的详细教程

WordPress文创插件实现柔性产品配置器开发的详细教程

WordPress文创插件实现柔性产品配置器开发详细教程

一、项目概述与准备工作

1.1 什么是柔性产品配置器

柔性产品配置器是一种允许用户自定义文创产品的交互工具。在WordPress电商场景中,这种配置器可以让客户选择不同的产品选项(如颜色、尺寸、材质、图案等),实时预览效果并生成个性化订单。这对于销售定制T恤、马克杯、手机壳等文创产品的网站尤为重要。

1.2 开发环境准备

在开始开发前,请确保您的环境满足以下要求:

  1. WordPress 5.0+ 版本
  2. PHP 7.4+ 版本
  3. MySQL 5.6+ 或 MariaDB 10.1+
  4. 基本的HTML、CSS、JavaScript知识
  5. 代码编辑器(如VS Code、Sublime Text等)

1.3 插件基础结构

首先,我们需要创建插件的基本文件结构:

wp-content/plugins/
└── flexible-product-configurator/
    ├── flexible-product-configurator.php
    ├── includes/
    │   ├── class-configurator.php
    │   ├── class-ajax-handler.php
    │   └── class-admin.php
    ├── assets/
    │   ├── css/
    │   │   ├── frontend.css
    │   │   └── admin.css
    │   └── js/
    │       ├── frontend.js
    │       └── admin.js
    ├── templates/
    │   ├── configurator-frontend.php
    │   └── configurator-admin.php
    └── languages/

二、创建主插件文件

2.1 插件头部信息

首先创建主插件文件 flexible-product-configurator.php

<?php
/**
 * Plugin Name: Flexible Product Configurator
 * Plugin URI: https://yourwebsite.com/flexible-product-configurator
 * Description: 文创产品柔性配置器,允许用户自定义产品选项
 * Version: 1.0.0
 * Author: Your Name
 * Author URI: https://yourwebsite.com
 * License: GPL v2 or later
 * Text Domain: flexible-product-configurator
 * Domain Path: /languages
 */

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

// 定义插件常量
define('FPC_VERSION', '1.0.0');
define('FPC_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('FPC_PLUGIN_URL', plugin_dir_url(__FILE__));
define('FPC_PLUGIN_BASENAME', plugin_basename(__FILE__));

// 自动加载类文件
spl_autoload_register(function ($class) {
    $prefix = 'FPC_';
    $base_dir = FPC_PLUGIN_DIR . 'includes/';
    
    $len = strlen($prefix);
    if (strncmp($prefix, $class, $len) !== 0) {
        return;
    }
    
    $relative_class = substr($class, $len);
    $file = $base_dir . 'class-' . strtolower(str_replace('_', '-', $relative_class)) . '.php';
    
    if (file_exists($file)) {
        require $file;
    }
});

// 初始化插件
function fpc_init() {
    // 检查WooCommerce是否激活
    if (!class_exists('WooCommerce')) {
        add_action('admin_notices', function() {
            echo '<div class="notice notice-error"><p>';
            echo __('柔性产品配置器需要WooCommerce插件支持,请先安装并激活WooCommerce。', 'flexible-product-configurator');
            echo '</p></div>';
        });
        return;
    }
    
    // 初始化核心类
    FPC_Configurator::get_instance();
    FPC_Ajax_Handler::get_instance();
    
    if (is_admin()) {
        FPC_Admin::get_instance();
    }
}
add_action('plugins_loaded', 'fpc_init');

// 插件激活钩子
register_activation_hook(__FILE__, 'fpc_activate');
function fpc_activate() {
    // 创建必要的数据库表
    global $wpdb;
    $charset_collate = $wpdb->get_charset_collate();
    $table_name = $wpdb->prefix . 'fpc_product_configs';
    
    $sql = "CREATE TABLE IF NOT EXISTS $table_name (
        id mediumint(9) NOT NULL AUTO_INCREMENT,
        product_id bigint(20) NOT NULL,
        user_id bigint(20) DEFAULT NULL,
        config_data longtext NOT NULL,
        preview_image varchar(255) DEFAULT NULL,
        created_at datetime DEFAULT CURRENT_TIMESTAMP,
        PRIMARY KEY (id),
        KEY product_id (product_id),
        KEY user_id (user_id)
    ) $charset_collate;";
    
    require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
    dbDelta($sql);
    
    // 添加版本号
    add_option('fpc_version', FPC_VERSION);
}

// 插件停用钩子
register_deactivation_hook(__FILE__, 'fpc_deactivate');
function fpc_deactivate() {
    // 清理临时数据
    wp_clear_scheduled_hook('fpc_daily_cleanup');
}

三、核心配置器类实现

3.1 配置器主类

创建 includes/class-configurator.php

<?php
/**
 * 柔性产品配置器核心类
 */
class FPC_Configurator {
    
    private static $instance = null;
    private $enabled_products = array();
    
    public static function get_instance() {
        if (null === self::$instance) {
            self::$instance = new self();
        }
        return self::$instance;
    }
    
    private function __construct() {
        // 初始化钩子
        add_action('init', array($this, 'init'));
        add_action('wp_enqueue_scripts', array($this, 'enqueue_scripts'));
        add_shortcode('product_configurator', array($this, 'render_configurator'));
        
        // 添加到产品页面
        add_action('woocommerce_before_add_to_cart_button', array($this, 'add_configurator_to_product'));
    }
    
    /**
     * 初始化配置器
     */
    public function init() {
        // 注册配置器选项
        $this->register_option_types();
        
        // 加载文本域
        load_plugin_textdomain(
            'flexible-product-configurator',
            false,
            dirname(FPC_PLUGIN_BASENAME) . '/languages'
        );
    }
    
    /**
     * 注册选项类型
     */
    private function register_option_types() {
        // 这里定义不同类型的配置选项
        $this->option_types = array(
            'color' => array(
                'label' => __('颜色选择', 'flexible-product-configurator'),
                'template' => 'color-selector',
                'has_preview' => true
            ),
            'text' => array(
                'label' => __('文本定制', 'flexible-product-configurator'),
                'template' => 'text-input',
                'has_preview' => true
            ),
            'image' => array(
                'label' => __('图片上传', 'flexible-product-configurator'),
                'template' => 'image-upload',
                'has_preview' => true
            ),
            'dropdown' => array(
                'label' => __('下拉选择', 'flexible-product-configurator'),
                'template' => 'dropdown-select',
                'has_preview' => true
            ),
            'checkbox' => array(
                'label' => __('复选框', 'flexible-product-configurator'),
                'template' => 'checkbox-group',
                'has_preview' => false
            )
        );
    }
    
    /**
     * 加载前端脚本和样式
     */
    public function enqueue_scripts() {
        if (is_product()) {
            global $product;
            
            // 检查产品是否启用配置器
            if ($this->is_product_configurable($product->get_id())) {
                // 加载CSS
                wp_enqueue_style(
                    'fpc-frontend',
                    FPC_PLUGIN_URL . 'assets/css/frontend.css',
                    array(),
                    FPC_VERSION
                );
                
                // 加载JavaScript
                wp_enqueue_script(
                    'fpc-fabric',
                    'https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.5.0/fabric.min.js',
                    array(),
                    '4.5.0',
                    true
                );
                
                wp_enqueue_script(
                    'fpc-frontend',
                    FPC_PLUGIN_URL . 'assets/js/frontend.js',
                    array('jquery', 'fpc-fabric'),
                    FPC_VERSION,
                    true
                );
                
                // 本地化脚本
                wp_localize_script('fpc-frontend', 'fpc_ajax', array(
                    'ajax_url' => admin_url('admin-ajax.php'),
                    'nonce' => wp_create_nonce('fpc_nonce'),
                    'product_id' => $product->get_id(),
                    'text' => array(
                        'loading' => __('加载中...', 'flexible-product-configurator'),
                        'saving' => __('保存配置...', 'flexible-product-configurator'),
                        'error' => __('发生错误,请重试', 'flexible-product-configurator')
                    )
                ));
            }
        }
    }
    
    /**
     * 检查产品是否可配置
     */
    public function is_product_configurable($product_id) {
        if (empty($this->enabled_products)) {
            $this->enabled_products = get_posts(array(
                'post_type' => 'product',
                'meta_key' => '_fpc_enabled',
                'meta_value' => 'yes',
                'fields' => 'ids',
                'posts_per_page' => -1
            ));
        }
        
        return in_array($product_id, $this->enabled_products);
    }
    
    /**
     * 渲染配置器短代码
     */
    public function render_configurator($atts) {
        $atts = shortcode_atts(array(
            'product_id' => 0,
            'width' => '100%',
            'height' => '500px'
        ), $atts, 'product_configurator');
        
        if (!$atts['product_id']) {
            global $product;
            if ($product) {
                $atts['product_id'] = $product->get_id();
            }
        }
        
        if (!$this->is_product_configurable($atts['product_id'])) {
            return '<p>' . __('此产品不支持配置', 'flexible-product-configurator') . '</p>';
        }
        
        ob_start();
        include FPC_PLUGIN_DIR . 'templates/configurator-frontend.php';
        return ob_get_clean();
    }
    
    /**
     * 添加到产品页面
     */
    public function add_configurator_to_product() {
        global $product;
        
        if ($this->is_product_configurable($product->get_id())) {
            echo do_shortcode('[product_configurator product_id="' . $product->get_id() . '"]');
        }
    }
    
    /**
     * 获取产品配置选项
     */
    public function get_product_options($product_id) {
        $options = get_post_meta($product_id, '_fpc_options', true);
        
        if (empty($options)) {
            $options = array(
                'base_image' => '',
                'areas' => array(),
                'options' => array()
            );
        }
        
        return $options;
    }
}

四、前端交互实现

4.1 前端JavaScript核心

创建 assets/js/frontend.js

/**
 * 柔性产品配置器前端交互
 */
(function($) {
    'use strict';
    
    var FPC_Frontend = {
        // 初始化变量
        canvas: null,
        fabricCanvas: null,
        currentProductId: 0,
        currentConfig: {},
        isSaving: false,
        
        /**
         * 初始化配置器
         */
        init: function() {
            this.currentProductId = fpc_ajax.product_id;
            this.setupCanvas();
            this.loadProductConfig();
            this.bindEvents();
        },
        
        /**
         * 设置Canvas画布
         */
        setupCanvas: function() {
            this.canvas = document.getElementById('fpc-canvas');
            
            if (!this.canvas) {
                console.error('Canvas元素未找到');
                return;
            }
            
            // 初始化Fabric.js画布
            this.fabricCanvas = new fabric.Canvas('fpc-canvas', {
                backgroundColor: '#f5f5f5',
                preserveObjectStacking: true
            });
            
            // 设置画布尺寸
            this.resizeCanvas();
            $(window).on('resize', this.resizeCanvas.bind(this));
        },
        
        /**
         * 调整画布尺寸
         */
        resizeCanvas: function() {
            var container = $('#fpc-canvas-container');
            var width = container.width();
            var height = container.height() || 500;
            
            this.fabricCanvas.setDimensions({
                width: width,
                height: height
            });
            
            this.fabricCanvas.calcOffset();
        },
        
        /**
         * 加载产品配置
         */
        loadProductConfig: function() {
            var self = this;
            
            $.ajax({
                url: fpc_ajax.ajax_url,
                type: 'POST',
                data: {
                    action: 'fpc_get_product_config',
                    nonce: fpc_ajax.nonce,
                    product_id: this.currentProductId
                },
                beforeSend: function() {
                    $('#fpc-loading').show();
                },
                success: function(response) {
                    if (response.success) {
                        self.currentConfig = response.data;
                        self.renderProduct();
                        self.renderOptions();
                    } else {
                        self.showError(response.data);
                    }
                },
                error: function() {
                    self.showError(fpc_ajax.text.error);
                },
                complete: function() {
                    $('#fpc-loading').hide();
                }
            });
        },
        
        /**
         * 渲染产品基础图像
         */
        renderProduct: function() {
            var self = this;
            
            if (!this.currentConfig.base_image) {
                return;
            }
            
            // 加载基础图像
            fabric.Image.fromURL(this.currentConfig.base_image, function(img) {
                // 设置图像为背景
                img.set({
                    selectable: false,
                    evented: false,
                    hasControls: false,
                    hasBorders: false
                });
                
                // 调整图像尺寸以适应画布
                var scale = Math.min(
                    self.fabricCanvas.width / img.width,
                    self.fabricCanvas.height / img.height
                );
                
                img.scale(scale);
                img.set({
                    left: (self.fabricCanvas.width - img.width * scale) / 2,
                    top: (self.fabricCanvas.height - img.height * scale) / 2
                });
                
                self.fabricCanvas.setBackgroundImage(img, self.fabricCanvas.renderAll.bind(self.fabricCanvas));
                
                // 渲染可配置区域
                self.renderConfigurableAreas();
            });
        },
        
        /**
         * 渲染可配置区域
         */
        renderConfigurableAreas: function() {
            if (!this.currentConfig.areas || !Array.isArray(this.currentConfig.areas)) {
                return;
            }
            
            var self = this;
            
            this.currentConfig.areas.forEach(function(area, index) {
                if (area.type === 'text') {
                    self.addTextArea(area, index);
                } else if (area.type === 'image') {
                    self.addImageArea(area, index);
                }
            });
        },
        
        /**
         * 添加文本区域
         */
        addTextArea: function(area, index) {
            var text = new fabric.Textbox(area.default_text || '点击编辑文本', {
                left: area.x,
                top: area.y,
                width: area.width,
                fontSize: area.font_size || 20,
                fontFamily: area.font_family || 'Arial',
                fill: area.color || '#000000',
                textAlign: area.align || 'left',
                editable: true,
                hasControls: true,
                lockScalingFlip: true,
                data: {
                    areaIndex: index,
                    type: 'text'
                }
            });
            
            // 添加文本变化事件
            text.on('changed', this.onTextChanged.bind(this));
            
            this.fabricCanvas.add(text);
        },
        
        /**
         * 文本变化处理
         */
        onTextChanged: function(e) {
            var target = e.target;
            var areaIndex = target.data.areaIndex;
            
            if (this.currentConfig.areas[areaIndex]) {
                this.currentConfig.areas[areaIndex].current_text = target.text;
                this.updatePreview();
            }
        },
        
        /**
         * 渲染配置选项
         */
        renderOptions: function() {
            if (!this.currentConfig.options || !Array.isArray(this.currentConfig.options)) {
                return;
            }
            
            var $optionsContainer = $('#fpc-options');
            $optionsContainer.empty();
            
            this.currentConfig.options.forEach(function(option, index) {
                var $option = $('<div class="fpc-option"></div>');
                $option.append('<h4>' + option.label + '</h4>');
                
                switch (option.type) {
                    case 'color':
                        this.renderColorOption(option, index, $option);
                        break;
                    case 'dropdown':
                        this.renderDropdownOption(option, index, $option);
                        break;
                    case 'checkbox':
                        this.renderCheckboxOption(option, index, $option);
                        break;
                }
                
                $optionsContainer.append($option);
            }.bind(this));
        },
        
        /**
         * 渲染颜色选项
         */
        renderColorOption: function(option, index, $container) {
            var $colorPicker = $('<div class="fpc-color-picker"></div>');
            
            option.choices.forEach(function(choice, choiceIndex) {
                var $color = $('<div class="fpc-color-choice"></div>');
                $color.css('background-color', choice.value);
                $color.attr('title', choice.label);
                $color.data('value', choice.value);
                

0) {

                $color.addClass('active');
            }
            
            $color.on('click', function() {
                $color.siblings().removeClass('active');
                $color.addClass('active');
                this.updateOptionValue(index, choice.value);
            }.bind(this));
            
            $colorPicker.append($color);
        }.bind(this));
        
        $container.append($colorPicker);
    },
    
    /**
     * 更新选项值
     */
    updateOptionValue: function(optionIndex, value) {
        if (this.currentConfig.options[optionIndex]) {
            this.currentConfig.options[optionIndex].value = value;
            this.applyOptionToCanvas(optionIndex);
            this.updatePreview();
        }
    },
    
    /**
     * 将选项应用到画布
     */
    applyOptionToCanvas: function(optionIndex) {
        var option = this.currentConfig.options[optionIndex];
        
        // 根据选项类型应用变化
        switch (option.target_type) {
            case 'background_color':
                this.fabricCanvas.backgroundColor = option.value;
                this.fabricCanvas.renderAll();
                break;
            case 'text_color':
                this.fabricCanvas.getObjects().forEach(function(obj) {
                    if (obj.data && obj.data.type === 'text') {
                        obj.set('fill', option.value);
                    }
                });
                this.fabricCanvas.renderAll();
                break;
        }
    },
    
    /**
     * 更新预览
     */
    updatePreview: function() {
        // 这里可以添加实时预览更新逻辑
        // 例如:更新缩略图或发送到服务器生成预览
    },
    
    /**
     * 保存当前配置
     */
    saveConfiguration: function() {
        if (this.isSaving) return;
        
        this.isSaving = true;
        var self = this;
        
        // 收集所有配置数据
        var configData = {
            product_id: this.currentProductId,
            options: {},
            areas: []
        };
        
        // 收集选项值
        this.currentConfig.options.forEach(function(option, index) {
            configData.options[option.id] = option.value || option.default;
        });
        
        // 收集区域数据
        this.fabricCanvas.getObjects().forEach(function(obj) {
            if (obj.data && obj.data.type === 'text') {
                configData.areas.push({
                    type: 'text',
                    text: obj.text,
                    font_size: obj.fontSize,
                    font_family: obj.fontFamily,
                    color: obj.fill,
                    position: {
                        x: obj.left,
                        y: obj.top
                    }
                });
            }
        });
        
        // 生成预览图像
        var previewData = this.fabricCanvas.toDataURL({
            format: 'jpeg',
            quality: 0.8
        });
        
        $.ajax({
            url: fpc_ajax.ajax_url,
            type: 'POST',
            data: {
                action: 'fpc_save_configuration',
                nonce: fpc_ajax.nonce,
                config_data: JSON.stringify(configData),
                preview_image: previewData,
                product_id: this.currentProductId
            },
            beforeSend: function() {
                $('#fpc-saving').show();
            },
            success: function(response) {
                if (response.success) {
                    self.showSuccess('配置已保存!');
                    // 更新购物车
                    self.addToCart(response.data.config_id);
                } else {
                    self.showError(response.data);
                }
            },
            error: function() {
                self.showError(fpc_ajax.text.error);
            },
            complete: function() {
                self.isSaving = false;
                $('#fpc-saving').hide();
            }
        });
    },
    
    /**
     * 添加到购物车
     */
    addToCart: function(configId) {
        $.ajax({
            url: fpc_ajax.ajax_url,
            type: 'POST',
            data: {
                action: 'fpc_add_to_cart',
                nonce: fpc_ajax.nonce,
                product_id: this.currentProductId,
                config_id: configId
            },
            success: function(response) {
                if (response.success) {
                    // 更新购物车数量
                    if (response.data.cart_count) {
                        $('.cart-count').text(response.data.cart_count);
                    }
                    self.showSuccess('已添加到购物车!');
                }
            }
        });
    },
    
    /**
     * 绑定事件
     */
    bindEvents: function() {
        var self = this;
        
        // 保存按钮
        $('#fpc-save-config').on('click', function() {
            self.saveConfiguration();
        });
        
        // 重置按钮
        $('#fpc-reset-config').on('click', function() {
            if (confirm('确定要重置所有配置吗?')) {
                self.loadProductConfig();
            }
        });
        
        // 图片上传
        $('#fpc-upload-image').on('change', function(e) {
            self.handleImageUpload(e.target.files[0]);
        });
    },
    
    /**
     * 处理图片上传
     */
    handleImageUpload: function(file) {
        if (!file) return;
        
        var reader = new FileReader();
        var self = this;
        
        reader.onload = function(e) {
            fabric.Image.fromURL(e.target.result, function(img) {
                // 添加图片到画布
                img.set({
                    left: 100,
                    top: 100,
                    scaleX: 0.5,
                    scaleY: 0.5,
                    hasControls: true,
                    data: {
                        type: 'uploaded_image'
                    }
                });
                
                self.fabricCanvas.add(img);
                self.fabricCanvas.setActiveObject(img);
            });
        };
        
        reader.readAsDataURL(file);
    },
    
    /**
     * 显示成功消息
     */
    showSuccess: function(message) {
        this.showMessage(message, 'success');
    },
    
    /**
     * 显示错误消息
     */
    showError: function(message) {
        this.showMessage(message, 'error');
    },
    
    /**
     * 显示消息
     */
    showMessage: function(message, type) {
        var $message = $('<div class="fpc-message fpc-message-' + type + '"></div>');
        $message.text(message);
        
        $('#fpc-messages').append($message);
        
        setTimeout(function() {
            $message.fadeOut(300, function() {
                $(this).remove();
            });
        }, 3000);
    }
};

// 文档加载完成后初始化
$(document).ready(function() {
    FPC_Frontend.init();
});

})(jQuery);


## 五、AJAX处理类

### 5.1 创建AJAX处理器

创建 `includes/class-ajax-handler.php`:

<?php
/**

  • AJAX请求处理器
    */

class FPC_Ajax_Handler {


private static $instance = null;

public static function get_instance() {
    if (null === self::$instance) {
        self::$instance = new self();
    }
    return self::$instance;
}

private function __construct() {
    // 注册AJAX动作
    add_action('wp_ajax_fpc_get_product_config', array($this, 'get_product_config'));
    add_action('wp_ajax_nopriv_fpc_get_product_config', array($this, 'get_product_config'));
    
    add_action('wp_ajax_fpc_save_configuration', array($this, 'save_configuration'));
    add_action('wp_ajax_nopriv_fpc_save_configuration', array($this, 'save_configuration'));
    
    add_action('wp_ajax_fpc_add_to_cart', array($this, 'add_to_cart'));
    add_action('wp_ajax_nopriv_fpc_add_to_cart', array($this, 'add_to_cart'));
    
    add_action('wp_ajax_fpc_upload_image', array($this, 'upload_image'));
    add_action('wp_ajax_nopriv_fpc_upload_image', array($this, 'upload_image'));
}

/**
 * 获取产品配置
 */
public function get_product_config() {
    // 验证nonce
    if (!wp_verify_nonce($_POST['nonce'], 'fpc_nonce')) {
        wp_die('安全验证失败');
    }
    
    $product_id = intval($_POST['product_id']);
    
    if (!$product_id) {
        wp_send_json_error('产品ID无效');
    }
    
    $configurator = FPC_Configurator::get_instance();
    $options = $configurator->get_product_options($product_id);
    
    // 添加默认值
    if (!empty($options['options'])) {
        foreach ($options['options'] as &$option) {
            if (!isset($option['value']) && isset($option['default'])) {
                $option['value'] = $option['default'];
            }
        }
    }
    
    wp_send_json_success($options);
}

/**
 * 保存配置
 */
public function save_configuration() {
    // 验证nonce
    if (!wp_verify_nonce($_POST['nonce'], 'fpc_nonce')) {
        wp_die('安全验证失败');
    }
    
    $product_id = intval($_POST['product_id']);
    $config_data = json_decode(stripslashes($_POST['config_data']), true);
    $preview_image = $_POST['preview_image'];
    
    if (!$product_id || empty($config_data)) {
        wp_send_json_error('数据无效');
    }
    
    global $wpdb;
    $table_name = $wpdb->prefix . 'fpc_product_configs';
    
    // 处理预览图片
    $preview_url = '';
    if (!empty($preview_image)) {
        $preview_url = $this->save_preview_image($preview_image, $product_id);
    }
    
    // 保存到数据库
    $data = array(
        'product_id' => $product_id,
        'user_id' => get_current_user_id(),
        'config_data' => json_encode($config_data),
        'preview_image' => $preview_url
    );
    
    $result = $wpdb->insert($table_name, $data);
    
    if ($result) {
        $config_id = $wpdb->insert_id;
        
        // 创建配置的唯一标识符
        $config_hash = wp_hash($config_id . time());
        
        // 保存到用户会话
        $user_configs = WC()->session->get('fpc_configurations', array());
        $user_configs[$config_hash] = array(
            'config_id' => $config_id,
            'product_id' => $product_id,
            'created' => time()
        );
        WC()->session->set('fpc_configurations', $user_configs);
        
        wp_send_json_success(array(
            'config_id' => $config_id,
            'config_hash' => $config_hash
        ));
    } else {
        wp_send_json_error('保存配置失败');
    }
}

/**
 * 保存预览图片
 */
private function save_preview_image($base64_image, $product_id) {
    // 移除base64头部
    $base64_image = str_replace('data:image/jpeg;base64,', '', $base64_image);
    $base64_image = str_replace(' ', '+', $base64_image);
    
    // 解码图片
    $image_data = base64_decode($base64_image);
    
    if (!$image_data) {
        return '';
    }
    
    // 创建上传目录
    $upload_dir = wp_upload_dir();
    $fpc_dir = $upload_dir['basedir'] . '/fpc-previews/';
    
    if (!file_exists($fpc_dir)) {
        wp_mkdir_p($fpc_dir);
    }
    
    // 生成文件名
    $filename = 'product-' . $product_id . '-' . time() . '.jpg';
    $filepath = $fpc_dir . $filename;
    
    // 保存文件
    if (file_put_contents($filepath, $image_data)) {
        return $upload_dir['baseurl'] . '/fpc-previews/' . $filename;
    }
    
    return '';
}

/**
 * 添加到购物车
 */
public function add_to_cart() {
    // 验证nonce
    if (!wp_verify_nonce($_POST['nonce'], 'fpc_nonce')) {
        wp_die('安全验证失败');
    }
    
    $product_id = intval($_POST['product_id']);
    $config_id = intval($_POST['config_id']);
    
    if (!$product_id || !$config_id) {
        wp_send_json_error('参数无效');
    }
    
    // 获取配置数据
    global $wpdb;
    $table_name = $wpdb->prefix . 'fpc_product_configs';
    $config = $wpdb->get_row($wpdb->prepare(
        "SELECT * FROM $table_name WHERE id = %d AND product_id = %d",
        $config_id, $product_id
    ));
    
    if (!$config) {
        wp_send_json_error('配置不存在');
    }
    
    // 准备购物车数据
    $cart_item_data = array(
        'fpc_config_id' => $config_id,
        'fpc_preview' => $config->preview_image,
        'fpc_config_data' => json_decode($config->config_data, true)
    );
    
    // 添加到购物车
    $cart_item_key = WC()->cart->add_to_cart(
        $product_id,
        1,
        0,
        array(),
        $cart_item_data
    );
    
    if ($cart_item_key) {
        wp_send_json_success(array(
            'cart_count' => WC()->cart->get_cart_contents_count(),
            'cart_item_key' => $cart_item_key
        ));
    } else {
        wp_send_json_error('添加到购物车失败');
    }
}

/**
 * 上传图片
 */
public function upload_image() {
    // 验证nonce
    if (!wp_verify_nonce($_POST['nonce'], 'fpc_nonce')) {
        wp_die('安全验证失败');
    }
    
    if (!function_exists('wp_handle_upload')) {
        require_once(ABSPATH . 'wp-admin/includes/file.php');
    }
    
    $uploadedfile = $_FILES['fpc_image'];
    
    // 验证文件类型
    $allowed_types = array('image/jpeg', 'image/png', 'image/gif');
    if (!in_array($uploadedfile['type'], $allowed_types)) {
        wp_send_json_error('不支持的文件类型');
    }
    
    // 验证文件大小(最大2MB)
    if ($uploadedfile['size'] > 2 * 1024 * 1024) {
        wp_send_json_error('文件大小不能超过2MB');
    }
    
    // 处理上传
    $movefile = wp_handle_upload($uploadedfile, array('test_form' => false));
    
    if ($movefile && !isset($movefile['error'])) {
        wp_send_json_success(array(
            'url' => $movefile['url'],
            'file' => $movefile['file']
        ));
    } else {
        wp_send_json_error($movefile['error']);
    }
}

}


## 六、管理界面实现

### 6.1 创建管理类

创建 `includes/class-admin.php`:

<?php
/**

  • 管理界面类
    */

class FPC_Admin {


private static $instance = null;

public static function get_instance() {
    if (null === self::$instance) {
        self::$instance = new self();
    }
    return self::$instance;
}

private function __construct() {
    add_action('admin_menu', array($this, 'add_admin_menu'));
    add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_scripts'));
    add_action('add_meta_boxes', array($this, 'add_product_meta_box'));
    add_action('save_post_product', array($this, 'save_product_meta'), 10, 2);
}

/**
 * 添加管理菜单
 */
public function add_admin_menu() {
    add_menu_page(
        __('产品配置器', 'flexible-product-configurator'),
        __('产品配置器', 'flexible-product-configurator'),
        'manage_options',
        'fpc-settings',
        array($this, 'render_settings_page'),
        'dashicons-admin-generic',
        56
    );
    
    add_submenu_page(
        'fpc-settings',
        __('配置管理', 'flexible-product-configurator'),
        __('配置管理', 'flexible-product-configurator'),
        'manage_options',
        'fpc-configs',
        array($this, 'render_configs_page')
    );
}

/**
 * 加载管理脚本
 */
public function enqueue_admin_scripts($hook) {
    global $post;
    
    // 只在产品编辑页面和插件设置页面加载
    if (($hook == 'post.php' && $post->post_type == 'product') || 
        strpos($hook, 'fpc-') !== false) {
        
        wp_enqueue_style(
            'fpc-admin',
            FPC_PLUGIN_URL . 'assets/css/admin.css',
            array(),
            FPC_VERSION
        );
        
        wp_enqueue_script(
            'fpc-admin',
            FPC_PLUGIN_URL . 'assets/js/admin.js',
            array('jquery', 'jquery-ui-sortable'),
            FPC_VERSION,
            true
        );
        
        wp_localize_script('fpc-admin', 'fpc_admin', array(
            'ajax_url' => admin_url('admin-ajax.php'),
            'nonce' => wp_create_nonce('fpc_admin_nonce'),
            'text' => array(
                'confirm_delete' => __('确定要删除这个选项吗?', 'flexible-product-configurator'),
                'saving' => __('保存中...', 'flexible-product-configurator')
            )
        ));
    }
}

/**
 * 添加产品元数据框
 */
public function add_product_meta_box() {
    add_meta_box(
        'fpc_product_configurator',
        __('柔性产品配置器', 'flexible-product-configurator'),
        array($this, 'render_product_meta_box'),
        'product',
        'normal',
        '
本文来自网络,不代表柔性供应链服务中心立场,转载请注明出处:https://mall.org.cn/6279.html

EXCHANGES®作者

上一篇
下一篇

为您推荐

发表回复

联系我们

联系我们

18559313275

在线咨询: QQ交谈

邮箱: vip@exchanges.center

工作时间:周一至周五,9:00-17:30,节假日休息
返回顶部