Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/wordpress/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 使用Woo Cancel for Customers插件在我的帐户订单列表上添加取消按钮_Php_Wordpress_Woocommerce_Hook Woocommerce_Orders - Fatal编程技术网

Php 使用Woo Cancel for Customers插件在我的帐户订单列表上添加取消按钮

Php 使用Woo Cancel for Customers插件在我的帐户订单列表上添加取消按钮,php,wordpress,woocommerce,hook-woocommerce,orders,Php,Wordpress,Woocommerce,Hook Woocommerce,Orders,在我的WooCommerce网站上,我正在使用这个插件,它允许客户根据付款类型和延迟时间取消订单。但取消按钮仅出现在“woocommerce\u order\u details\u”表之后的“”上 我希望此取消按钮出现在“查看”按钮附近的“我的帐户”>“订单列表”中: 我试图编辑插件并添加以下代码:add_filter('woocommerce_我的_account_我的_orders_actions',array('this,'order_cancel_button'),10,2) 但它不起

在我的WooCommerce网站上,我正在使用这个插件,它允许客户根据付款类型和延迟时间取消订单。但取消按钮仅出现在“
woocommerce\u order\u details\u”表之后的“
”上

我希望此取消按钮出现在“查看”按钮附近的“我的帐户”>“订单列表”中:

我试图编辑插件并添加以下代码:
add_filter('woocommerce_我的_account_我的_orders_actions',array('this,'order_cancel_button'),10,2)

但它不起作用:视图按钮不见了,取消按钮不显示

以下是全部代码:

<?php
/**
 * Plugin Name: WooCommerce Order Cancel For Customers
 * Plugin URI: https://wpmanageninja.com/plugins/order-cancel-for-customers-woocommerce
 * Description: A tiny plugin that will enable customers to cancel woocommerce order within a certain amount of time.
 * Version: 1.0
 * Author: Techjewel
 * Author URI: https://wpmanageninja.com
 * Requires at least: 4.4
 * Tested up to: 4.8
 *
 * Text Domain: wco
 *
 */


// If this file is called directly, abort.
if ( ! defined( 'WPINC' ) ) {
    die;
}

require_once plugin_dir_path( __FILE__ ) . 'libs/class-wco-woo-settings.php';

if ( ! class_exists( 'WCOCancelOrder' ) ) :
    class WCOCancelOrder {

        /**
         * Eligible Order statuses for cancel
         * @type array
         */
        private $eligibleCancelStatuses;

        /**
         * New Order Status for Woocommerce Order, It must have wc prefix
         * @type string
         */
        private $custom_order_status_name = 'wc-customer-cancel';

        /**
         * Declare all the action and filter hooks 
         *
         */
        public function init_plugin() {



            add_filter("plugin_action_links_".plugin_basename(__FILE__), array($this, 'wco_plugin_settings_link') );


            $cancelOrderStatus = get_option('wc_wco_settings_activate');
            if($cancelOrderStatus != 'yes') {
                return;
            }

            $eligible_order_statuses = get_option('wc_wco_settings_eligible_statuses', array());

            $this->eligibleCancelStatuses = apply_filters(
                'wco_eligible_cancel_order_statuses', $eligible_order_statuses
            );

            $this->register_custom_order_status();

            add_filter('wc_order_statuses', array($this,'custom_wc_order_statuses'));
            add_action('admin_head', array($this, 'cancel_order_font_icon'));
            add_action('woocommerce_order_details_after_order_table', array($this, 'order_cancel_button'), 10, 1);
            add_filter('woocommerce_my_account_my_orders_actions', array($this, 'order_cancel_button'), 10, 2);
            add_action('wp', array($this, 'process_cancel_order'));
            add_action('wco_after_order_cancel_action', array($this, 'send_email_notification_to_shop_admin'), 10, 2);
            add_filter('wco_notification_email_subject', array($this, 'parse_text_with_order_fields'), 10, 2);
            add_filter('wco_notification_email_body', array($this, 'parse_text_with_order_fields'), 10, 2);
        }

        public function wco_plugin_settings_link($links) { 
              $settings_link = '<a href="admin.php?page=wc-settings&tab=wco_settings">'.__('Settings', 'wco').'</a>'; 
              array_unshift($links, $settings_link); 
              return $links; 
        }


        /**
         * Register New order status for Woocommerce
         *
         * @uses register_post_status()
         */
        public function register_custom_order_status()
        {
            register_post_status( $this->custom_order_status_name, array(
                'label'                     => __('Cancelled By Customer', 'wco'),
                'public'                    => true,
                'show_in_admin_status_list' => true,
                'show_in_admin_all_list'    => true,
                'exclude_from_search'       => false,
                'label_count'               => _n_noop( 'Cancelled By Customer <span class="count">(%s)</span>', 'Cancelled By Customers <span class="count">(%s)</span>' )
            ) );
        }

        /**
         * Append newly registered order-status in woocommerce status lists
         *
         * @param array $order_statuses
         * @return array $new_order_statuses
         */
        public function custom_wc_order_statuses($order_statuses)
        {
            $new_order_statuses = array();

            foreach ( $order_statuses as $key => $status ) {

                $new_order_statuses[ $key ] = $status;

                if ( 'wc-cancelled' === $key ) {
                    $new_order_statuses[$this->custom_order_status_name] = __('Cancelled By Customer', 'wco');
                }
            }

            return $new_order_statuses;
        }

        /**
         * Add order cancel button
         * 
         * @uses $this->can_customer_cancel_order($order)
         * @param $order
         */
        public function order_cancel_button($order) {
            $can_cancel = apply_filters('wco_can_customer_cancel_order', $this->can_customer_cancel_order($order), $order);
            if($can_cancel) {
                $cancel_url = $this->get_cancel_url($order->get_id());

                do_action('wco_before_cancel_button_wrapper', $order);      
        ?>
                <div class="ico_cancel_order_wrapper">

                    <p><i><?php _e('', 'wco'); ?></i> <a class="button" href="<?php echo $cancel_url; ?>"><?php  _e('CANCEL ORDER', 'wco');?></a></p>
                </div>
    <?php
                do_action('wco_after_cancel_button_wrapper', $order);
            }
        }

        public function get_cancel_url($order_id) {
            $urlData = build_query(array(
                'wco_order_cancel_id' => $order_id,
                '_nonce' => wp_create_nonce('wco_customer_cancel_order_' . $order_id),
                'action' => 'process_cancel_order'
            ));

            return site_url().'?'.$urlData;
        }

        /**
         * Process Cancel Order once user request to cancel
         */
        public function process_cancel_order() {
            if(isset($_REQUEST['wco_order_cancel_id'])) {
                $order_id = $_REQUEST['wco_order_cancel_id'];

                if(!wp_verify_nonce($_REQUEST['_nonce'], 'wco_customer_cancel_order_'.$order_id)) {
                    wp_die('Security Error, Please try again!', 'wco');
                }

                $order = wc_get_order($order_id);

                if($this->can_customer_cancel_order($order)) {

                    $redirectUrl = esc_url( wc_get_endpoint_url( get_option( 'woocommerce_myaccount_orders_endpoint', 'orders' ), '', wc_get_page_permalink( 'myaccount' ) ));

                    $redirectUrl = apply_filters('wco_after_cancel_redirect_url', $redirectUrl , $order_id);

                    // cancel the order now
                    $order_status_change_message = __('Customer wants to cancel the order and want to get refund.', 'wco');
                    $order_status_change_message = apply_filters('wco_after_order_cancel_note', $order_status_change_message, $order_id);

                    $success_message = get_option('wc_wco_settings_cancel_success_message', __('Your order has been submitted as "Cancelled by Customer"!', 'wco'));
                    $success_message = apply_filters('wco_after_order_cancel_message', $success_message, $order_id);

                    if(!wc_has_notice($success_message)) {
                        wc_add_notice($success_message, 'success');
                    }

                    $order = new WC_Order($order_id);
                    $order->update_status($this->custom_order_status_name, $order_status_change_message);
                    do_action('wco_after_order_cancel_action', $order, get_current_user_id());
                    wp_redirect($redirectUrl);
                    die();
                } else {
                    wp_die('Sorry! You can not cancel this order now!', 'wco');
                }
            }

        }

        /**
         * Determine if customer can cancel a selected order
         * 
         * @param $order
         *
         * @return bool
         */
        private function can_customer_cancel_order($order)
        {
            $cancelOrderStatus = get_option('wc_wco_settings_activate');
            if($cancelOrderStatus != 'yes') {
                return false;
            }

            $cancelTimeValidityMinutes = apply_filters('wco_cancel_validity_minutes', get_option('wc_wco_settings_cancel_order_threshold_time', 0), $order);
            $cancelTimeValidity = $cancelTimeValidityMinutes * 60; // in seconds

            $customer_id = $order->get_customer_id();
            $user_ID = get_current_user_id();

            $order_timestamp_diff = strtotime(current_time('mysql')) - strtotime($order->get_date_created());

            if ($cancelTimeValidity > $order_timestamp_diff && $customer_id == $user_ID && in_array($order->get_status(), $this->eligibleCancelStatuses) ) {
                return true;
            }
            return false;
        }

        /**
         * CSS for Cancel Order Icon
         */
        public function cancel_order_font_icon()
        {
            echo '<style>
                    mark.customer-cancel:after{
                        font-family:WooCommerce;
                        speak:none;
                        font-weight:400;
                        font-variant:normal;
                        text-transform:none;
                        line-height:1;
                        -webkit-font-smoothing:antialiased;
                        margin:0;
                        text-indent:0;
                        position:absolute;
                        top:0;
                        left:0;
                        width:100%;
                        height:100%;
                        text-align:center;
                    }

                    mark.customer-cancel:after{
                        content:"\e012";
                        color:#ff0000;
                    }
          </style>';
        }

        /**
         * Send email notification to admin once the customer cancel an order
         * 
         * @param $order
         * @param $user_id
         */
        public function send_email_notification_to_shop_admin($order, $user_id) {
            $email_to = apply_filters('wco_notification_email', get_option('wc_wco_settings_shop_owner_email'), $order);
            echo $email_to;

            if(!$email_to)
                return;

            $email_subject = apply_filters('wco_notification_email_subject', get_option('wc_wco_settings_notification_email_subject'), $order);

            $email_body = apply_filters('wco_notification_email_body', get_option('wc_wco_settings_notification_email_body'), $order);

            $email_headers = array(
                    'Content-Type: text/html; charset=UTF-8'
            );
            $email_headers = apply_filters('wco_notification_email_headers', $email_headers, $order);

            $mail_result = wp_mail($email_to, $email_subject, $email_body, $email_headers);

            do_action('wco_after_cancel_notification_email_sent_action', $mail_result, $order);
        }

        /**
         * Parse text with order shortcodes for email
         * @param $text
         * @param $order
         *
         * @return mixed
         */
        public function parse_text_with_order_fields($text, $order) {
            $replace_fields = array(
                '%%order_id%%' => $order->get_id(),
                '%%customer_name%%' => $order->get_billing_first_name().' '.$order->get_billing_last_name(), 
                '%%order_admin_url%%' => get_edit_post_link($order->get_id())
            );

            apply_filters('wco_parse_email_replace_fields', $replace_fields, $order);

            $replaces = array_keys($replace_fields);
            $replacesWith = array_values($replace_fields);

            $parsed_text = str_replace($replaces, $replacesWith, $text);
            return $parsed_text;
        }
    }
endif;

/**
 * Boot this plugin
 */
function wco_boot_plugin() {
    $cancelOrderClass = new WCOCancelOrder();
    $cancelOrderClass->init_plugin();

    if(is_admin()) {
        WCO_Woo_Settings::init();
    }
}
add_action('init', 'wco_boot_plugin');

新更新2018年5月:


关于您的评论的旧更新取消按钮在3天内可用(从创建日期算起),并在按下取消按钮时解决了一个bug问题(2018年1月制作)

无需编辑或使用此插件,您可以在“操作”列的“我的帐户”>“订单”列表中启用“取消”按钮,使用以下代码片段设置:

  • 订单状态:您希望“取消”按钮出现的位置
  • 从订单创建日期算起的持续时间(以天为单位)
这是代码:

add_filter( 'woocommerce_valid_order_statuses_for_cancel', 'custom_valid_order_statuses_for_cancel', 10, 2 );
function custom_valid_order_statuses_for_cancel( $statuses, $order ){

    // Set HERE the order statuses where you want the cancel button to appear
    $custom_statuses    = array( 'completed', 'pending', 'processing', 'on-hold', 'failed' );

    // Set HERE the delay (in days)
    $duration = 3; // 3 days

    // UPDATE: Get the order ID and the WC_Order object
    if( isset($_GET['order_id']))
        $order = wc_get_order( absint( $_GET['order_id'] ) );

    $delay = $duration*24*60*60; // (duration in seconds)
    $date_created_time  = strtotime($order->get_date_created()); // Creation date time stamp
    $date_modified_time = strtotime($order->get_date_modified()); // Modified date time stamp
    $now = strtotime("now"); // Now  time stamp

    // Using Creation date time stamp
    if ( ( $date_created_time + $delay ) >= $now ) return $custom_statuses;
    else return $statuses;
}
代码位于活动子主题(或主题)的function.php文件或任何插件文件中

这段代码在Woocommerce 3+上进行了测试,可以正常工作。您将得到如下结果:

注意:此函数中返回的默认订单状态为
'pending'
'failed'

您还可以在函数中使用对象参数来设置一些自定义条件

请参阅此相关线程:


默认情况下,当订单状态为“挂起”或“仅失败”时,显示订单的“取消订单”按钮

但我做了这个插件,所以你们可以显示订单取消请求按钮,甚至在处理状态下的订单

您可以设置要有“取消请求按钮”的订单状态

一旦您设置了此用户将在其我的帐户订单列表上有“取消请求”按钮,使用这些按钮,用户可以发送带有取消原因的取消请求


但是,我想使用插件的功能,使取消按钮在设定的时间可见,比如客户放置order@RhobGatchalian这也可以在没有插件的情况下完成…使用插件要复杂得多,太长(太宽)而且对开发人员来说不是一种专业的方式(如果要覆盖插件文件)。RhobGatcalian更新2:时间设置为从创建日期算起的3天-更正了一个打字错误(缺少
)。Gtting此错误未捕获ArgumentCounter错误:函数筛选器参数太少\u woocommerce\u有效\u订单\u状态\u for \u cancel()在WordPress 4.91和WooCudio3.2.6上通过了,但是它仍然显示错误,WP包含了WP HOOK类。PHP在第286行希望得到2个参数,但是通过了1个。请通过演示如何使用插件来解决这个问题来改进这个答案。例如,展示一些示例用法/编码,描述任何需要的设置,然后显示完成结果的屏幕截图。