好吧,这本身并不是一个完整的解决方案,但我将从隔离问题是SQL查询还是wp_mail()
呼叫如果您注释掉wp_mail()
第行,您可以了解函数运行查询和构建消息所需的时间,而无需尝试发送它们。
如果您突然发现该功能的速度非常快,那么可以肯定的是,邮件连接会让您的速度变慢,但不幸的是,这会打开另一罐蠕虫,因为电子邮件配置可能因web主机而异。
另一方面,如果函数同样慢,那么查询很可能是罪魁祸首,那么查看Wordpress生成的实际SQL将非常有帮助,以尝试识别性能泄漏。
编辑:
听起来好像是查询在进行许多连接。在这种情况下,目标是避免这种情况。我们可以利用这样一个事实,即我们正在寻找相同的不同案例wp_usermeta.meta_key
用于构建不需要所有联接的查询的值:
function messages_notify() {
global $post;
// if post already published, abort
if($post->post_status == \'publish\') {
return;
}
// get districts ticked, else abort
$post_districts = get_the_terms($post->ID, \'message_district\');
if(empty($post_districts)) return;
// Build a list of districts to get users from.
$districts = array(
\'Northeast\' => \'whprms_district_ne\',
\'North Central\' => \'whprms_district_nc\',
\'Southeast\' => \'whprms_district_se\',
\'Southwest\' => \'whprms_district_sw\',
\'West\' => \'whprms_district_w\',
//\'Another\' => \'whprms_district_XX\',
);
$searchDistricts = array();
$districtNames = array_keys($districts);
foreach($post_districts as $d){
if(in_array($d->name, $districtNames){
$searchDistricts[] = $districts[$d->name];
}
}
$districts = implode(\' OR \', array_map(function($s){ return "wp_usermeta.meta_key = \'{$s}\'"; }, $searchDistricts)); // Squash it down into an sql-compatible WHERE subclause.
$sql = "SELECT DISTINCT wp_users.*
FROM wp_users
INNER JOIN wp_usermeta ON (wp_users.ID = wp_usermeta.user_id)
WHERE
-- This part isolates to keys in the list of districts
({$districts})
-- Where the value of the district is 1.
AND CAST(wp_usermeta.meta_value AS CHAR) = \'1\'
ORDER BY user_login ASC";
$district_members = $wpdb->WHATEVER_THE_CUSTOM_QUERY_METHOD_IS_CALLED($sql);
$attachment_args = array(\'post_type\' => \'attachment\', \'orderby\' => \'date\', \'order\' => \'ASC\', \'numberposts\' => -1, \'post_status\' => NULL, \'post_parent\' =>$post->ID);
$attachments = get_posts($attachment_args);
if ($attachments) {
$att_array = array();
foreach ($attachments as $attachment) {
$att_array[] = get_the_title($attachment->ID);
}
}
// message only users with desired role(s)
$bcc = array();
foreach($district_members as $district_member) {
// Don\'t use user_can()! It\'s a DB hit!
//if(user_can($district_member->ID, \'board_members\') || user_can($district_member->ID, \'members\')) { //@TODO: Look at $district_member->caps
if(in_array(\'board_members\', $district_member->roles) || in_array(\'members\', $district_member->roles)) {
$bcc[] = $district_member->user_email;
}
}
$subject = \'WHPRMS Message: \'.$post->post_title;
$message = \'New message posted by \';
if(user_can($post->post_author, \'administrator\')) {
$message .= get_the_author_meta(\'user_nicename\', $post->post_author)."\\n\\r";
}
else {
$message .= get_the_author_meta(\'first_name\', $post->post_author).\' \'.get_the_author_meta(\'last_name\', $post->post_author)."\\n\\r";
}
$message .= \'Excerpt: \'.stripslashes(substr($post->post_content, 0, 240)).\'...\'."\\n\\r";
$message .= \'Link: \'.get_permalink($post->ID)."\\n\\r";
$message .= \'District(s): \'.implode(\', \', $the_districts)."\\n\\r";
if (!empty($att_array)) {
$message .= \'Attachment(s): \'.implode(\', \', $att_array)."\\n\\r";
}
$message .= \'You are receiving this message because you belong to one of the districts mentioned above.\';
$chunked_bcc = array_chunk($bcc, 25);
foreach($chunked_bcc as $bcc_chunk){
$headers = array();
$headers[\'Bcc\'] = \'BCC: \'.implode(\', \', $bcc_chunk);
wp_mail(\'[email protected]\', $subject, $message, $headers);
}
}
有几件事没有考虑在内,因为我面前没有这个特定的WP实例可供测试:
无论调用什么\\u CUSTOM\\u QUERY\\u METHOD\\u。用任何正确的方法替换此方法我也不知道返回结果的格式。如果您可以从中获取WP\\u用户对象,那将是理想的,因为下一部分取决于$district\\u用户看起来与get_users()
已提供也要注意foreach($district_members as $district_member)
. 这个user_can()
方法是对每个正在循环的用户进行2次不必要的DB命中。您已经在查询返回的结果中拥有了用户的功能,请改用它