Eu tenho WordPress Multisite com vários sites. Eu configurei DISABLE_WP_CRON
para true
no meu wp-config.php
.
Se configurarmos a tarefa Cron com wget ou curl, temos uma regra de 30 segundos para executar o script PHP. É tão pequeno enviar toneladas de notificações por e-mail e fazer outras coisas (talvez a conexão remota do servidor SMTP seja lenta, talvez seja um monte de notificações por e-mail do bbPress ou qualquer outra coisa).
Talvez possamos usar algo assim?
php -q wp-cron.php
Mas é só executar o cron em um site no Multisite (cada site tem suas próprias tarefas do cron em diferentes tabelas do MySQL).
P. S. No fórum wpmudev.org Eu encontrei "solução" estranha que também usa Curl.
Outro P. S. WP CLI tem awesome wp cron
comandos mas é só permitir executar tarefas cron manualmente (sim, podemos usar --url
attr). Por exemplo:
wp cron event list --url=multisite.com
wp cron event list --url=subdomain.multisite.com
Eu acho que a melhor maneira é usar o WP-CLI, mas você precisa escrever um script bash para fazer isso. Aqui está um que deve fazer isso por você:
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
Você precisaria adicionar esse script para crontab e executá-lo talvez a cada minuto, se quiser
Depois de adicionar a constante em wp-config.php
defined('DISABLE_WP_CRON') or define('DISABLE_WP_CRON', true);
E supondo que você tenha seu config.yml
setup corretamente, você pode omitir o flag --path
ao chamar cron run
.
wp cron event run --due-now
[<hook>…]
Um ou mais ganchos para rodar.
[--due-now]
Execute todos os ganchos devidos agora mesmo.
[--all]
Executa todos os ganchos.
Para executar todas as tarefas agendadas em ordem:
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;
Se você quiser que eles sejam executados simultaneamente (executando o cron não específico do site primeiro):
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;
Você gostaria de colocar qualquer opção em um arquivo executável
chmod +x run_all_wp_cron_events_due_now.sh
adicionar uma tarefa de crontab
crontab -e
e provavelmente executar cada minuto
* * * * * run_all_wp_cron_events_due_now.sh > /dev/null
Se você deseja executar um comando customizado do cron, você pode precisar especificar os caminhos completos para wp-cli para trabalhar.
* * * * * cd /home/username/public_html; /usr/local/bin/php /home/username/wp-cli.phar your-custom-cron-commands run >/dev/null 2>&1
A única razão pela qual você precisaria carregar o WordPress aqui é reunir as URLs do banco de dados em vez de usar uma lista predefinida. Nós só vamos pingar essas URLs e nós realmente não nos importamos com a resposta.
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 );
}
E adicione uma única chamada ao seu custom-cron.php
em um crontab
* * * * * wget -q -O - http://your-site.com/custom-cron.php?doing_wp_cron
Esta é minha solução:
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();
Nós chamamos isso de crontab, espero que ajude