Exécuter WP Cron sur plusieurs sites de la bonne façon

18

J'ai WordPress Multisite avec plusieurs sites. Je mis en place DISABLE_WP_CRONà truemon 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 e-mail et de faire d'autres choses (peut-être que la connexion au serveur SMTP à distance est lente, c'est peut-être vraiment un tas énorme de notifications par e-mail de bbPress ou autre).

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

php -q wp-cron.php

Mais il n'est exécuté que sur un seul site Cron Multisite (chaque site a ses propres tâches cron dans différentes tables MySQL).

PS Sur le forum wpmudev.org, j'ai trouvé une étrange "solution" qui utilise également Curl.

Une autre CLIwp cron PS WP a des commandes impressionnantes mais elle permet uniquement d'exécuter les tâches cron manuellement (oui, nous pouvons utiliser --urlattr). Par exemple:

wp cron event list --url=multisite.com
wp cron event list --url=subdomain.multisite.com
Kolya Korobochkin
la source
Avez-vous jeté un œil au WP-CLIcode principal?
kaiser
Oui. Je fouille dans le code source en ce moment et j'essaie de comprendre :) La commande pour exécuter toutes les tâches (événements) n'existe pas, je peux peut-être la créer à l'avenir.
Kolya Korobochkin
Avez-vous wp/ WP-CLI dans votre PATH? Si oui, pourquoi ne pas déclencher cela à partir d'un fichier bash exécuté en cron?
kaiser
Super! Mais comment exécuter toutes les tâches cron à partir de wp cli? Je ne vois aucune commande pour cela.
Kolya Korobochkin
Exactement comme vous l'avez montré à la fin de votre question?
kaiser

Réponses:

13

Je pense que la meilleure façon est d'utiliser WP-CLI, mais vous devez écrire un script bash pour ce faire. En voici une 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 devrez ensuite ajouter ce script à crontab et l'exécuter peut-être toutes les minutes si vous le souhaitez

DiverseAndRemote.com
la source
Hm merci pour votre avis mais je pense que c'est une solution hacky (sale). Je pense qu'il vaudrait mieux écrire un addon PHP pour wpcli qui exécute simplement toutes les tâches nécessaires. J'ai besoin de plus de temps pour comprendre les fonctions et le code WP pour le faire.
Kolya Korobochkin
4
@KolyaKorobochkin Je ne suis pas d'accord. Ce n'est pas du tout hacky puisque WP CLI a été conçu pour être utilisé sur la ligne de commande et dans les scripts bash.
DiverseAndRemote.com
1
wp cron event run --due-now --url="$SITE_URL" --path="$WP_PATH- Selon les rundocuments, vous devez utiliser le --due-nowdrapeau. Cela réduirait les recherches et les appels d'événements individuels. Voir: wp-cli.org/commands/cron/event/run . Quoi qu'il en soit, je suis avec @OmarJackman - il utilise la ligne de commande pour utiliser les outils de ligne de commande WordPress. Props pour un exemple de Bash propre. Vous pouvez compléter cette réponse en affichant l'entrée crontab.
jgraup
Pour le bénéfice des futurs lecteurs, le script ressemble alors à: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 wp cron event run --due-now --url="$SITE_URL" --path="$WP_PATH"; done
perplexe
10

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 vous avez config.ymlcorrectement votre configuration, vous pouvez annuler le --pathdrapeau lors de l'appel cron run.


wp cron event run --due-now

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

[--due-now] Exécutez tous les crochets dus dès 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 souhaitez 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 crontab

crontab -e

et probablement exécuter chaque minute

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

Si vous souhaitez exécuter une commande personnalisée à partir de cron, vous devrez peut-être spécifier les chemins d'accès 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 cingler 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.phpdans une crontab

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

Une doublure plus facile avec moins de coups:

wp site list --field=url | xargs -i -n1 wp cron event run --due-now --url="{}"

Vous pouvez l'exécuter manuellement ou le mettre dans un script et l'appeler depuis cron comme dans les autres réponses.

Anastis
la source
0

Voici 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

Amon-Ra
la source
-5

Je pense que vous devez d'abord nous dire ce que vous entendez par «exécuter wp-cron.php de la bonne façon». Selon Wordpress, cela n'a aucun sens que vous désactiviez wp-cron et que vous souhaitiez néanmoins qu'il s'exécute ... Du point de vue Linux, wget-ing ou / bin / php-ing wp-cron.php serait correct, mais il semble que votre hôte particulier limite votre nombre d'appels php pour des raisons de sécurité? - cette partie n'est pas complètement claire à partir de votre description.

Une autre question: combien d'e-mails sont "une tonne"? Il y a de bonnes raisons pour lesquelles vous ne devriez pas essayer d'envoyer trop de courriels aussi rapidement.

Vous devrez peut-être repenser vos objectifs.

(Je commenterais au lieu de répondre mais je n'ai pas assez de réputation sur wpstack.)

Jorge Orpinel
la source
3
Il existe plusieurs façons d'exécuter le cron WordPress. Le mécanisme intégré est déclenché par les pages vues, et il est courant DISABLE_WP_CRONde désactiver cette méthode lors de la configuration de la méthode cron du système plus fiable.
Marcus Downing
La question n'est pas pourquoi le faire / si les raisons sont significatives mais comment appeler correctement wp-cron.php sur une installation multisite. Tout à fait clair pour moi;)
Philipp
1
J'espère que vous vous rendez compte que vous commentez une réponse très ancienne et déjà cachée.
Jorge Orpinel