根据过期时间或排队处理更新内容

时间:2021-08-31 作者:Dan

通过cron,我每小时调用一个函数来更新内容。如果在post上有带有auto的自定义字段,请执行此操作。(以区别于手动书写的内容)。

 function aggiorna_dati() {
            $args = array(
                \'post_type\' => \'post\',
                \'posts_per_page\' => -1 ,
                \'post_status\'    => \'private\'
            );
        
            $articoli = new WP_Query($args);
            if ($articoli->have_posts()):
                while($articoli->have_posts()): $articoli->the_post();    
        $auto = get_post_meta( get_the_ID(), \'auto\', true);
        if  ($auto) {
                    funzione_recensione($articoli);
            
        }
        
                endwhile;
            endif;
    
    }
cron使用以下代码回调函数:

function dg_cron_schedule_aggiorna_dati() {
    $timestamp = wp_next_scheduled( \'dg_aggiorna_dati\' );
    if ( $timestamp == false ) {
        wp_schedule_event( time(), \'hourly\', \'dg_aggiorna_dati\' );
    }
}
add_action( \'init\', \'dg_cron_schedule_aggiorna_dati\' );
问题是函数会同时更新所有文章,但这是不可能的,因为生成内容的函数(funzione\\u recensioni)与外部api一起工作,外部api的数量和调用/小时频率有限。因此,我需要缓慢地处理队列,例如,每小时四篇文章,或者在重新生成页面之前设置过期日期(例如每天一次)

感谢那些能帮助我的人

1 个回复
SO网友:Antti Koskinen

我脑子里几乎没有什么东西能帮上忙。

Post status

也许你可以使用pending post状态,您可以将其用作中的参数aggiorna_dati(), 对于需要处理的自动生成的帖子funzione_recensione(). 完成该功能后,它会将状态更改为其他状态。

$args[\'post_status\'] = \'pending\';

Posts per page

您可以设置posts_per_page 参数设置为API每小时可以处理的最大数量。但是,这需要您跟踪paged 参数(transient,custom option,hour of the day…),这样您就不必反复循环前n篇文章,也不必以这种或那种方式标记已处理的文章,以便下次运行查询时将其排除。

$api_hourly_max_capacity = 4;
$args[\'posts_per_page\'] = $api_hourly_max_capacity;

Date query

如果自动生成的帖子不需要每小时更新一次,那么可以使用date参数限制查询,例如只获取今天没有更新的帖子。为了让它发挥作用,funzione_recensione() 应在处理完成后更新已处理的帖子,以便更新其“修改日期”。

$args[\'date_query\'] = array(
    array(
        \'column\' => \'post_modified_gmt\',
        \'before\' => \'today\',
    ),
);

Meta query

作为补充说明,您可以使用元参数限制POST查询。这样你就不需要if 语句,因为查询的帖子已经匹配。如果使用pending 帖子状态不是一个选项,您可以考虑添加一个助手元值来跟踪需要处理的帖子,以进一步限制帖子查询。

$args[\'meta_query\'] = array(
    array(
        \'key\'     => \'auto\',
        \'value\'   => true, // or whatever the value is when is auto-generated
    ),
    // helper meta maybe?
    array(
        \'key\'     => \'process_state\',
        \'value\'   => \'pending\',
    ),
);
尽管使用自定义私有分类法来跟踪这类事情(是自动生成的,需要处理)在性能方面是一个更好的选择。

Regarding the loop

如果您对WP模板函数没有严格的需求,可以跳过设置循环have_posts()the_post() 因为您可以通过post对象属性直接访问post数据,并使用PHP本机函数循环找到的post。

$post_id = $post->ID;
array_walk( $articoli->posts, \'funzione_recensione\' );

P.s.

另一方面,您可以通过添加额外的限制来节省一点处理时间,并使查询执行得更好。

$args[\'no_found_rows\'] = true; // if pagination is not needed
$args[\'update_post_term_cache\'] = true; // if terms are not needed
$args[\'fields\'] = \'ids\'; // if only ids are needed
EDIT: 上述解释的简化代码示例。

// optional helper taxonomy
add_action(
    \'init\',
    function() {
        // minimal example
        register_taxonomy(\'my_private_tax\', \'post\', array(
            \'public\' => false,
        ));
    }
);

function some_function_to_auto_generate_posts() {   
    // generate the post
    $post_id = wp_insert_post(array(
        // title, content, etc. for the post..
        // ...
        // upon creation, set the status pending to signify the post is waiting for content
        \'post_status\' => \'pending\',
    ));
    // append private taxonomy term to the new post
    // you could 
    wp_set_object_terms( $post_id, \'is-autogenerated\', \'my_private_tax\', true );
    // OR if taxonomy is not used, set post meta
    // add_post_meta( $post_id, \'auto\', \'true\' );
}

function aggiorna_dati() {

    $api_hourly_max_capacity = 4; // or what ever the actual limit is

    // OPTION 1, if the posts are processed only once
    $posts_waiting_to_be_processed = \'pending\'; // if using this post status is an option
    $args = array(
    \'post_type\' => \'post\',
    \'posts_per_page\' => $api_hourly_max_capacity,
    \'post_status\'    => $posts_waiting_to_be_processed,
        \'no_found_rows\' => true, // pagination is not needed
    );

    // OPTION 2, if the posts are updated daily
    // $posts_waiting_to_be_processed = array(\'pending\', \'publish\');
    // $args = array(
    //  \'post_type\' => \'post\',
    //  \'posts_per_page\' => $api_hourly_max_capacity,
    //  \'post_status\'    => $posts_waiting_to_be_processed,
    //  \'no_found_rows\' => true, // pagination is not needed
    //  \'date_query\' => array(
    //      array(
    //       \'column\' => \'post_modified_gmt\',
    //       \'before\' => \'today\',
    //     ),
    //  ),
    // );

    // if the private taxonomy is used (better performance)
    $args[\'tax_query\'] = array(
        array(
            \'taxonomy\' => \'my_private_tax\',
      \'field\'    => \'slug\',
      \'terms\'    => \'is-autogenerated\',
        )
    );
    // OR do the meta query, if the custom taxonomy is not used
    // $args[\'meta_query\'] = array(
  //   array(
  //     \'key\'     => \'auto\',
  //     \'value\'   => \'true\',
  //   ),
    // );

    // query posts matching the $args
    $articoli = new WP_Query($args);

    // OPTION A, loop found posts
    array_walk( $articoli->posts, \'funzione_recensione\' );
    // this is the same as doing
    // foreach ($articoli->posts as $post) {
    //  funzione_recensione($post);
    // }
    // OPTION B, pass the query to the processing function
    // funzione_recensione($articoli);
}

// OPTION A, pass one post at a time to the processor function
function funzione_recensione( WP_Post $post ) {

    // fetch data from API, do some processing, etc.

    $post_status_after_processing = \'publish\';
    $processed_post_data = array(
        \'ID\' => $post,
        \'post_status\' => $post_status_after_processing,
        // other post fields that get updated...
    );
    
    wp_update_post($processed_post_data);
}

// OPTION B, pass the whole query to the processor
// function funzione_recensione( WP_Query $query ) {
//  // fetch data from API, do some processing, update posts, etc.
// }

相关推荐

从服务器手动运行cron

我有一个暂存服务器begind basic auth,我想运行系统cron而不是WordPress的cron。我已经把define(\'DISABLE_WP_CRON\', true); 在我的wp-config.php, 首先我添加了*/5 * * * * curl -u user:pass https://example.com/wp-cron.php?doing_wp_cron 但后来我想,为什么我不直接ping文件呢?*/5 * * * * php /home/mysite_staging