【问题标题】:Cron event is not executed in custom Wordpress plugin自定义 Wordpress 插件中未执行 Cron 事件
【发布时间】:2017-01-27 06:13:57
【问题描述】:

我有一个网站,我需要每天从外部 url 导入数据,所以我制作了一个插件来处理这个问题。到目前为止一切顺利,但问题是我的 cron 事件不起作用。我安装了 Crontrol 插件来测试事件,但没有任何反应。我在列表中看到了我的钩子名称,但是当我单击“立即运行”时,我收到一条消息,指出 cron 事件已成功执行,但未导入数据。

我搜索了很多recoursesonline(例如),但不知何故,其他地方发布的所有解决方案似乎都不适合我。我一定是在某个地方漏掉了一步。

这个插件叫做 import-data 并且在 wp-content/plugins/import-data/ 我有 import-data.php:

<?php

     /**
      *   Plugin Name: Import data
      *   Plugin URI: 
      *   Description: Import data
      *   Version: 1.0.0
      *   Author: 
      *   Author URI: 
      *   License: GPL2
      */

     // Block direct acces to file
     defined('ABSPATH') or die();

     // Include functions
     require_once dirname( __FILE__ ).DIRECTORY_SEPARATOR.'functions.php';

     // Include class
     require_once dirname( __FILE__ ).DIRECTORY_SEPARATOR.'lib/class.import_data.php';

     /**
      *   @desc iterate through all posts and update information
      */
     function import_data(){
          $wp_query = new WP_Query(
               array(
                    'post_type' => 'post',
                    'post_status' => 'publish',
               )
          );

          if($wp_query->have_posts()){
               while($wp_query->have_posts()){
                    $wp_query->the_post();
                    $post_id = $wp_query->post->ID;
                    $external_id = get_field(trim(get_option('acfname_external_id')));

                    // Execute plugin
                    Import_Data::getInstance()->fetchDetails($external_id, $post_id);
               }
               wp_reset_postdata();
          }
     }

     /**
      *   Set cron
      */
     function my_event(){
          if(!wp_next_scheduled('import_data')){
               wp_schedule_event(time(), 'daily', 'import_data');
          }
     }

     add_action('wp', 'my_event');

     function unset_event(){
          wp_clear_scheduled_hook('import_data');
     }

     register_deactivation_hook(__FILE__, 'unset_event');

我知道fetchDetails() 方法有效,因为我在手动运行它之前和当我手动运行它时测试了输出(我已经向import_data() 添加了一个短代码并在演示页面上使用它)数据被导入,但是上面的 cron 设置没有。

functions.php 中只有管理页面设置。

这是我在 Wordpress 插件开发领域的第一步,因此我可以想象我错过了一个重要的钩子或过滤器(或其他任何东西),但我就是找不到它是什么。也许一些初始化?

【问题讨论】:

    标签: php wordpress cron


    【解决方案1】:

    首先你应该为你的全局 php 函数添加前缀以避免与其他插件、主题或核心冲突。

    我会使用激活钩子来安排事件,我会这样做:

    <?php
    
    /**
      *   Plugin Name: Import data
      *   Plugin URI: 
      *   Description: Import data
      *   Version: 1.0.0
      *   Author: 
      *   Author URI: 
      *   License: GPL2
      */
    
     // Block direct acces to file
     defined('ABSPATH') or die();
    
     // Include functions
     require_once dirname( __FILE__ ).DIRECTORY_SEPARATOR.'functions.php';
    
     // Include class
     require_once dirname( __FILE__ ).DIRECTORY_SEPARATOR.'lib/class.import_data.php';
    
    // Register activation / deactivation hooks
    register_deactivation_hook( __FILE__, 'ip_deactivation_func' );
    register_activation_hook( __FILE__, 'ip_activation_func' );
    
    // The plugin activation function
    function ip_activation_func(){
        // Do not forget to namespace your hooks also
        if( !wp_next_scheduled( 'ip_import_data' ) ){
           wp_schedule_event( time(), 'daily', 'ip_import_data' );
      }
    }
    
    // The plugin deactivation function
    function ip_deactivation_func(){
        wp_clear_scheduled_hook( 'ip_import_data' );
    }
    
    // Add the action event hook
    add_action( 'ip_import_data', 'ip_do_import_data' );
    
    // Your actual event code:
    function ip_do_import_data(){
        $wp_query = new WP_Query(
            array(
                'post_type' => 'post',
                'post_status' => 'publish'
            )
        );
    
        if( $wp_query->have_posts() ){
            while($wp_query->have_posts()){
                $wp_query->the_post();
    
                // Added this part, no need to use: $wp_query object here!
                global $post;
    
                $post_id = $post->ID;
                $external_id = get_field( trim( get_option( 'acfname_external_id' ) ) );
    
                // Execute plugin
                Import_Data::getInstance()->fetchDetails( $external_id, $post_id );
            }
            wp_reset_postdata();
        }
    }
    

    我不知道您的事件代码,您可能需要运行它以确保其正常工作。

    在此处了解有关 WP cron 的更多信息: https://developer.wordpress.org/plugins/cron/

    在此处了解有关激活/停用挂钩的更多信息: https://developer.wordpress.org/plugins/the-basics/activation-deactivation-hooks/

    还有一个很好的插件来调试 wp cron 事件: https://wordpress.org/plugins/wp-crontrol/

    【讨论】:

    • 不幸的是,结果和我一样:没有任何反应。我安装了你提到的插件(WP Crontrol),我看到那里发生了事件,但是当我点击立即运行几次时,什么都没有导入。当我将 add_shortcode('ip_test_output', 'ip_do_import_data'); 添加到 import-data.php 的底部,然后将 ['ip_test_output] 添加到测试页面时,当我进入测试页面时,数据会被导入。
    • 确保 WordPress 正在运行您的 cron 功能,然后您需要停用并重新激活您的插件以安排 cron 事件。您可以通过访问手动激活 wp cron 环境:yourdomain.com/wp-cron.php?doing_wp_cron - 如果安排了任何事件,它们将被激活。您需要开始调试代码以查看失败的原因。
    • 我尝试了上面的插件,虽然我删除了所有的require_once() 和事件代码,并添加了一个简单的wp_mail() 调用。在 WordPress 4.6.1 中,添加了该事件,并且我收到了我的测试电子邮件,确认它可以正常工作。确保预定的事件是:ip_import_data 而不是:import_data
    • 我没有停用/激活插件。现在可以了,谢谢!
    猜你喜欢
    • 1970-01-01
    • 2017-03-03
    • 1970-01-01
    • 2014-08-13
    • 1970-01-01
    • 2013-07-05
    • 1970-01-01
    • 1970-01-01
    • 2019-05-04
    相关资源
    最近更新 更多