草庐IT

php - WooCommerce 通过 AJAX 触发自定义电子邮件

coder 2024-01-05 原文

您好,感谢您的光临。 我目前正在为 wordpress 编写一个插件。我需要某个页面内的按钮,触发电子邮件通知。我认为使用 woocommerce 电子邮件功能会很好,因为它是客户电子邮件,我也想使用 woocommerce-email-templates。

在我的插件中我包含了我的类扩展

function add_wc_custom_email( $email_classes ) {
    require( 'includes/class-wc-custom-email.php' );
    $email_classes['WC_Custom_Email'] = new WC_Custom_Email();

    return $email_classes;
}
add_filter( 'woocommerce_email_classes', 'add_wc_custom_email' );
//if i write a print_r(something) inside this function, just to alert if this filters hits, i don't see a result, so i think the error is here.. the filter gets hit under woocommerce->settings->emails but not, if you simply load a page in the backend 

在文件 class-wc-custom-email.php 中我有我的类扩展

class WC_Custom_Email extends WC_Email {
    public function __construct() {
        …
    }
    public function mail( $var1, $var2, $var3 ) {
        …
    }
}

我的ajax是这样的

( function( $ ) {
    $('#button1').on( "click", function() {
        $.post(
            ajaxurl,
            {
                'action' : 'jnz_email_custom',
                'page_id': '<?php the_ID(); ?>',
            },
            function ( response ) {
                console.log( "triggered", response )
            }
        );
    });
})(jQuery);

ajax 处理程序看起来像这样

add_action('wp_ajax_jnz_email_custom', 'jnz_email_custom');
function jnz_email_custom() {
    $message = email_custom( $_POST['page_id'] );
    $response = array(
        'what'   => 'email_custom_triggered',
        'action' => 'email custom triggered',
        'id'     => $_POST['page_id'],
        'data'   => $message,
    );
    $xmlResponse = new WP_Ajax_Response( $response );
    $xmlResponse->send();
}

我用ajax触发的函数

function email_custom( $page_id = 2728 ) {
    $field = get_field( 'something', $page_id )[0];
    //get_field() is a function by plugin 'Advanced Custom Fields' and works fine

    function somethingSomething( $field ) {
        …
        return $results;
    }

    foreach ( $results as $result ) :
        $email = new WC_Custom_Email();
        $email->mail( $result['details']['name'], $result['details']['email'], $result['something'] );
    endforeach;

    return json_encode( $results, JSON_UNESCAPED_UNICODE );
    //this is the $xmlResponse i get from the ajax call and looks fine (but only works, if i uncomment the 'new WC_Custom_Email()' stuff. otherwise i see the "Fatal Error" thingy)
}

响应是: fatal error :在...中找不到类“WC_Custom_Email”

所有功能都工作正常,如果我返回 $results,我会看到所有我想要的并且没有错误。

相同的是,当我将其更改为 new WC_Email() 时。所以我的猜测是,woocommerce 功能没有加载到我的 admin->edit_page_xy 屏幕中。所以最大的问题是:我如何将 woocommerce 功能(或仅电子邮件功能)加载到我的插件中..??

希望这有点清楚并且有任何意义。我对 PHP 知之甚少,对 oop 完全陌生。

最佳答案

好吧,这有点像野兽。

我编写了一个具有以下结构的演示插件:

kia-ajax-email.php
- includes
  -- class-wc-test-ajax-email.php
-- js
   -- script.js
-- templates
   -- emails
      -- test.php
      -- plain
         -- test.php

主要插件文件kia-ajax-email.php

此文件负责将脚本排入队列、添加您的自定义电子邮件类、在单个产品页面上创建按钮以及将操作注册为触发 WooCommerce 电子邮件的操作:

<?php
/**
 * Plugin Name: Test Ajax Email
 * Plugin URI: http://stackoverflow.com/q/35018177/383847
 * Description: Demo plugin for sending email via ajax
 * Author: helgatheviking
 * Author URI: http://www.kathyisawesome.com
 * Version: 0.1
 *
 * License: GNU General Public License v3.0
 * License URI: http://www.gnu.org/licenses/gpl-3.0.html
 *
 */

if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly


/**
 *  get plugin path
 *
 * @since 0.1
 */
function kia_ajax_email_plugin_path(){
    return untrailingslashit( plugin_dir_path( __FILE__ ) ); 
}

