Добавьте кнопку в заказы администратора WooCommerce, которая отправляет пользовательское уведомление по электронной почте

В настоящее время я работаю над проектом, который предполагает внедрение кнопки уведомления, чтобы оповещать наших водителей по электронной почте, когда заказ готов к выдаче. Однако я столкнулся с загадочной проблемой, которая заставила меня почесать затылок.

Вот ситуация: при каждом нажатии кнопки уведомления статус заказа необъяснимым образом меняется на «ожидает оплаты». Это нежелательное поведение, и я изо всех сил пытаюсь определить причину этой проблемы.


add_action( 'woocommerce_admin_order_data_after_order_details', 'send_driver_email_on_order_ready' );
function send_driver_email_on_order_ready( $order_id ) {
    $order = wc_get_order( $order_id );
    $id=$order->get_ID();
    $status = $order->get_status();
    $meta_data = $order->get_meta_data();
    
    if ($status=='processing' || 'driver-assigned' || 'out-for-delivery'){
        foreach ( $meta_data as $meta ) {
            if ( $meta->key === 'lddfw_driverid' ) {
                $driver_id = $meta->value;
            }
            if ( $meta->key === 'Order_Ready' ) {
                $order_ready_value = $meta->value;

                if ( $order_ready_value === 'Yes' ) {
                    // Check if email has already been sent
                    $email_sent = $order->get_meta( 'email_sent', true );

                    if ( $email_sent != 'Yes' ) {
                        // Get driver information
                        $driver = get_userdata( $driver_id );
                        $driver_name = $driver->display_name;
                        $driver_email = $driver->user_email;

                        // Send email to driver
                        $subject = 'Order no.' . $id . ' ready for pickup';
                        $message = 'Hello ' . $driver_name . ',<br><br> Order no.' . $id . ' is now ready for pickup.';
                        $headers = array( 'Content-Type: text/html; charset=UTF-8' );

                        if ( wp_mail( $driver_email, $subject, $message, $headers ) ) {
                            // Update email_sent meta value
                            $order->update_meta_data( 'email_sent', 'Yes' );
                            $order->save();
                        }
                    }
                }
            }
        }
    }
}
add_filter('wp_mail_from', 'original_mail_address_email');
function original_mail_address_email(){
    $email ='[email protected]';
    return $email;
}
add_filter('wp_mail_from_name', 'email_name_order_ready');
function email_name_order_ready(){
    return 'Oven Fresh';
}


В дополнение к этой задаче я хотел бы улучшить функциональность кнопки. В идеале я хочу, чтобы кнопка отображалась только тогда, когда статус заказа «назначен водитель» или «готов к доставке». Это упростило бы процесс и сделало бы его более эффективным для нашей команды.

Любая помощь, идеи или предложения, которые вы можете предоставить, будут очень признательны. Ваша помощь будет не чем иным, как благословением.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
0
53
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Есть ошибки, ненужные сложности и недочеты.

Ниже будет отображена кнопка для отправки уведомления по электронной почте водителю об определенных статусах заказа:

  • новый столбец в списке заказов администратора,


  • отдельные заказы после платежного адреса.

При отправке электронного письма вместо кнопки появляется сообщение об успехе и устанавливается примечание администратора. После отправки электронного письма вместо кнопки отображается строка «Электронное письмо отправлено».

