• Resolved dewd

    (@dewd)


    Hi

    I’m running WordPress in 2 environments. 1) on Windows for development, 2) on Linux for production (via a hosting provider).

    Note, I’ve tried WP-CLI with respect to the following but it chokes badly on Windows. I’ve not tried it on Linux.

    I’ve created a plugin which works perfectly fine in all environments. There iss one thing I need help with, however. The plugin requires an overnight process to run. I’ve fudged a way of making it work by running the process using a WP-JSON end point e.g. curl https://example.com/wp-json/plugin-namespace/batch-run-route

    This is poor practice for at least 2 reasons. 1) This is a REST endpoint and should return json. It doesn’t, it just echo’s progress on the batch process. 2) output is buffered before being output in 1 big output when the process completes – as you would expect output to flush for http.

    Am I missing something obvious? If anyone could give me any pointers I’d appreciate it.

    Many thanks

    The page I need help with: [log in to see the link]

Viewing 13 replies - 1 through 13 (of 13 total)
  • Moderator Jan Dembowski

    (@jdembowski)

    Forum Moderator and Brute Squad

    That sounds like WP-CLI territory. What are you processing that needs to run overnight? I mean, is there someway to break up the tasks into smaller chunks?

    Thread Starter dewd

    (@dewd)

    Yeah, I’ve looked at WP-CLI and it has very poor support for Windows. I couldn’t get it to function without countless errors.

    The process could be broken into smaller chunks, but it still feels like a fudge to use wp-json. The plugin runs to check for rows added to a plugin table during the previous 24 hours.

    Moderator bcworkz

    (@bcworkz)

    You could use wp_schedule_event(), but for development you’d need something to make requests to cause the events to fire. It shouldn’t be an issue on production. On Linux you could use a CRON job to execute something. I’ve no idea the equivalent for Windows, or if it’s possible at all. A virtual machine could work except for the performance issues.

    Thread Starter dewd

    (@dewd)

    @bcworkz

    Thanks for your suggestion. The main issue with using wp_schedule_event() is that it is only executed when someone visits the site:

    The action will trigger when someone visits your WordPress site if the scheduled time has passed.

    This wouldn’t work well because the browser would hang whilst the batch process executed. It would probaly timeout because the batch could take a while to execute.

    Ideally there would be a stable equivalent of WP-CLI which would allow specific functions within plugin classes to be executed in the same way that wp-json allows.

    I’m going to expand on @jdembowski suggestion. I’m going to build a wrapper which controls the number of items which need processing, and have the wp-json process only one item at a time. This should prevent hanging and also flush the buffer on an almost immediate basis. It will be easy to run as a batch process on either Windows or Linux. IT’s not ideal having to use wp-json out of context, but I cannot see any other way right now.

    Many thanks.

    Dion

    (@diondesigns)

    Is this task entirely database work, or are you also calling WordPress functions to manipulate the data?

    In either case, it seems to me that you could write a standalone PHP script that loads some or all of the WP core (if needed), then does the required work. Such a script could be set up to run as a CRON task in Linux, or as a scheduled task in Windows.

    Thread Starter dewd

    (@dewd)

    @diondesigns

    WordPress functions are used. As part of the batch process the following are used:

    Create instance of plugin class –

    __construct runs various add_action and add_filter items. I suppose I could remove these from __construct and only run them as part of plugin load e.g.:

    add_action( 'init',
        function(){
    
            $object =  new Plugin_Class();
    
            //curretly in __construct
            $object->initialise();
    
         },
    10);

    Doing the plugin load this way would theoretically mean I wouldn’t have to run $object->initialise() for the batch process.

    After object creation:
    global $wpdb used throughout
    $wpdb->prefix
    $wpdb->insert
    $wpdb->update
    $wpdb->get_row
    $wpdb->get_results
    $wpdb->query
    $wpdb->get_var

    other:
    get_bloginfo
    get_option
    get_pages()
    get_post()
    get_shortcode_regex()
    wp_mail

    What do you think?

    Dion

    (@diondesigns)

    I’ll assume you have WordPress at the web root, which in this example is the public_html directory when viewed from one level up. So…if you had the following two-line script that’s one level above the WP root directory (making it unavailable to web-based hackers):

    define('MY_FANCY_CRON_TASK', true);
    require('public_html/wp_load.php');

    it would load the WP core but not “start” the WordPress frontend. Your plugin could check for the constant and execute your custom code if it’s defined. The script could be executed via PHP-CLI and added as a task.

    I have no idea whether this would work, but given how easy it is to test, it’s worth trying. Just keep in mind that all $_SERVER variables will be missing since the script is running via PHP-CLI.

    Thread Starter dewd

    (@dewd)

    Marvelous stuff @diondesigns . Yes, I wouldn’t put the batch file in the website path. Do you know if there a way of loading the core without loading plugins?

    Dion

    (@diondesigns)

    You can block WordPress fron loading its theme and non-MU plugins by adding the following constant to the two-line script above:

    define('WP_INSTALLING', true);
    define('MY_FANCY_CRON_TASK', true);
    require('public_html/wp-load.php');

    Cache and database drop-ins, and must-use plugins, will still be loaded. I believe they can also be blocked from loading if they are an issue for you.

    Thread Starter dewd

    (@dewd)

    @diondesigns perfect. ????

    Just an FYI for anyone reading this. If you need to use wp_mail, unfortunately it creates a Notice for global $_SERVER['SERVER_NAME'] being undefined. I manually set this to an empty string, in my set up file and it works fine.

    Thread Starter dewd

    (@dewd)

    @diondesigns I posted my question on Stackoverflow before here: https://stackoverflow.com/questions/55166411/command-line-run-and-flush-output-from-wordpress-plugin-function. If you would like to answer it, I’ll give you a +1 and a ?

    Dion

    (@diondesigns)

    I’m glad you were able to get this sorted out! Tell you what…how about marking this topic as resolved, and then replying to your own question on stackoverflow with a link to this topic.

    Thread Starter dewd

    (@dewd)

    Done! ????

Viewing 13 replies - 1 through 13 (of 13 total)
  • The topic ‘My plugin needs to run an overnight process’ is closed to new replies.