根据POST_MODIFIED日期设置期间后将POST设置为草稿

时间:2013-11-29 作者:user36987

我有一个用户配置文件页面的自定义帖子类型。我的客户希望所有用户每月至少更新一次他们的个人资料,所以我们希望他们的个人资料(自定义帖子)在30天后自动设置为草稿。然后他们会收到一封电子邮件,要求他们更新帖子。该帖子需要设置为在上次修改日期后30天再次起草,并发出另一个提醒等。

到目前为止,我有这个代码在发布日期30天后过期,这似乎不起作用。我想我遗漏了一些关于cron调度的信息:

if ( ! wp_next_scheduled( \'run_post_expiration\' ) ) {
    wp_schedule_event( time(), \'hourly\', \'run_post_expiration\' );
}    
add_action( \'run_post_expiration\', \'expire_posts\' );

function expire_posts() {
    global $wpdb;
    $daystogo = "30";
    $sql = "UPDATE wp_posts 
        SET `post_status` = \'draft\' 
        WHERE `post_type` = \'profile\' 
        AND DATEDIFF(NOW(), `the_date`) > \'$daystogo\')";
    $wpdb->query($sql);
}
add_action(\'init\', \'expire_posts\');
我使用此代码将post\\u日期设置为post\\u修改日期,因此使上述代码每30天仍然有效:

function reset_post_date_wpse_121565($data,$postarr) {
    $data[\'post_date\'] = $data[\'post_modified\'];
    $data[\'post_date_gmt\'] = $data[\'post_modified_gmt\'];      
    global $post;
    if ($post->post_type == \'profile\'){
        return $data;
    } 
}
add_filter(\'wp_insert_post_data\',\'reset_post_date_wpse_121565\',99,2);
上面的修改post\\u日期的代码确实有效,但它也会导致其他post类型出现一些问题,这是我所没有预料到的,因此我认为可能在某个地方出现了错误。

有人能帮我把这件事做好吗?还是说我做得对?也许有更好的解决办法。我尝试过“Post Expirator”插件,但这只适用于Post\\u日期;一旦有人更新了他们的个人资料一次,它就不再起作用了。

EDIT:

我编辑了原始代码,将要起草的帖子设置为这样(基于我在其他地方找到的一些代码):

add_action( \'my_trash_hook\', \'my_trash_hook_function\' );
if (!wp_next_scheduled(\'my_trash_hook\')) {
    wp_schedule_event( time(), \'hourly\', \'my_trash_hook\' );
}

function my_trash_hook_function() {
    global $wpdb;
    $daystogo = "1";
    $sql = "UPDATE {$wpdb->posts}
        SET \'post_status\' = \'draft\'
        WHERE \'post_type\' = \'tests\'
        AND DATEDIFF(NOW(), \'the_date\') > \'$daystogo\')";
    $wpdb->query($sql);
}
我设置了另一个功能,可以在帖子设置为草稿时向我发送电子邮件,也可以在帖子再次发布时向我发送电子邮件。

现在发生的事情是,当我登录到该网站时,我收到一封电子邮件,说帖子已经发布,但没有一封邮件说帖子已设置为草稿。不确定这两段代码是相互冲突还是完全错误。

2 个回复
SO网友:s_ha_dum

不使用global $post. 您需要的所有内容都应传递到$data$postarr 参数。

其次,你必须return 这个$data 在所有情况下。您现在所做的是有效地擦除除profile 岗位类型。

您需要重新组织一下:

function reset_post_date_wpse_121565($data,$postarr) {
  if ($data[\'post_type\'] == \'profile\'){
    $data[\'post_date\'] = $data[\'post_modified\'];
    $data[\'post_date_gmt\'] = $data[\'post_modified_gmt\'];
  } 
  return $data;
}
add_filter(\'wp_insert_post_data\',\'reset_post_date_wpse_121565\',99,2);
我还没有彻底测试过,但这是正确的想法。

至于更好的方法。。。

你的expire_posts 函数的可移植性不可靠,因为它使用了硬编码的数据库前缀。至少,请重写该SQL,以便前缀不是硬编码的:

function expire_posts() {
  global $wpdb;
  $daystogo = "30";
  $sql = "UPDATE {$wpdb->posts} SET `post_status` = \'draft\' WHERE `post_type` = \'profile\' AND DATEDIFF(NOW(), `post_date`) > \'$daystogo\')";
  $wpdb->query($sql);
}
add_action(\'init\', \'expire_posts\');
我还注意到你的WHERE 子句的列不存在。There is no the_date column in the $wpdb->posts table. 应该是这样的post_date.

老实说,如果你只处理修改后的日期,你应该能够在根本不改变发布日期的情况下实现这一点。我认为您根本不需要第二块代码。

SO网友:Oliver Gehrmann

快速更正s\\u ha\\u dum的精彩帖子:在$sql语句末尾有一个不应该出现的右括号。这对我很有用:

function expire_posts() {
    global $wpdb;
    $daystogo = "12";
    $sql = "UPDATE {$wpdb->posts} SET `post_status` = \'draft\' WHERE `post_type` = \'post\' AND `post_status` = \'publish\' AND DATEDIFF(NOW(), `post_date`) > $daystogo";
    $wpdb->query($sql);
}
add_action(\'init\', \'expire_posts\');

结束

相关推荐

如何确保wp-cron作业运行

我正在使用一个插件向一个相对较大的电子邮件列表发送电子邮件。因为我们的主机每小时发送电子邮件的阈值很低,所以我们必须使用插件中的设置,将电子邮件限制在每小时只有一定数量。我假设插件使用wp cron来实现这一点。我曾尝试在wp-cron上查找文档,但我能找到的唯一重要信息是它需要一个页面视图才能运行。问题:RSS提要是否被ping到足以触发“页面视图”,从而触发wp cron</wp cron将在页面视图后运行多长时间?(例如,如果最后一次查看页面是在下午6:59,cron是否会安排在晚上7点运行?