// Utility function: Display the button "Send Email"
function send_email_button_html( $order, $order_id ) {
    $order_ready = $order->get_meta('Order_Ready');
    $email_sent  = $order->get_meta('email_sent');

    $allowed_statuses = ['driver-assigned', 'out-for-delivery'];

    if ( in_array( $order->get_status(), $allowed_statuses ) && $order_ready === 'Yes' && $email_sent !== 'Yes' ) {
        printf('<div><button type = "button" class = "email-btn button button-primary" data-id = "%d">%s</button>
        <div class = "message-%d"></div></div>', $order_id, __("Send email"), $order_id );
    } elseif ( $email_sent === 'Yes' ) {
        printf('<div>%s</div>', __("Email sent"));
    }
}

// Utility function: Send the email to the driver
function send_email_to_driver( $order ){
    $from_name  = __('Oven Fresh'); // Reply-to from name
    $from_email = '[email protected]'; // Reply-to from email

    $driver_id  = $order->get_meta('lddfw_driverid');
    $driver     = wp_get_current_user( $driver_id );
    $mailer     = WC()->mailer(); // Load WC Mailer

    $headers    = 'Content-Type: text/html; charset=UTF-8'."\r\n";
    $headers   .= 'Reply-to: ' . $from_name . ' <' . $from_email . ">\r\n";

    $subject    = sprintf(__('Order no.%s ready for pickup'), $order->get_order_number());

    $message    = sprintf(__('Hello %s,<br><br> Order no.%s is now ready for pickup.'), $driver->display_name, $order->get_order_number());
    $message    = '<html><head></head><body><p>'.$message.'</p></body><html>';
    $message    = $mailer->wrap_message( __('Order ready for pickup'), $message );
 
    $email_sent = $mailer->send( $driver->user_email, $subject, $message, $headers ); // Send email to diver

    if ( $email_sent ) {
        $order->update_meta_data( 'email_sent', 'Yes' ); // Tag order
        $order->add_order_note( __('Email sent to the driver.') ); // Add an admin note to the order
        $order->save(); // Save to database
    } 
}

// Add a new column in admin order list
add_filter( 'manage_edit-shop_order_columns', 'order_column_send_email_driver' );
function order_column_send_email_driver( $columns ) {
    $new_columns = array();

    foreach ( $columns as $column_key => $column_label ) {
        if ( 'order_total' === $column_key ) {
            $new_columns['email_driver'] = __('Email driver', 'woocommerce');
        }
        $new_columns[$column_key] = $column_label;
    }
    return $new_columns;
}

// Display send email button as content for column in admin order list
add_action( 'manage_shop_order_posts_custom_column', 'order_column_send_email_button', 10, 2 );
function order_column_send_email_button( $column, $order_id ) {
    if ( $column === 'email_driver' ) {
        global $the_order;
        send_email_button_html( $the_order, $order_id );
    }     
}

// Display send email button in Single orders
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'display_send_email_button_single_order' );
function display_send_email_button_single_order( $order ) {
    send_email_button_html( $order, $order->get_id() );
}

// WP Admin Ajax receiver: Trigger email and update order
add_action('wp_ajax_send_email_driver', 'send_email_driver_ajax');
function send_email_driver_ajax() {
    if (isset($_POST['order_id'])) {
        $order = wc_get_order(intval($_POST['order_id']));
        echo send_email_to_driver($order) ? '1' : '0';
    }
    wp_die(); // Exit silently (mandatory)
}

// jQuery Ajax
add_action('admin_footer', 'send_email_driver_js');
function send_email_driver_js() {
    global $pagenow, $typenow;

    if ( in_array( $pagenow, ['edit.php', 'post.php'] ) && 'shop_order' === $typenow ) :
    ?>
    <script id = "send-email-driver" type = "text/javascript">
        jQuery(function($) {
            $('body').on('click', 'button.email-btn', function(e) {
                e.preventDefault();
                const btnSend = $(this),
                      orderID = btnSend.data('id');
                      
                $.ajax({
                    url:  '<?php echo admin_url( 'admin-ajax.php' ); ?>',
                    type: 'POST',
                    data: {
                        'action'  : 'send_email_driver',
                        'order_id': orderID,
                    },
                    success: function(response) {
                        if ( response ) {
                            btnSend.replaceWith('<small style = "color:green;">Email just sent!</small>');
                        } else {
                            $('.message-'+orderID).html('<small style = "color:green;font-weight:bold;">Email NOT sent!</small>').fadeIn().delay(2000).fadeOut();
                        }
                    },
                });
            });
        });
    </script>
    <?php
    endif;
}

Код находится в файле function.php вашей дочерней темы (или в плагине). Протестировано и работает.

Скриншот отправленного письма:

Другие вопросы по теме