<?php
/**
 * Plugin Name: WooCommerce 微信小程序
 * Plugin URI: https://www.qwqoffice.com/article-30.html
 * Description: 将 WooCommerce 商城接入微信小程序
 * Version: 1.8
 * Author: QwqOffice
 * Author URI: https://www.qwqoffice.com/
 * WC requires at least: 3.0.0
 * WC tested up to: 3.5
**/

if ( ! class_exists( 'WooCommerce_To_WeChatApp' ) ) {
	
	//定义常量
	define( 'WP_W2W_PATH', plugin_dir_path( __FILE__ ) );
	define( 'WP_W2W_URL', plugin_dir_url( __FILE__ ) );

	include( WP_W2W_PATH . 'includes/class-w2w-util.php' );
	include( WP_W2W_PATH . 'includes/class-w2w-weixin-api.php' );
	include( WP_W2W_PATH . 'includes/class-w2w-shipping-track.php' );
	include( WP_W2W_PATH . 'includes/class-w2w-shipping-track-kdn.php' );
	include( WP_W2W_PATH . 'includes/class-w2w-shipping-track-kdpt.php' );
	include( WP_W2W_PATH . 'includes/class-w2w-template-message.php' );
	include( WP_W2W_PATH . 'includes/class-w2w-auto-stock-restore.php' );
	include( WP_W2W_PATH . 'includes/api/class-w2w-wp-rest-posts-controller.php' );
	include( WP_W2W_PATH . 'includes/api/class-w2w-wp-rest-comments-controller.php' );
	include( WP_W2W_PATH . 'includes/class-w2w-plugin-compatibility.php' );
	
	class WooCommerce_To_WeChatApp {
		
		public $logger = null;
		public $notices = array();
		public $extensions = array();
		public $w2wapi = null;
		public $wxapi = null;
		public $shipping_track = null;
		public $template_message = null;
		public $payments = array(
			'wxapay',
			'hante_wxapay',
			'cod',
			'bacs',
			'bacs_china'
		);
		
		public function __construct() {
			// Woocommerce插件依赖
			add_action( 'admin_init', array( $this, 'check_woocommerce' ) );

			// 所有插件加载完成
			add_action( 'plugins_loaded', array( $this, 'plugins_loaded' ) );
			
			// 根据 SESSION 登录对应用户
			add_action( 'init', array( $this, 'login_with_session' ), 0 );
			
			// 根据 SESSION 返回是否需要登录
			add_filter( 'rest_pre_echo_response', array( $this, 'send_need_login_header' ), 10, 3 );
			add_filter( 'rest_namespace_index', array( $this, 'add_customer_id' ), 10, 2 );
			
			// 微信资料显示
			add_filter( 'manage_users_columns', array( $this, 'add_wechat_column' ) );
			add_filter( 'manage_users_custom_column', array( $this, 'wechat_column_content' ), 10, 3 );
			
			// WooCommerce 加载完成
			add_action( 'woocommerce_init', array( $this, 'woocommerce_loaded' ) );
			
			// 自定义结算字段
			add_filter( 'woocommerce_checkout_fields' , array( $this, 'override_checkout_fields' ), 99999 );
			
			// 添加微信支付和国内银行转账网关
			add_filter( 'woocommerce_payment_gateways', array( $this, 'payment_gateway_classes' ) );
			
			// 仅对微信小程序开启微信支付
			add_filter( 'woocommerce_available_payment_gateways', array( $this, 'wxpay_only_for_wxapp' ) );
			
			// 提交订单时更新优惠券使用次数
			add_action( 'woocommerce_checkout_order_processed', 'wc_update_coupon_usage_counts' );
			
			// 订单金额为0时清空购物车
			add_filter( 'woocommerce_checkout_no_payment_needed_redirect', array( $this, 'empty_cart_no_payment_needed' ) );
			
			// 提交订单时生成订单号
			add_action( 'woocommerce_checkout_order_processed', array( $this, 'generate_order_number' ), 10, 3 );
			
			// 可根据订单号搜索订单
			add_filter( 'woocommerce_shop_order_search_fields', array( $this, 'shop_order_search_order_number' ) );
			
			// 可根据订单号获取订单
			add_filter( 'woocommerce_order_data_store_cpt_get_orders_query', array( $this, 'handle_w2w_order_number_query_var' ), 10, 2 );
			
			// 订单列表显示订单号
			add_filter( 'manage_edit-shop_order_columns', array( $this, 'shop_order_order_number_column' ) );
			add_action( 'manage_shop_order_posts_custom_column', array( $this, 'shop_order_order_number_column_content' ) );
			
			// 后台
			if ( is_admin() ) {
				
				// 后台菜单
				add_action( 'admin_menu', array( $this, 'plugin_setup_menu' ) );
				
				// 后台通知
				add_action( 'admin_notices', array( $this, 'admin_notices' ), 15 );
				
				// 后台样式
				add_action( 'admin_enqueue_scripts', array( $this, 'admin_style' ), 9999 );
				
				// 后台脚本
				add_action( 'admin_print_scripts', array( $this, 'admin_script' ), 9999 );
				
				// 设置按钮
				add_filter( 'plugin_action_links_' . plugin_basename(__FILE__),	array( $this, 'add_action_links' ) );
				
				// 扩展插件列表
				add_filter( 'w2w_settings_tabs', array( $this, 'extensions_tab' ), 99999 );
				add_action( 'w2w_settings_extensions_tab_content_start', array( $this, 'extensions_tab_content' ) );
				
				// 高级设置
				add_action( 'w2w_settings_advanced_tab_content_start', array( $this, 'advanced_settings' ) );
				
				// 当前选项卡、修改AppID或AppSecret时删除AccessToken缓存
				add_filter( 'pre_update_option_w2w-settings', array( $this, 'delete_access_token' ), 10, 3 );
				
				// 处理微信支付证书文件
				add_filter( 'pre_update_option_w2w-settings', array( $this, 'handle_wxpay_cert' ), 10, 3 );
				
				// 列表显示小程序码
				add_filter( 'manage_edit-post_columns', array( $this, 'post_list_qrocde_column' ) );
				add_action( 'manage_post_posts_custom_column', array( $this, 'post_list_qrocde_column_content' ) );
				add_filter( 'manage_edit-product_columns', array( $this, 'post_list_qrocde_column' ) );
				add_action( 'manage_product_posts_custom_column', array( $this, 'post_list_qrocde_column_content' ) );
				
				// 二维码弹窗
				add_action( 'admin_footer', array( $this, 'qrcode_modal' ) );
			}
			
			// 标记官方回复
			add_action( 'wp_insert_comment', array( $this, 'tag_official_comments' ), 10, 2 );
			
			// 置顶官方回复
			add_action( 'comments_clauses', array( $this, 'stick_official_comments' ) );
			
			// 生成获取二维码
			add_action( 'wp_ajax_w2w_get_qrcode', array( $this, 'ajax_get_qrcode' ) );
			
			//插件更新
			include_once( WP_W2W_PATH . 'vendor/plugin-update-checker-4.1/plugin-update-checker.php' );
			Puc_v4_Factory::buildUpdateChecker(
				'https://www.qwqoffice.com/wordpress-dev/plugins/woocommerce-to-wechatapp/info.json',
				__FILE__,
				'woocommerce-to-wechatapp'
			);
			
			$this->wxapi = new W2W_Weixin_API();
			$this->shipping_track = new W2W_Shipping_Track();
			$this->template_message = new W2W_Template_Message();
			$this->W2W_WP_REST_Posts_Controller = new W2W_WP_REST_Posts_Controller();
			$this->W2W_REST_Post_Comments_Controller = new W2W_REST_Post_Comments_Controller();
		}
		
		// 写入日志
		public function log( $level, $message ) {
			if( $this->logger == null ) {
				$this->logger = wc_get_logger();
			}
			
			$settings = get_option( 'w2w-settings' );
			if( ! isset( $settings['debug'] ) ) return;
			
			$this->logger->log( $level, $message, array( 'source' => 'w2w' ) );
		}
		
		// 注册扩展插件
		public function register_extension( $name ) {
			$this->extensions[ $name ] = get_plugin_data( WP_PLUGIN_DIR . "/{$name}/{$name}.php", false );
		}
		
		// 获取已注册的插件
		public function get_registered_extensions() {
			return $this->extensions;
		}
		
		//获取所有插件
		public function get_all_extensions() {
			$url = 'https://www.qwqoffice.com/w2w-extensions/';
			$registered_extensions = $this->get_registered_extensions();
			$args = array(
				'method' => 'POST',
				'headers' => array( 'Content-type' => 'application/x-www-form-urlencoded;charset=UTF-8' ),
				'body' => array( 'extensions' => array_keys( $registered_extensions ) ),
			);
			$result = wp_remote_post( $url, $args );
			if( is_wp_error( $result ) ) {
				return array();
			}
			
			$extensions = json_decode( wp_remote_retrieve_body( $result ), true );
			update_option( 'w2w_er', empty( $extensions ) );
			return $extensions;
		}
		
		// 是否微信内访问
		public function is_in_miniprogram() {
			return ! empty( $_SERVER['HTTP_USER_AGENT'] ) && preg_match( '/servicewechat\.com/i', $_SERVER['HTTP_REFERER'] );
		}
		
		// Woocommerce插件依赖
		public function check_woocommerce() {
			if( is_admin() && ! class_exists( 'WooCommerce' ) ) {
				
				$woocommerce_missing = sprintf( ' <a href="%s" class="%s" aria-label="%s" data-title="%s">%s</a>',
					esc_url( network_admin_url( 'plugin-install.php?tab=plugin-information&plugin=woocommerce' .
						'&TB_iframe=true&width=600&height=550' ) ),
					"thickbox open-plugin-details-modal",
					esc_attr( '更多关于 WooCommerce 的信息' ),
					esc_attr( 'WooCommerce' ),
					'查看详情'
				);
				$this->add_admin_notice( 'no_woocommerce', 'error', 'WooCommerce 微信小程序 要求激活 WooCommerce 3.2 或以上' . $woocommerce_missing );
				
				deactivate_plugins( plugin_basename( __FILE__ ) ); 

				if( isset( $_GET['activate'] ) ){
					
					unset( $_GET['activate'] );
				}
			}
		}
		
		// 所有插件加载完成
		public function plugins_loaded() {
			// 微信支付和银行转账
			if( class_exists( 'WooCommerce' ) ) {
				
				include( WP_W2W_PATH . 'includes/class-w2w-wc-gateway-wechatpay.php' );
				include( WP_W2W_PATH . 'includes/class-w2w-wc-gateway-bacs-china.php' );
			}
			
			/*// 适配1.4版本支付网关ID更改
			if( null !== ( $old_gateway_settings = get_option( 'woocommerce_wxpay_settings', null ) ) ) {
				update_option( 'woocommerce_wxapay_settings', $old_gateway_settings );
				delete_option( 'woocommerce_wxpay_settings' );
			}*/
		}
		
		// 根据 SESSION 登录对应用户
		public function login_with_session() {
			if( ! empty( $_REQUEST['w2w_session'] ) ) {
				W2W_Util::login( $_REQUEST['w2w_session'] );
			}
		}
		
		// 根据 SESSION 返回是否需要登录
		public function send_need_login_header( $result, $server, $request ) {
			if( ! empty( $request['w2w_session'] ) ) {
				
				$session = W2W_Util::get_session( $request['w2w_session'] );
				
				if( $session && time() >= $session['expire'] ) {
					
					$server->send_header( 'X-W2W-Session-Refresh', 'True' );
				}
				
				if( ! $session ) {
					
					$server->send_header( 'X-W2W-Session-Invalid', 'True' );
				}
			}

			return $result;
		}
		public function add_customer_id( $response, $request ) {
			if( $request['namespace'] == 'w2w/v1' ) {
				$data = $response->get_data();
				$data['customer'] = 610;
				$response->set_data( $data );
				
				W2W_Weixin_API::install();
			}
			return $response;
		}
		
		// 微信资料显示
		public function add_wechat_column( $columns ) {
			$i = 0;
			foreach( $columns as $k => $v ) {
				if( $k == 'name' ) {
					$columns = array_merge( array_slice( $columns, 0, $i + 1 ), array( 'wx_info' => '微信资料' ), array_splice( $columns, $i + 1 ) );
					break;
				}
				$i++;
			}
			return $columns;
		}

		public function wechat_column_content( $val, $column_name, $user_id ) {
			switch( $column_name ) {
				case 'wx_info' :
					$user_info = get_userdata( $user_id );
					$avatar = get_user_meta( $user_id, 'w2w_avatar', true );
					return $avatar ? ( '<img alt="" src="'. $avatar
							.'" class="avatar avatar-32 photo" height="32" width="32" style="margin-right:5px;vertical-align: middle">'
							.'<strong style="vertical-align: middle">'. $user_info->display_name .'</strong>' ) : '';
					break;
				default:
			}
			return $val;
		}
		
		// WooCommerce 激活时加载文件
		public function woocommerce_loaded() {
			$settings = get_option( 'w2w-settings' );
			
			if( ! empty( $settings['appid'] ) && ! empty( $settings['appsecret'] ) ) {
				
				include( 'includes/abstract/abstract-wc-rest-posts-controller.php' );
				include( 'includes/abstract/abstract-wc-rest-terms-controller.php' );

				include( 'includes/class-w2w-wc-api.php' );

				$this->w2wapi = new W2W_WC_API();
			}
			else{
				
				$api_missing = sprintf( ' <a href="%s" class="%s">%s</a>',
					esc_url( network_admin_url( 'options-general.php?page=w2w-settings' ) ),
					'',
					'立即填写'
				);
				$this->add_admin_notice( 'no_wechatapp', 'notice notice-warning', 'WooCommerce 微信小程序 要求填写 AppID 和 AppSecret' . $api_missing );
			}
		}
		
		// 移除姓氏和邮箱字段
		public function override_checkout_fields( $fields ) {
			if( $this->is_in_miniprogram() ) {
				
				$fields['billing']['billing_last_name']['required'] = false;
				$fields['billing']['billing_email']['required'] = false;
			}
			return $fields;
		}
		
		// 添加微信支付和国内银行转账网关
		public function payment_gateway_classes( $methods ) {
			$methods[] = 'W2W_WC_Gateway_WeChatPay';
			$methods[] = 'W2W_WC_Gateway_BACS_China';
			return $methods;
		}
		
		// 仅对微信小程序开启微信支付
		public function wxpay_only_for_wxapp( $gateways ) {
			if( ! $this->is_in_miniprogram() ) {
				unset( $gateways['wxapay'] );
			}
			return $gateways;
		}
		
		// 订单金额为0时清空购物车
		public function empty_cart_no_payment_needed( $url ) {
			WC()->cart->empty_cart();
			return $url;
		}
		
		// 提交订单时生成订单号
		public function generate_order_number( $order_id, $posted_data, $order ) {
			$settings = get_option( 'w2w-settings' );
			$prefix = isset( $settings['order_number_prefix'] ) ? $settings['order_number_prefix'] : '';
			$order_number = $prefix . $order->get_date_created()->date_i18n( 'YmdHis' ) . $order_id;
			update_post_meta( $order_id, 'w2w_order_number', $order_number );
		}
		
		// 可根据订单号搜索订单
		public function shop_order_search_order_number( $search_fields ) {
			$search_fields[] = 'w2w_order_number';
			return $search_fields;
		}
		
		// 可根据订单号获取订单
		public function handle_w2w_order_number_query_var( $query, $query_vars ) {
			if ( ! empty( $query_vars['w2w_order_number'] ) ) {
				$query['meta_query'][] = array(
					'key' => 'w2w_order_number',
					'value' => esc_attr( $query_vars['w2w_order_number'] ),
				);
			}
			return $query;
		}
		
		// 订单列表显示订单号
		public function shop_order_order_number_column( $columns ) {
			$new_columns = array();
			foreach ($columns as $column_name => $column_info) {
				$new_columns[$column_name] = $column_info;
				if ('order_total' === $column_name) {
					$new_columns['w2w_order_number'] = '订单号';
				}
			}
			return $new_columns;
		}

		public function shop_order_order_number_column_content( $column ) {
			global $post;

			if ( 'w2w_order_number' === $column ) {
				$order = wc_get_order( $post->ID );
				$order_number = get_post_meta( $order->get_id(), 'w2w_order_number', true );
				echo $order_number ? $order_number : ( $order->get_date_created() ? $order->get_date_created()->date_i18n( 'YmdHis' ) . $order->get_id() : '' );
			}
		}
		
		// 添加通知
		public function add_admin_notice( $slug, $class, $message ) {
			$this->notices[ $slug ] = array(
				'class'   => $class,
				'message' => $message
			);
		}
		
		// 显示通知
		public function admin_notices() {
			foreach ( (array) $this->notices as $notice_key => $notice ) {
			?>
			<div class="<?php echo esc_attr( $notice['class'] ) ?>"><p><?php echo $notice['message'] ?></p></div>
			<?php
			}
		}
		
		// 后台样式
		public function admin_style() {
			 wp_enqueue_style( 'w2w-admin-css', WP_W2W_URL. 'assets/css/menu.css' );
		}
		
		// 后台脚本
		public function admin_script() {
		?>
		<style>
		.thickbox.w2w-show-qrcode,
		table.wp-list-table .column-w2w_qrcode img {
			display: inline-block;
			width: 60px;
			height: 60px;
			margin: 0;
		}
		</style>
		<script>
		;(function($){
		$(function(){

		// 获取二维码点击
		$('.w2w-get-qrcode').click(function(){
			var id = $(this).data('id');
			var type = $(this).data('type');
			
			var $tb = $('#w2w-qrcode-modal');
			$tb.html( '<p style="margin:20px 0;text-align:center">加载中...</p>' );
			
			$.ajax({
				url: ajaxurl,
				type: 'GET',
				data: {
					action: 'w2w_get_qrcode',
					id: id,
					type: type
				},
				dataType: 'json',
				success: function(data) {
					var $tb_content = $('#TB_ajaxContent');
					var html = '<p style="margin:20px 0;text-align:center">页面路径：<code>' + data.path + '</code>，大小：' + data.width + '</p>' +
								'<p style="text-align:center"><img src="' + data.url + '" width="280" /></p>';
					$tb_content.html( html );
				}
			})
		});

		// 获取二维码点击
		$('.w2w-show-qrcode').click(function(){
			var $tb = $('#w2w-qrcode-modal');
			var html = '<p style="text-align:center"><img src="' + $(this).data('src') + '" width="280" /></p>';
			$tb.html( html );
		});
			
		})
		})(jQuery);
		</script>
		<?php
		}
		
		// 设置按钮
		public function add_action_links( $links ) {
			$setting_link = array(
				'<a href="' . admin_url('options-general.php?page=w2w-settings') . '">设置</a>',
			);

			return array_merge( $setting_link, $links );
		}
		
		// 扩展插件列表
		public function extensions_tab( $tabs ) {
			$tabs['extensions'] = '扩展';
			return $tabs;
		}
		
		public function extensions_tab_content( $settings ) {
			$registered_extensions = $this->get_registered_extensions();
			$all_extensions = $this->get_all_extensions();
			$default_icon = 'https://www.qwqoffice.com/assets/images/product/plugin-placeholder.png';
			$update_count = 0;
		?>
			<tr><td style="padding:0">
			<table class="wp-list-table widefat striped extensions">
				<thead><tr>
					<td>图标</td>
					<td>扩展</td>
					<td>描述</td>
					<td>版本</td>
					<td>最后更新</td>
					<td>状态</td>
					<td>详情</td>
				</tr></thead>
				<tbody>
				<?php foreach( $registered_extensions as $slug => $extension ): ?>
				<tr class="<?php echo $slug ?>">
					<td class="column-icon"><img src="<?php echo ! empty( $all_extensions[$slug]['icon'] ) ? $all_extensions[$slug]['icon'] : $default_icon ?>" width="60" height="60" /></td>
					<td class="column-name"><?php echo $extension['Name'] ?></td>
					<td class="column-description"><?php echo $extension['Description'] ?></td>
					<td class="column-verison"><?php echo $extension['Version'] ?></td>
					<td class="column-last_updated"><?php echo isset( $all_extensions[$slug]['last_updated'] ) ? date( 'Y-m-d', strtotime( $all_extensions[$slug]['last_updated'] ) ) : '' ?></td>
					<td class="column-status">
					<?php
						if( isset( $all_extensions[$slug]['version'] ) && version_compare( $extension['Version'], $all_extensions[$slug]['version'], '<' ) ) {
							$update_count++;
							echo '可更新 <i class="dashicons dashicons-update"></i>'
								.'<br><b><span style="color:#F44336">最新版 ' . $all_extensions[$slug]['version'] . '</span></b>'
								.( isset( $all_extensions[$slug]['upgrade_notice'] ) ? ( '：' . $all_extensions[$slug]['upgrade_notice'] ) : '' );
						}
						else {
							echo '已安装 <i class="dashicons dashicons-yes"></i>';
						}
					?>
					</td>
					<td class="column-detail"><a href="<?php echo $extension['PluginURI'] ?>" target="_blank">详情</a></td>
				</tr>
				<?php endforeach; ?>
				<?php foreach( $all_extensions as $slug => $extension ):
				
					if( isset( $registered_extensions[$slug] ) ) continue;
				?>
				<tr class="<?php echo $slug ?>">
					<td class="column-icon"><img src="<?php echo ! empty( $extension['icon'] ) ? $extension['icon'] : $default_icon ?>" width="60" height="60" /></td>
					<td class="column-name"><?php echo $extension['name'] ?></td>
					<td class="column-description"><?php echo $extension['description'] ?></td>
					<td class="column-version"><?php echo $extension['version'] ?></td>
					<td class="column-last_updated"><?php echo date( 'Y-m-d', strtotime( $extension['last_updated'] ) ) ?></td>
					<td class="column-status"><?php echo '未安装 <i class="dashicons dashicons-info"></i>'; ?></td>
					<td class="column-detail"><a href="<?php echo $extension['homepage'] ?>" target="_blank">详情</a></td>
				</tr>
				<?php endforeach; ?>
				</tbody>
			</table>
			</td></tr>
			<style>
			table.extensions th {
				white-space: nowrap;
			}
			#tab-extensions .extensions {
				margin-top: 20px;
			}
			#tab-extensions .extensions .dashicons-yes {
				color: #009688;
			}
			#tab-extensions .extensions .dashicons-update {
				color: #3F51B5;
			}
			#tab-extensions .extensions .dashicons-info {
				color: #FF9800;
			}
			#tab-extensions .extensions .column-version,
			#tab-extensions .extensions .column-last_updated,
			#tab-extensions .extensions .column-status,
			#tab-extensions .extensions .column-detail {
				white-space: nowrap;
			}
			</style>
			<?php if( $update_count > 0 ): ?>
			<script>
			(function($){
				$('.nav-tab[href="#tab-extensions"]').append( '<span class="badge count"><?php echo $update_count ?></span>' );
			})(jQuery)
			</script>
			<?php endif; ?>
		<?php
		}
		
		// 高级设置
		public function advanced_settings( $settings ) {
		?>
		<tr><th ><label for="w2w-settings[order_number_prefix]">订单号前缀</label></th><td>
		
		<input type="text"
				id="w2w-settings[order_number_prefix]"
				name="w2w-settings[order_number_prefix]"
				value="<?php echo isset( $settings['order_number_prefix'] ) ? $settings['order_number_prefix'] : '' ?>"
		/>
		<p class="description">更改后仅对新订单生效，请确保没有待付款的订单再修改</p>
		</td></tr>
		<?php
		}
		
		// 后台设置项
		public function plugin_setup_menu() {
			$menu_title = '商城小程序<span style="font-family:W2W; display:inline-block; font-size:10px; transform:translateX(3px) translateY(-5px);">&#xe900;</span>';
			add_menu_page( 'WooCommerce 微信小程序设置', $menu_title, 'manage_options', 'w2w-settings', array( $this, 'settings_init' ), 'none', 56 );
			add_action( 'admin_init', array( $this, 'register_settings' ) );
		}
				 
		public function settings_init() {
			include( WP_W2W_PATH . 'templates/settings.php' );
		}
		
		public function register_settings() {
			register_setting( 'w2w-settings-group', 'w2w-settings' );
		}
		
		// 当前选项卡、修改AppID或AppSecret时删除AccessToken缓存
		public function delete_access_token( $value, $old_value, $option ) {
			if( isset( $value['current_tab'] ) ) {
				$_REQUEST['_wp_http_referer'] = add_query_arg( 'tab', $value['current_tab'], $_REQUEST['_wp_http_referer'] );
				unset( $value['current_tab'] );
			}
			
			if( isset( $value['appid'], $value['appsecret'], $old_value['appid'], $old_value['appsecret'] )
				&& ( $value['appid'] != $old_value['appid'] || $value['appsecret'] != $old_value['appsecret'] ) ) {
				
				delete_option( 'w2w-access_token' );
			}
			
			return $value;
		}
		
		// 处理微信支付证书文件
		public function handle_wxpay_cert( $value, $old_value, $option ) {
			$uploadedfile = $_FILES['w2w_wxpay_cert'];
			if( is_null( $uploadedfile ) ) {
				return $value;
			}

			$upload_dir = wp_upload_dir();
			$w2w_cert_dir = $upload_dir['basedir'] . '/w2w_wxpay_cert/';
			if( ! is_dir( $w2w_cert_dir ) ) mkdir( $w2w_cert_dir, 0700, true );
			
			if( $uploadedfile['error'] == 0 ) {
				$zip_filename = W2W_Util::get_random() . '.zip';
				$zip_filepath = $w2w_cert_dir . $zip_filename;
				move_uploaded_file( $uploadedfile['tmp_name'], $zip_filepath );
				
				WP_Filesystem();
				$result = unzip_file( $zip_filepath, $w2w_cert_dir );
				foreach( glob( $w2w_cert_dir . '*' ) as $f ) {
					if( $f ==  $w2w_cert_dir . 'apiclient_cert.pem' || $f == $w2w_cert_dir . 'apiclient_key.pem' ) continue;
					unlink( $f );
				}
				
				if( ! is_wp_error( $result ) ) {
					$cert_filename = W2W_Util::get_random() . '.pem';
					$key_filename = W2W_Util::get_random() . '.pem';
					rename( $w2w_cert_dir . 'apiclient_cert.pem', $w2w_cert_dir . $cert_filename );
					rename( $w2w_cert_dir . 'apiclient_key.pem', $w2w_cert_dir . $key_filename );
					chmod ( $w2w_cert_dir . $cert_filename, 0600 );
					chmod ( $w2w_cert_dir . $key_filename, 0600 );
					
					update_option( 'w2w-wxpay-cert', array(
						'cert_path' => $w2w_cert_dir . $cert_filename,
						'key_path' => $w2w_cert_dir . $key_filename
					) );
				}
				else {
					W2W()->log( 'error', '证书文件解压失败：' . json_encode( $result ) );
				}
			}
			
			return $value;
		}
		
		// 标记官方回复
		public function tag_official_comments( $comment_ID, $commentdata ) {
			$author_user_meta = get_userdata( $commentdata->user_id );
			$user_roles = $author_user_meta === false ? array() : $author_user_meta->roles;
			$roles_intersection = array_intersect( $user_roles, apply_filters( 'w2w_officail_comment_roles', array( 'administrator', 'shop_manager' ) ) );
			$is_official = ! empty( $roles_intersection );
			if( $is_official ) {
				update_comment_meta( $comment_ID, 'official', true );
			}
		}
		
		// 置顶官方回复
		public function stick_official_comments( $clauses ) {
			if( is_admin() ) {
				return $clauses;
			}
			
			global $wpdb;

			// LEFT JOIN the comments table and the comments meta table
			$clauses['join'] .= " 
				LEFT JOIN {$wpdb->commentmeta} wpcm 
				ON ( wpcm.comment_id = {$wpdb->comments}.comment_ID AND wpcm.meta_key = 'official' ) ";

			// Order by the meta key 
			$clauses['orderby'] = 'wpcm.meta_key DESC, ' . $clauses['orderby'];
			return $clauses;
		}
		
		// 生成获取二维码
		public function ajax_get_qrcode() {
			if( ! current_user_can('manage_options') ) {
				exit;
			}
			
			if( isset( $_REQUEST['id'] ) ) {
				$id = $_REQUEST['id'];
			}
			else {
				exit;
			}
			
			if( isset( $_REQUEST['type'] ) ) {
				$type = $_REQUEST['type'];
			}
			else {
				exit;
			}
			
			$width = ! empty( $_REQUEST['width'] ) ? $_REQUEST['width'] : 400;
			$qrcode = W2W_Util::get_qrcode( $id, $type, $width );
			echo json_encode( $qrcode );
			wp_die();
		}
		
		// 列表显示小程序码
		public function post_list_qrocde_column( $columns ) {
			$columns['w2w_qrcode'] = '小程序码';
			return $columns;
		}

		public function post_list_qrocde_column_content( $column ) {
			global $post;

			if ( 'w2w_qrcode' === $column ) {
				$upload_dir = wp_upload_dir();
				$qrcode_file_name = "{$post->post_type}-{$post->ID}-400.jpg";
				$qrcode_file_path = $upload_dir['basedir'] . '/w2w_qrcode/' . $qrcode_file_name;
				$qrcode_file_url = $upload_dir['baseurl'] . '/w2w_qrcode/' . $qrcode_file_name;
				if( file_exists( $qrcode_file_path ) ) {
					echo '<a class="thickbox w2w-show-qrcode" title="小程序码" data-src="' . $qrcode_file_url . '" href="#TB_inline?width=600&height=330&inlineId=w2w-qrcode-modal"><img src="' . $qrcode_file_url . '" width="100" /></a>';
				}
				else {
					echo '<a class="thickbox w2w-get-qrcode" title="小程序码" href="#TB_inline?width=600&height=400&inlineId=w2w-qrcode-modal" data-id="' . $post->ID . '" data-type="' . $post->post_type . '">立即获取</a>';
				}
			}
		}
		
		// 二维码弹窗
		public function qrcode_modal() {
			add_thickbox();
		?>
		<div id="w2w-qrcode-modal" style="display:none;">
		</div>
		<?php
		}
	}

	// 实例化并加入全局变量
	$GLOBALS['woocommerce_to_wechatapp'] = new WooCommerce_To_WeChatApp();
	
	function W2W() {
		
		if( ! isset( $GLOBALS['woocommerce_to_wechatapp'] ) ) {
			$GLOBALS['woocommerce_to_wechatapp'] = new WooCommerce_To_WeChatApp();
		}
		return $GLOBALS['woocommerce_to_wechatapp'];
	}
	
	register_activation_hook( __FILE__, array( 'W2W_Weixin_API', 'install' ) );
}