/**
 *  Add a custom email to the list of emails WooCommerce should load
 *
 * @since 0.1
 * @param array $email_classes available email classes
 * @return array filtered available email classes
 */
function kia_add_custom_email( $email_classes ) {

    // include our custom email class
    require_once( 'includes/class-wc-test-ajax-email.php' );

    // add the email class to the list of email classes that WooCommerce loads
    $email_classes['WC_Test_Ajax_Email'] = new WC_Test_Ajax_Email();

    return $email_classes;

}
add_filter( 'woocommerce_email_classes', 'kia_add_custom_email' );


/**
 *  Enqueue the scripts with apprpriate vars
 *
 * @since 0.1
 */
function kia_ajax_email_js(){
    wp_enqueue_script( 'kia_ajax_email', plugins_url( 'js/script.js', __FILE__ ), array('jquery'), '1.0.0', true );
    wp_localize_script( 'kia_ajax_email', 'kia_ajax_email', array( 
                'ajax_url'                  => WC()->ajax_url(),
                'wc_ajax_url'               => WC_AJAX::get_endpoint( "test_email" ) ) );
}
add_action( 'wp_enqueue_scripts', 'kia_ajax_email_js', 20 );


/**
 *  AJAX callback
 *
 * @since 0.1
 */
function kia_ajax_email_callback() {
    $mailer = WC()->mailer();

    do_action( 'kia_trigger_ajax_email' );

    die('ajax finished'); // this is required to terminate immediately and return a proper response
}
add_action( 'wc_ajax_test_email', 'kia_ajax_email_callback' );


/**
 *  Register action as one that sends emails
 *
 * @since 0.1
 */
function kia_ajax_email_action( $actions ){
    $actions[] = 'kia_trigger_ajax_email';
    return $actions;
}
add_action( 'woocommerce_email_actions', 'kia_ajax_email_action' );


/**
 *  Add a dummy button to product page
 *
 * @since 0.1
 */
function kia_ajax_email_button(){
    echo '<button class="email-trigger">' . __( 'Email Trigger', 'kia-ajax-email' ). '</button>';
}
add_action('woocommerce_before_single_product_summary', 'kia_ajax_email_button');

电子邮件类 includes/class-wc-test-ajax-email.php

<?php

if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly

/**
 * A custom Expedited Order WooCommerce Email class
 *
 * @since 0.1
 * @extends \WC_Email
 */
class WC_Test_Ajax_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_text_ajax_email';

        // this is the title in WooCommerce Email settings
        $this->title = 'Test Ajax';

        // this is the description in WooCommerce email settings
        $this->description = 'Text emails are sent when ajax button is clicked';

        // these are the default heading and subject lines that can be overridden using the settings
        $this->heading = 'Test Ajax';
        $this->subject = 'Test Ajax';

        // 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/test.php';
        $this->template_plain = 'emails/plain/test.php';

        // Trigger on new paid orders
        add_action( 'kia_trigger_ajax_email', 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() {

        if ( ! $this->is_enabled() || ! $this->get_recipient() )
            return;

        // woohoo, send the email!
        $this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() );
    }


    /**
     * get_content_html function.
     *
     * @since 0.1
     * @return string
     */
    public function get_content_html() {
        return wc_get_template_html( $this->template_html, array(
            'email_heading' => $this->get_heading(),
            'sent_to_admin' => false,
            'plain_text'    => false,
            'email'         => $this
        ),
        '',
        kia_ajax_email_plugin_path() . "/templates/" );
    }


    /**
     * get_content_plain function.
     *
     * @since 0.1
     * @return string
     */
    public function get_content_plain() {
        return wc_get_template_html( $this->template_plain, array(
            'email_heading' => $this->get_heading(),
            'sent_to_admin' => false,
            'plain_text'    => false,
            'email'         => $this
        ),
        '',
        kia_ajax_email_plugin_path() . "/templates/" );
    }


    /**
     * 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' ),
                )
            )
        );
    }


} // end \WC_Test_Ajax_Email class

脚本js/script.js

jQuery(document).ready(function($) {

  $(".email-trigger").on("click", function(e) {

    e.preventDefault();

    $.ajax({
        url: kia_ajax_email.wc_ajax_url.toString(),
        type: 'POST',
        data: {
          'whatever': 1234
        },
      })
      .done(function(data) {
        if (console && console.log) {
          console.log(data);
        }
      });
  });

});

电子邮件模板。首先是 templates/emails/test.phptemplates/emails/plain/test.php

<?php
/**
 * Test email
 *
 * This template can be overridden by copying it to yourtheme/woocommerce/emails/test.php.
 *
 * HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
 * will need to copy the new files to your theme to maintain compatibility. We try to do this.
 * as little as possible, but it does happen. When this occurs the version of the template file will.
 * be bumped and the readme will list any important changes.
 *
 * @see         http://docs.woothemes.com/document/template-structure/
 * @author      WooThemes
 * @package     WooCommerce/Templates/Emails
 * @version     2.5.0
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * @hooked WC_Emails::email_header() Output the email header
 */
