我想更好地理解Wordpress
处理cron jobs
因此,我可以更好地了解如何创建一些自定义作业,这些作业可以基于单一事件发送电子邮件,例如lesson started
或lesson webinar started
.
In my case, I want to have emails sent to users when I have certain content that becomes available. 可用性基于一个日期字段,我将其作为自定义帖子类型的自定义元数据。
所以想象一下一系列的课程和课程。当课程打开时,我希望该事件触发向有权访问该课程的用户发送电子邮件。同样,当课程的网络研讨会开始时,我也想触发电子邮件。
现在,对于课程点播日期,我对save_post_membrepressrule
通过的挂钩$rule_id
并安排一个cron作业,在课程的drip发布日期发送电子邮件。我在钩子里这样做
// save meta for lesson if this rule is \'single_sfwd-lessons\' and has fixed drip
function my_save_post_membrepressrule_hook ($rule_id)
{
// bunch of checks first
if ( (isset($_POST[\'_mepr_rules_type\']) AND $_POST[\'_mepr_rules_type\'] == \'single_sfwd-lessons\')
AND ( isset($_POST[\'_mepr_rules_drip_enabled\']) AND $_POST[\'_mepr_rules_drip_enabled\'] == \'on\')
AND ( isset($_POST[\'_mepr_rules_drip_after_fixed\']) AND $_POST[\'_mepr_rules_drip_after_fixed\'] != \'\') )
{
// we have fixed drip date for a given lesson
$lesid = $_POST[\'_mepr_rules_content\'];
$course_id = (int) learndash_get_course_id($lesid);
// now set notification if rule is in future
$lesdate = $_POST[\'_mepr_rules_drip_after_fixed\'];
$lesdate = new DateTime($lesdate, new DateTimeZone(\'UTC\'));
$current_date = new DateTime();
$current_date->setTimeZone(new DateTimeZone( \'UTC\' ));
if ($lesdate > $current_date)
{
$notifs = get_notifications( \'lesson_started\', $course_id, $lesson_id);
if ( ! $notifs ) {
return;
}
// what memberships are tied to this drip rule?
global $wpdb;
$memberships = $wpdb->get_results("SELECT access_condition FROM wp_mepr_rule_access_conditions WHERE access_type = \'membership\' AND access_operator = \'is\' AND rule_id = \'$rule_id\'");
foreach ($memberships as $membership) {
$membership_id = $membership->access_condition
$wpdb->query("SET time_zone = \'UTC\'");
$activeusers = $wpdb->get_results("SELECT DISTINCT user_id FROM wp_mepr_transactions WHERE status IN(\'confirmed\',\'complete\') AND (expires_at >= NOW() OR expires_at = \'0000-00-00 00:00:00\') AND product_id = \'$membership_id\'");
// likely just one notification post for a given notification type, but use loop just in case
foreach ($notifs as $notif)
{
foreach ($activeusers as $activeuser)
{
if ((int) $activeuser->user_id != 0)
{
// delete what currently is set for these users for this lesson/membership combo
delete_user_meta($activeuser->user_id, \'ld_sent_notification_lesson_started\'.$notif->ID . \'_\' . $lesson_id . \'_\'. $membership_id);
}
}
// see if we already have cron job to send email for this lesson drip, so we can remove in case we changed the drip date
if ( wp_next_scheduled( \'my_custom_crons\', [ $notif->ID, \'lesson_started\', $membership_id, $course_id, $lesson_id ] ) )
{
wp_clear_scheduled_hook( \'my_custom_crons\', [ $notif->ID, \'lesson_started\', $membership_id, $course_id, $lesson_id ] );
}
wp_schedule_single_event( $lesdate->getTimeStamp(), \'my_custom_crons\', [ $notif->ID, \'lesson_started\', $membership_id, $course_id, $lesson_id ] );
} // end notif loop
} // end memberships loop
} // if date in future
} // if drip rule for lesson
}
因此,这在名为my_custom_crons
. 我对webinar_started
事件,以及webinat_starts_in_onehour
给定课程的事件。要对这个钩子做出反应,我必须
add_action( \'my_custom_crons\',\'my_custom_crons\', 99, 5 );
function my_custom_crons( $notif, $notification_type, $membership_id, $course_id, $lesson_id) {
global $wpdb;
$wpdb->query("SET time_zone = \'UTC\'");
$activeusers = $wpdb->get_results("SELECT DISTINCT user_id FROM wp_mepr_transactions WHERE status IN(\'confirmed\',\'complete\') AND (expires_at >= NOW() OR expires_at = \'0000-00-00 00:00:00\') AND product_id = \'$membership_id\'");
if ( empty( $activeusers ) ) {
return;
}
// ok, we have users that are active
foreach ( $activeusers as $activeuser ) {
$user_id = absint( $activeuser->user_id );
if ($user_id != 0) {
// bunch of checking
// get notification message for notification type (lessons tarted, or webinar started)
// then send the emails
}
}
// clear the job (but this not needed?)
wp_clear_scheduled_hook(\'my_custom_crons\', array(
$notif->ID,
$notification_type,
$course_id,
$membership_id,
$lesson_id,
));
}
就cron的设置而言,一切似乎都在起作用。如果我跑步wp cron event list
在为课程添加Membrepress滴水规则后,我看到my_custom_crons
计划的作业:my_custom_crons| 2021-11-03 20:01:00 |16 hours 1 minute| Non-repeating
But what happens if I have multiple lessons and multiple events I want to use for email triggers, all with various dates? As mentioned, I might have lesson_started
and lesson_webinar_started
event for various lessons. So will my current approach work, or will various events for various lessons all triggered at different times, all using my one cron hook\'s logic, interfere with one another?
谢谢