今天收到两条评论,发现没有收到邮件通知,转念一想自己也没设置过邮件相关的配置,查了一下文档发现wordpress是通过wp_mail函数发送邮件的。
打开wordpress源码文件 \wp-includes\pluggable.php,定位到wp_mail函数:
<?php
//255行代码如下
global $phpmailer;
// (Re)create it, if it's gone missing.
if ( ! ( $phpmailer instanceof PHPMailer\PHPMailer\PHPMailer ) ) {
require_once ABSPATH . WPINC . '/PHPMailer/PHPMailer.php';
require_once ABSPATH . WPINC . '/PHPMailer/SMTP.php';
require_once ABSPATH . WPINC . '/PHPMailer/Exception.php';
$phpmailer = new PHPMailer\PHPMailer\PHPMailer( true );
$phpmailer::$validator = static function ( $email ) {
return (bool) is_email( $email );
};
}看到了熟悉的PHPMainler。https://github.com/PHPMailer/PHPMailer ,继续往下:
<?php
//第467行代码
// Set to use PHP's mail().
$phpmailer->isMail();->isMail();通过IDE追溯一下isMail,PHPMailer类如下:
<?php
/**
* Send messages using SMTP.
*/
public function isSMTP()
{
$this->Mailer = 'smtp';
}
/**
* Send messages using PHP's mail() function.
*/
public function isMail()
{
$this->Mailer = 'mail';
}由此可知worpdress使用的是php自带的mail函数,继续拓展一下:
我的PHP压根就没配置过这些玩意,理所当然,邮件发不出,但是讲道理,为什么不提供一个错误日志或者干脆抛致命错误🤦♂️。
继续往下看代码:
<?php
//第473行
// If we don't have a content-type from the input headers.
if ( ! isset( $content_type ) ) {
$content_type = 'text/plain';
}
//第486行
$phpmailer->ContentType = $content_type;默认邮件内容类型为普通文本,先记录一下,继续往下:
<?php
//第583h行
do_action( 'wp_mail_failed', new WP_Error( 'wp_mail_failed', $e->getMessage(), $mail_data ) );阅读完毕,梳理一下中间过程的钩子。
官方文档:https://developer.wordpress.org/reference/hooks/wp_mail/
wp_mail,用于过滤wp_mail()使用到的参数,参数列表:
add_filter时参数为上方数组,过滤后返回同样的数组即可。
官方文档:https://developer.wordpress.org/reference/hooks/pre_wp_mail/
简单的说,得到上面使用的参数,判断是否需要中断发送,返回false,会直接中断邮件发送。
官方文档:https://developer.wordpress.org/?s=wp_mail_from
修改发信地址和发信人。
官方文档:https://developer.wordpress.org/reference/hooks/wp_mail_failed/
这是一个action钩子,发送失败时触发这个钩子上的函数。
官方文档:https://developer.wordpress.org/reference/hooks/phpmailer_init/
这是一个action,参数是phpmailer的引用地址,可以在这个钩子进行完全的自定义操作。
新发现
do_action_ref_array和do_action的区别,应该在于一个是引用传递参数一个是按值传递
这就就不细说了,发送成功时触发的钩子。
准备着手改造,计划打算最终的成品应该如下:
全局查找wp_mail(),被调用过的地方。
<?php
//\wp-admin\includes\privacy-tools.php
//第588行
//向用户发送一封带有个人数据导出文件链接的电子邮件
wp_privacy_send_personal_data_export_email();
//主题自动更新通知
//插件自动更新通知
//新人注册通知
//新人欢迎通知
//密码修改通知
//邮件地址修改通知
...............................太多了,找点有用的吧 ..............😂😂😂😂🤣
开启评论审核之后,有新的评论时wordpress会自动给站长邮箱发送邮件,我们需要做的就是在评论被回复时通知评论对象,以及审核通过时通知评论对象。(主动调用wp_mail),邮件模板就不写了,直接借鉴一个开源的。https://github.com/seatonjiang/kratos
<?php
add_action('comment_unapproved_to_approved', 'callback');评论审核通过时,通知评论者,和被回复者。剩下的就是把逻辑糅合到主题里了。