do_action( 'woocommerce_email_header', $email_heading, $email ); ?>

<p><?php _e( 'A test email is being sent', 'kia-ajax-email' ); ?></p>


<?php
/**
 * @hooked WC_Emails::email_footer() Output the email footer
 */
do_action( 'woocommerce_email_footer', $email );

templates/emails/plain/test.php

<?php
/**
 * Test email
 *
 * This template can be overridden by copying it to yourtheme/woocommerce/emails/plain/test.php.
 *
 * HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
 * will need to copy the new files to your theme to maintain compatibility. We try to do this.
 * as little as possible, but it does happen. When this occurs the version of the template file will.
 * be bumped and the readme will list any important changes.
 *
 * @see         http://docs.woothemes.com/document/template-structure/
 * @author      WooThemes
 * @package     WooCommerce/Templates/Emails
 * @version     2.5.0
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}


echo "= " . $email_heading . " =\n\n";

echo "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n";


_e( 'A test email is being sent', 'kia-ajax-email' );

echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n";

echo apply_filters( 'woocommerce_email_footer_text', get_option( 'woocommerce_email_footer_text' ) );

展望 future

这会在单击按钮时发送一封电子邮件。您将需要修改该按钮的位置,并且因为它有点慢(或者在我的本地设置中看起来很慢)我肯定会推荐某种微调器/通知来指示该操作正在发生。您还需要自定义通过 ajax 发送的数据以及这些数据如何在模板中结束。这只是一个概念证明。

关于php - WooCommerce 通过 AJAX 触发自定义电子邮件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35018177/

有关php - WooCommerce 通过 AJAX 触发自定义电子邮件的更多相关文章

  1. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  2. ruby - 通过 rvm 升级 ruby​​gems 的问题 - 2

    尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub

  3. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  4. ruby - 通过 erb 模板输出 ruby​​ 数组 - 2

    我正在使用puppet为ruby​​程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby​​不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这

  5. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  6. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  7. ruby - 通过 ruby​​ 进程共享变量 - 2

    我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是

  8. ruby - 通过 RVM (OSX Mountain Lion) 安装 Ruby 2.0.0-p247 时遇到问题 - 2

    我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search

  9. ruby-on-rails - Enumerator.new 如何处理已通过的 block ? - 2

    我在理解Enumerator.new方法的工作原理时遇到了一些困难。假设文档中的示例:fib=Enumerator.newdo|y|a=b=1loopdoy[1,1,2,3,5,8,13,21,34,55]循环中断条件在哪里,它如何知道循环应该迭代多少次(因为它没有任何明确的中断条件并且看起来像无限循环)? 最佳答案 Enumerator使用Fibers在内部。您的示例等效于:require'fiber'fiber=Fiber.newdoa=b=1loopdoFiber.yieldaa,b=b,a+bendend10.times.m

  10. ruby - 触发器 ruby​​ 中 3 点范围运算符和 2 点范围运算符的区别 - 2

    请帮助我理解范围运算符...和..之间的区别,作为Ruby中使用的“触发器”。这是PragmaticProgrammersguidetoRuby中的一个示例:a=(11..20).collect{|i|(i%4==0)..(i%3==0)?i:nil}返回:[nil,12,nil,nil,nil,16,17,18,nil,20]还有:a=(11..20).collect{|i|(i%4==0)...(i%3==0)?i:nil}返回:[nil,12,13,14,15,16,17,18,nil,20] 最佳答案 触发器(又名f/f)是

随机推荐