Php 根据产品变更条款向Woocommerce电子邮件通知添加收件人

Php 根据产品变更条款向Woocommerce电子邮件通知添加收件人,php,wordpress,woocommerce,attributes,email-notifications,Php,Wordpress,Woocommerce,Attributes,Email Notifications,我创建了一个Woocommerce插件,并要求它做两件事: 根据购物车中的产品变体向特定电子邮件地址发送通知消息 电子邮件必须仅包含相关产品,而不包含其他属性的产品 例如: 产品A有一个名为Chef的属性,其中Chef one和Chef two是变量项。用户可以从厨师一号或厨师二号中选择产品A 如果用户从chef one中选择产品A,则必须向发送通知电子邮件chefone@email.com包含所订购产品的名称(它将显示在定期的Woocommerce通知电子邮件中) 如果用户从厨师一号选择产品A

我创建了一个Woocommerce插件,并要求它做两件事:

  • 根据购物车中的产品变体向特定电子邮件地址发送通知消息

  • 电子邮件必须仅包含相关产品,而不包含其他属性的产品

  • 例如:

    产品A有一个名为Chef的属性,其中Chef one和Chef two是变量项。用户可以从厨师一号或厨师二号中选择产品A

    如果用户从chef one中选择产品A,则必须向发送通知电子邮件chefone@email.com包含所订购产品的名称(它将显示在定期的Woocommerce通知电子邮件中)

    如果用户从厨师一号选择产品A,从厨师二号选择产品B,则必须向厨师一号发送只包含产品A的通知电子邮件,向厨师二号发送只包含产品B的通知电子邮件

    我已经使用上的教程创建了插件,并对其进行了调整,以满足上述目的

    我还修改了代码,找到了以下解决方案:

    以下是我的插件类文件中的代码:

    if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
    
    /**
     * A custom WAKIKI Order WooCommerce Email class
     *
     * @since 0.1
     * @extends \WC_Email
     */
    
    class WC_Wakiki_Order_Email extends WC_Email {
    
    
    /**
     * Set email defaults
     *
     * @since 0.1
     */
    public function __construct() {
    
        // set ID, this simply needs to be a unique name
        $this->id = 'wc_wakiki_order';
    
        // this is the title in WooCommerce Email settings
        $this->title = 'WAKIKI Order';
    
        // this is the description in WooCommerce email settings
        $this->description = 'WAKIKI Order Notification emails are sent when a customer places an order on the website';
    
        // these are the default heading and subject lines that can be overridden using the settings
        $this->heading = 'WAKIKI Delivery Order';
        $this->subject = 'WAKIKI Delivery Order';
    
        // these define the locations of the templates that this email should use, we'll just use the new order template since this email is similar
        $this->template_html  = 'emails/admin-new-order.php';
        $this->template_plain = 'emails/plain/admin-new-order.php';
    
        // Trigger on new paid orders
        add_action( 'woocommerce_order_status_pending_to_processing_notification', array( $this, 'trigger' ) );
        add_action( 'woocommerce_order_status_failed_to_processing_notification',  array( $this, 'trigger' ) );
    
        // Call parent constructor to load any other defaults not explicity defined here
        parent::__construct();
    
        // this sets the recipient to the settings defined below in init_form_fields()
        $this->recipient = $this->get_option( 'recipient' );
    
        // if none was entered, just use the WP admin email as a fallback
        if ( ! $this->recipient )
            $this->recipient = get_option( 'admin_email' );
    }
    
    
    /**
     * Determine if the email should actually be sent and setup email merge variables
     *
     * @since 0.1
     * @param int $order_id
     */
    public function trigger( $order_id ) {
    
        // Bail if no order ID is present
        if ( ! $order_id )
            return;
    
          $order = new WC_Order( $order_id );
    
          // Find the product_id
          $items = $order->get_items();
          foreach ( $items as $item ) {
              $product_id = $item['product_id'];
          }
                // From the product_id get the product attribute
                $product = new WC_Product( $product_id );  // create an object of WC_Product class
    
                $patt = $product->get_attributes();  // call get_attributes method
    
                // Condition valid to send the email (if the attributes is chef)
                if ( array_key_exists('pa_chef', $patt) ) 
    
                // Determine which email address to send to, based on Product Attribute Term)
                add_filter( 'new_order' , 'add_recipient', 20, 2 );
    
                function add_recipient( $email, $order ) {
                    $additional_email = "info@email.com";
                    $terms = get_terms("pa_chef");
                    if( $order->$term->name == "pa_chef-one" ){
                     $email = explode( ',', $email );
                     array_push( $email, $additional_email );
    }
    return $email;
    }
    
    
    
        {
                // Send the email
                // Setup order object
                $this->object = new WC_Order( $order_id );
                $this->recipient    = $this->object->billing_email;
    
                // Replace variables in the subject/headings
                $this->find[] = '{order_date}';
                $this->replace[] = date_i18n( woocommerce_date_format(), strtotime( $this->object->order_date ) );
    
                $this->find[] = '{order_number}';
                $this->replace[] = $this->object->get_order_number();
    
                if ( ! $this->is_enabled() || ! $this->get_recipient() )
                    return;
    
                // Send the email!
                $this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() );
    
            }
    
            else
            {
                return; //do nothing if there is not chef attribute
            }
    }
    
    
    /**
     * get_content_plain function
     *
     * @since 0.1
     * @return string
     */
    public function get_content_plain() {
        ob_start();
        woocommerce_get_template( $this->template_plain, array(
            'order'         => $this->object,
            'email_heading' => $this->get_heading()
        ) );
        return ob_get_clean();
    }
    
    
    /**
     * Initialize Settings Form Fields
     *
     * @since 2.0
     */
    public function init_form_fields() {
    
        $this->form_fields = array(
            'enabled'    => array(
                'title'   => 'Enable/Disable',
                'type'    => 'checkbox',
                'label'   => 'Enable this email notification',
                'default' => 'yes'
            ),
            'recipient'  => array(
                'title'       => 'Recipient(s)',
                'type'        => 'text',
                'description' => sprintf( 'Enter recipients (comma separated) for this email. Defaults to <code>%s</code>.', esc_attr( get_option( 'admin_email' ) ) ),
                'placeholder' => '',
                'default'     => ''
            ),
            'subject'    => array(
                'title'       => 'Subject',
                'type'        => 'text',
                'description' => sprintf( 'This controls the email subject line. Leave blank to use the default subject: <code>%s</code>.', $this->subject ),
                'placeholder' => '',
                'default'     => ''
            ),
            'heading'    => array(
                'title'       => 'Email Heading',
                'type'        => 'text',
                'description' => sprintf( __( 'This controls the main heading contained within the email notification. Leave blank to use the default heading: <code>%s</code>.' ), $this->heading ),
                'placeholder' => '',
                'default'     => ''
            ),
            'email_type' => array(
                'title'       => 'Email type',
                'type'        => 'select',
                'description' => 'Choose which format of email to send.',
                'default'     => 'html',
                'class'       => 'email_type',
                'options'     => array(
                    'plain'     => __( 'Plain text', 'woocommerce' ),
                    'html'      => __( 'HTML', 'woocommerce' ),
                    'multipart' => __( 'Multipart', 'woocommerce' ),
                )
            )
        );
    }
    
    这是我能得到的最接近的,但它不起作用。我怀疑问题出在“根据产品属性术语确定发送到哪个电子邮件地址”这句话的周围。插件一直在加载,直到我添加了那个部分

    该函数应该在一个单独的插件文件中吗

    我还需要帮助,使电子邮件中只包含与发送给的供应商相关的信息

    任何帮助这个插件工作将不胜感激

    WooCommerce(或您的代码)中不存在新订单的筛选器

    正确的过滤器挂钩(位于类别核心代码第269行)如下所示:

    $recipient  = apply_filters( 'woocommerce_email_recipient_' . $this->id, $this->recipient, $this->object );
    
    在这个钩子中,
    $this->id
    是您的“
    新订单”

    您的代码中存在较大错误:

    • 术语名称应该类似于
      “one”
      “chef one”
      ,但绝对不是
      “pa_chef-one”
      ,因为
      “pa_chef”是属性“chef”的分类标准
    • 多个电子邮件收件人不在一个数组中,而是在一个分隔的字符串中
    因此,正确的代码应该是:

    add_filter( 'woocommerce_email_recipient_new_order', 'add_recipient', 10, 2 );
    function add_recipient( $recipient, $order )
    {
        if ( ! is_a( $order, 'WC_Order' ) ) return $recipient;
    
        // Additional email recipient
        $additional_email = "info@email.com";
    
        // The term name "pa_chef-one" is very strange … It should be "one" or "chef-one" (may be)
        $term_slug = "one";
    
        $has_term = false;
    
        // Iterating through each order item
        foreach ($order->get_items() as $item_id => $item_obj) {
            $variation_id = $item_obj->get_variation_id();
            $variation_obj = wc_get_product($variation_id);
            $variation_attributes = $variation_obj->get_attributes();
            foreach( $variation_attributes as $taxonomy_key => $term_value ){
    
                if( $taxonomy_key == "pa_chef" && $term_value == $term_slug ){
                    $recipient .= ','. $additional_email;
                    $has_term = true;
                    break; // stop the 2nd loop
                }
            }
            if( $has_term ) break; // stop the 1st loop
        }
        return $recipient;
    }
    
    代码位于活动子主题(或主题)的function.php文件或任何插件文件中

    为WooCommerce版本3制作+


    类似的答案:


    我已在回答中更新了代码……感谢@LoicTheAztec对代码的反馈和改进。我已经将上面的代码片段添加到插件的类文件中,在“确定发送到哪个电子邮件地址”和“return$email;”这两行下面,当我激活插件时仍然收到一个错误。“返回$recipient;”是否替换“$email”功能?这是我的第一个插件,因此我可能需要一定的尝试和错误。@CraigdeGouveia我不完全确定我的代码是否100%,但钩子是正确的。函数中的参数是正确的。(我在最后的答案中用这个钩子添加了一些旧答案的工作参考…)。我已经测试了foreach循环周围的所有代码,它也可以工作。现在问题可能出在您将在此函数中设置的术语名称或slug中。问题也可能在其他地方。我希望你能找到路。但是这里的主要问题是关于钩子的,这个钩子就是这个问题的女仆。