web-dev-qa-db-fra.com

Fonctionnement WP Cron sur multisite dans le bon sens

J'ai WordPress Multisite avec plusieurs sites. J'ai configuré DISABLE_WP_CRON à true dans mon wp-config.php.

Si nous configurons la tâche cron avec wget ou curl, nous avons une règle de 30 secondes pour exécuter le script PHP. C’est si petit d’envoyer des tonnes de notifications par courrier électronique et d’autres tâches (peut-être que la connexion à un serveur SMTP distant est lente, peut-être que c’est vraiment une énorme quantité de notifications par courrier électronique de bbPress ou autre).

Peut-être que nous pouvons utiliser quelque chose comme ça?

php -q wp-cron.php

Mais il ne fait exécuter cron que sur un seul site multisite (chaque site a ses propres tâches cron dans différentes tables MySQL).

P. S. Sur le forum wpmudev.org J'ai trouvé une "solution" étrange qui utilise également Curl.

Une autre P. S. WP CLI a des commandes wp cron impressionnantes mais elle autorise uniquement les tâches cron exécutées manuellement (oui, nous pouvons utiliser --url attr). Par exemple:

wp cron event list --url=multisite.com
wp cron event list --url=subdomain.multisite.com
18

Je pense que le meilleur moyen est d'utiliser WP-CLI, mais vous auriez besoin d'écrire un script bash pour le faire. En voici un qui devrait le faire pour vous:

WP_PATH="/path/to/wp"
for SITE_URL in = $(wp site list --fields=domain,path,archived,deleted --format=csv --path="$WP_PATH" | grep ",0,0$" | awk -F ',' '{print $1 $2}')
do
    for EVENT_HOOK in $(wp cron event list --format=csv --fields=hook,next_run_relative --url="$SITE_URL" --path="$WP_PATH" | grep \"now\"$ | awk -F ',' '{print $1}')
    do
        wp cron event run "$EVENT_HOOK" --url="$SITE_URL" --path="$WP_PATH"
    done
done

Vous devez ensuite ajouter ce script à crontab et l'exécuter peut-être toutes les minutes si vous le souhaitez.

12

Après avoir ajouté la constante dans wp-config.php

defined('DISABLE_WP_CRON') or define('DISABLE_WP_CRON', true);

WP-CLI

Et en supposant que votre config.yml setup soit correctement configuré, vous pouvez omettre le drapeau --path lorsque vous appelez cron run .


wp cron event run --due-now

[<hook>…] Un ou plusieurs hooks à exécuter.

[--due-now] Exécuter tous les hooks dus maintenant.

[--all] Exécutez tous les crochets.


Pour exécuter toutes les tâches cron dues dans l'ordre:

function run_crons_due_now_in_order { for SITE_URL in $(wp site list --fields=url --format=csv | tail -n +2 | sort); do wp cron event run --due-now --url="$SITE_URL" && echo -e "\t+ Finished crons for $SITE_URL"; done; echo "Done"; }; run_crons_due_now_in_order;

Si vous souhaitez qu'ils s'exécutent simultanément (en exécutant d'abord le cron non spécifique au site):

function run_all_crons_due_now { for SITE_URL in $(wp site list --fields=url --format=csv | tail -n +2 | sort); do wp cron event run --due-now --url="$SITE_URL" && echo -e "\t+ Finished crons for $SITE_URL" & done; wait $(jobs -p); echo "Done"; }; run_all_crons_due_now;

Vous voudriez mettre l'une ou l'autre option dans un fichier exécutable

chmod +x run_all_wp_cron_events_due_now.sh

ajouter une tâche de crontab

crontab -e

et probablement exécuter chaque minute

* * * * * run_all_wp_cron_events_due_now.sh > /dev/null

Si vous voulez exécuter une commande custom from cron, vous devrez peut-être spécifier les chemins complets pour que wp-cli fonctionne.

* * * * * cd /home/username/public_html; /usr/local/bin/php /home/username/wp-cli.phar your-custom-cron-commands run >/dev/null 2>&1

PHP

La seule raison pour laquelle vous auriez besoin de charger WordPress ici est de rassembler les URL de la base de données plutôt que d'utiliser une liste prédéfinie. Nous allons seulement envoyer une requête ping à ces URL et nous ne nous soucions pas vraiment de la réponse.

custom-cron.php

<?php

// Load WP
require_once( dirname( __FILE__ ) . '/wp-load.php' );

// Check Version
global $wp_version;
$gt_4_6 = version_compare( $wp_version, '4.6.0', '>=' );

// Get Blogs
$args  = array( 'archived' => 0, 'deleted' => 0, 'public' => 1 );
$blogs = $gt_4_6 ? get_sites( $args ) : @wp_get_sites( $args ); // >= 4.6

// Run Cron on each blog
echo "Running Crons: " . PHP_EOL;
$agent = 'WordPress/' . $wp_version . '; ' . home_url();
$time  = time();

foreach ( $blogs as $blog ) {
    $domain  = $gt_4_6 ? $blog->domain : $blog['domain'];
    $path    = $gt_4_6 ? $blog->path : $blog['path'];
    $command = "http://" . $domain . ( $path ? $path : '/' ) . 'wp-cron.php?doing_wp_cron=' . $time . '&ver=' . $wp_version;

    $ch = curl_init( $command );
    $rc = curl_setopt( $ch, CURLOPT_RETURNTRANSFER, false );
    $rc = curl_exec( $ch );
    curl_close( $ch );

    print_r( $rc );
    print_r( "\t✔ " . $command . PHP_EOL );
}

Et ajoutez un seul appel à votre custom-cron.php dans une crontab

* * * * * wget -q -O - http://your-site.com/custom-cron.php?doing_wp_cron
11
jgraup

Ceci est ma solution:

global $multisite_hosts;
$multisite_hosts = Array('xxxx.dev.xxx.oondeo.es','x2.dev.xxx.oondeo.es','x3.dev.xxx.oondeo.es');

function run_cron(){
  global $multisite_hosts;
  $Host=array_pop($multisite_hosts);
  if (!$Host)
    return;
  register_shutdown_function('shutdown');
  if (!isset($_SERVER['HTTP_Host'])) {
       $_SERVER['HTTP_Host'] = $Host;  // replace with primary Host
  }

  require './wp-cron.php';
}

function shutdown()
{
  run_cron();
}
run_cron();

Nous appelons cela de crontab, espérons que cela aide

0
Amon-Ra