优先级调用方法-PHPMailer->addAddress(空)

时间:2018-11-13 作者:J.D.

我目前正在制作一个可湿性粉剂小部件,我一直坚持这样做。

我想传递一个变量$emailReceiver 从我的form() 方法到我的deliver_mail() 方法问题是我的deliver_mail() 方法已首先执行,它给出以下错误:

“未捕获的phpmailerException:无效地址:…PHPMailer->addaddaddress(NULL)”

这个想法是,当表单显示在小部件部分时,用户应该填写收件人的电子邮件地址。

 add_action( \'widgets_init\', \'contact_form_register_widget\' );
 $add_action = new jpen_Custom_Form_Widget();
 $add_action->init();

function contact_form_register_widget() {
    register_widget( \'jpen_Custom_Form_Widget\');

    wp_register_script( "contact-form-script-widget", WP_PLUGIN_URL.\'/contact-form-widget/contact-form-script-widget.js\', array(\'jquery\') );
    wp_localize_script( \'contact-form-script-widget\', \'contactFormAjax\', array( \'ajaxurl\' => admin_url( \'admin-ajax.php\' )));

    wp_enqueue_script( \'jquery\' );
    wp_enqueue_script( \'contact-form-script-widget\' );
}

class jpen_Custom_Form_Widget extends WP_Widget {
    //private $emailReceiver;

    public function __construct() {
        $widget_options = array(
            \'classname\' => \'custom_form_widget\',
            \'description\' => \'This is a Custom Form Widget\',
        );

        parent::__construct( \'custom_form_widget\', \'Custom Form Widget\', $widget_options );
         );

    } 

    //Hooks in a separate class method
    public function init() {

        add_action( \'wp_ajax_send_mail\', array( $this, \'deliver_mail\' ) );
        add_action( \'wp_ajax_nopriv_send_mail\', array( $this, \'deliver_mail\' ) );
    }

    //deliver mail    
    function deliver_mail() {     

        //name of button 
        require_once "C:/xampp/htdocs/WP/wp-includes/class-phpmailer.php";

        // sanitize form values
        $name    = sanitize_text_field( $_POST["name"] );
        $email   = sanitize_email( $_POST["email"] );
        $subject = sanitize_text_field( $_POST["subject"] );
        $message = esc_textarea( $_POST["message"] );
        // get the blog administrator\'s email address

        $headers = "From: $name <$email>" . "\\r\\n";

        // Localhost
        $mail = new PHPMailer(true);
        $mail->IsSMTP(); // telling the class to use SMTP
        $mail->CharSet = \'UTF-8\';

        $mail->SMTPDebug = 0;                     // enables SMTP debug information (for testing)
        $mail->SMTPAuth = true;                  // enable SMTP authentication
        $mail->SMTPSecure = "ssl";                 // sets the prefix to the servier
        $mail->Host = "mail.gmx.com";      // sets GMX as the SMTP server for example: mail.gmx.com
        $mail->Port = 465;                 // set the SMTP port for the GMX server


        $mail->Username = $email;
        $mail->Password = \'PASS\';

        $mail->SetFrom($email, $name);
        $mail->AddAddress($instance[\'email\']);
         //Here has to be accessed $instance[\'email\'] variable from the form() function;

        $mail->Subject = $subject;
        $mail->MsgHTML($message);

        $headers .= "Content-Type: text/html; charset=utf-8";
        $headers .= "Content-Transfer-Encoding: 8bit";

        try {
            $mail->send();
            $msg = "An email has been sent for verfication.";
            $msgType = "success";

            // wp_safe_redirect( home_url(), 302 );
            //exit();

        } catch (Exception $ex) {
            $msg = $ex->getMessage();
            $msgType = "warning";

            //wp_safe_redirect( home_url(), 302 );
            //exit();
        }

        die();
    }    

    function widget( $args, $instance ) {

        echo $args[\'before_widget\'];


        ?>
<form action="<?php esc_url( $_SERVER[\'REQUEST_URI\'] )?>" method="post" class="contact-form" id="contact-form" >
    <div class=header-contact>
        <p><h2>Contact Form</h2></p>
        <hr>
    </div>
    <div class=input-containers>
        <input type="text" id="name" name="cf-name" pattern="[a-zA-Z0-9 ]+" value="" size="40" placeholder="Име и фамилия"/>
    </div>
    <div class=input-containers>
        <input type="email" id="email" name="cf-email" value="" size="40" placeholder="Поща"/>
    </div>
    <div class=input-containers>
        <input type="text" id="subject" name="cf-subject" pattern="[a-zA-Z ]+" value="" size="40" placeholder="Относно"/>
    </div>
    <div class=input-containers>
        <textarea rows="10" id="message" cols="35" name="cf-message" placeholder="Текст"></textarea>
    </div>
    <div class=input-containers>
        <input type="submit" name="cf-submitted" value="Send" id="submitForm">
        <input type="hidden" name="form_submitted" id="ajax_url" value="<?php echo admin_url(\'admin-ajax.php\'); ?>" />
    </div>
    <button id="btn1">Bacon Button1</button>
    <p id="verify" style="display:none;">Your message has been sent.<br /><br /></p> 
</form>
<script>

</script>
<?php
       echo $args[\'after_widget\']; 
    }

    public function update( $new_instance, $old_instance ) {    
        var_dump( $new_instance);
        return $new_instance;  
    }

    // Displays form in the widget section which the user should use to fill the receiver\'s email address.
    public function form( $instance )
    {

        $emailReceiver = \'\';
        if( !empty( $instance[\'email\'] ) ) {
            $emailReceiver = $instance[\'email\'];
        }

        ?>    
    <p>
        <label for="<?php echo $this->get_field_name( \'email\' ); ?>"><?php _e( \'Email:\' ); ?></label>
        <input class="widefat" id="<?php echo $this->get_field_id( \'email\' ); ?>" name="<?php echo $this->get_field_name( \'email\' ); ?>" type="text" value="<?php echo esc_attr( $emailReceiver ); ?>" />
    </p>
    <?php 
    if(!isset($emailReceiver) || trim($emailReceiver) == \'\') {
        echo "You did not fill out title field.";
    }
    ?>
<?php
    }
}

1 个回复
SO网友:Tom J Nowell

您正在尝试使用$instance 在您的deliver_mail 方法,但该方法中不存在该变量。要获取该变量,您需要在widget 功能,但这是不可能的。该函数仅在显示该小部件的实例时调用,这在管理AJAX调用中永远不会发生。

问题是首先执行了deliver\\u mail()方法,它给了我“未捕获的phpmailerException:无效地址:…PHPMailer->addAddress(NULL)”

这可以解释错误,但是,处理AJAX请求并调用PHPMailer的请求与呈现/保存小部件的请求完全不同。它们也可能运行在完全不同的机器上,记住,PHP请求不像Node/Java/Python web应用程序,每个请求都是从一张白板开始的。这与调用函数的顺序无关,因为没有请求从一开始就调用这两个函数

此外,在WP_Widget 像这样基于对象是极不寻常的。

因此:

首先,将ajax处理程序从小部件对象中分离出来。它们不属于那里第二,你需要随请求一起发送所需的一切第三,你不能将表单发送的电子邮件存储在小部件中,因为你无法知道是哪个小部件发送了请求,在请求中发送电子邮件会允许攻击者使用你的联系表单通过你的服务器向任何人发送任何邮件,这会让你很快被列入黑名单(除其他外),所以这不是一个选项。

相反,您可以存储收件人:

在附加到帖子的选项中,在小部件中选择帖子并传递帖子ID,以便回调可以处理它。此外,我看到您使用了旧的管理AJAX请求,您没有使用更简单/更容易/更新的REST API有什么具体原因吗?

结束

相关推荐

如何检查你是否在Widget.php页面上?

我正在尝试编写一个小部件,我需要将颜色选择器添加到我的小部件表单中。我只想在widget上添加脚本。php页面,而不是所有的管理页面。有没有一种方法可以在我的小部件的构造函数中检测页面?如果不是的话,我怎样才能在我使用widget时包含脚本。php页面?