Je souhaite utiliser wp_schedule_single_event( )
pour exécuter un événement unique qui m'envoie un courrier électronique 8 minutes après que l'utilisateur a envoyé un formulaire.
Le code suivant est dans mon functions.php
:
function nkapi_send_to_system( $args ) {
wp_mail( 'xxx', 'xxx', $args );
}
add_action( 'nkapi_send', 'nkapi_send_to_system' );
function schedule_event( $id ) {
wp_schedule_single_event( current_time( 'timestamp' ) + 480, 'nkapi_send', array( $id ) );
}
Et le code suivant est utilisé pour appeler schedule-event
:
schedule_event( $_SESSION['insert_id'] ); // the $_SESSION var contains an INT
Après avoir attendu plus de 8 minutes, il n'y avait pas d'e-mail dans ma boîte de réception.
Avec le plugin Core Control , il est possible de voir quelles tâches cron sont planifiées.
Après quelques modifications, j'ai réussi à les corriger, et mieux encore, lorsque je clique sur "Run Now", je reçois un message électronique dans ma boîte de réception.
Mais pourquoi le cron ne s'exécute pas lorsque je visite mon site après 8 minutes. Quel est le problème avec ce code? Je dois dire que c'est la première fois que j'utilise WP Cron.
J'ai essayé plus
Après le commentaire de vancoder id a décidé de vérifier si le code fonctionne si je mets le code suivant directement dans le functions.php
:
function schedule_event( $id ) {
wp_schedule_single_event( time(), 'nkapi_send', array( $id ) );
}
if ( isset( $_SESSION['insert_id'] ) ) {
if ( ! array_key_exists( 'insert_scheduled', $_SESSION ) || $_SESSION['insert_scheduled'] != $_SESSION['insert_id'] ) {
schedule_event( $_SESSION['insert_id'] );
$_SESSION['insert_scheduled'] = $_SESSION['insert_id'];
}
}
L'inconvénient de ce code est que l'utilisateur doit accéder à une autre page avant que ce code ne soit exécuté. Mais de l’autre côté, cela ne marche pas non plus, alors ce ne serait pas mon premier problème….
D'abord, pouvez-vous s'il vous plaît confirmer que vous n'avez aucun plugin de cache activé? Les plugins de mise en cache peuvent interférer avec les tâches cron car vos visiteurs ne reçoivent pas une page en direct mais une version mise en cache de votre page.
Si un plug-in de mise en cache est activé, vous pouvez choisir l'une de vos pages, ajouter une exclussion aux paramètres de votre plug-in de mise en cache pour cette page afin qu'elle ne soit jamais mise en cache.
Ensuite, vous devrez créer manuellement une tâche cron (en utilisant cpanel si vous êtes sur un environnement d'hébergement partagé ou à partir du terminal s'il s'agit d'un serveur VPS/dédié) qui visitera cette page toutes les quelques minutes.
J'espère que ça aide!
Tout d’abord, définissez vos plannings de tâches cron personnalisés.
add_filter('cron_schedules', array($this, 'cron_schedules'));
public function cron_schedules($schedules){
$prefix = 'cron_';// Avoid conflict with other crons. Example Reference: cron_30_mins
$schedule_options = array(
'30_mins' => array(
'display' => '30 Minutes',
'interval' => '1800'
),
'1_hours' => array(
'display' => 'Hour',
'interval' => '3600'
),
'2_hours' => array(
'display' => '2 Hours',
'interval' => '7200'
)
);
/* Add each custom schedule into the cron job system. */
foreach($schedule_options as $schedule_key => $schedule){
$schedules[$prefix.$schedule_key] = array(
'interval' => $schedule['interval'],
'display' => __('Every '.$schedule['display'])
);
}
return $schedules;
}
Vous devez décider où et quand programmer réellement l'événement.
Voici juste un exemple de code qui appelle la méthode de classe personnalisée:
$schedule = $this->schedule_task(array(
'timestamp' => current_time('timestamp'), // Determine when to schedule the task.
'recurrence' => 'cron_30_mins',// Pick one of the schedules set earlier.
'hook' => 'custom_imap_import'// Set the name of your cron task.
));
Voici le code qui planifie réellement l'événement:
private function schedule_task($task){
/* Must have task information. */
if(!$task){
return false;
}
/* Set list of required task keys. */
$required_keys = array(
'timestamp',
'recurrence',
'hook'
);
/* Verify the necessary task information exists. */
$missing_keys = array();
foreach($required_keys as $key){
if(!array_key_exists($key, $task)){
$missing_keys[] = $key;
}
}
/* Check for missing keys. */
if(!empty($missing_keys)){
return false;
}
/* Task must not already be scheduled. */
if(wp_next_scheduled($task['hook'])){
wp_clear_scheduled_hook($task['hook']);
}
/* Schedule the task to run. */
wp_schedule_event($task['timestamp'], $task['recurrence'], $task['hook']);
return true;
}
Il ne vous reste plus qu'à appeler le nom de votre tâche périodique personnalisée. Dans cet exemple, le nom de la tâche périodique est custom_imap_import
.
add_action('custom_imap_import', array($this, 'do_imap_import'));
public function do_imap_import(){
// .... Do stuff when cron is fired ....
}
Ainsi, dans cet exemple, $this->do_imap_import();
est appelée toutes les 30 minutes (en supposant que le trafic sur votre site Web soit suffisant).
Nécessite une visite de la page pour que votre cron puisse se déclencher aux heures appropriées.
Exemple: Si vous planifiez une tâche à 30 minutes d'intervalle, mais que personne ne visite votre site pendant 4 heures, votre tâche cron ne sera déclenchée que lorsque ce visiteur viendra sur votre site 4 heures plus tard. Si vous avez vraiment besoin que votre tâche soit renvoyée toutes les 30 minutes, il est conseillé de configurer une tâche cron légitime via votre fournisseur d’hébergement Web pour visiter votre site Web aux intervalles souhaités.
Les travaux cron de WordPress ne ralentissent pas votre site Web!
Vous pensez peut-être que si l'exécution du script cron prend beaucoup de temps, les visiteurs devront-ils attendre que le script soit exécuté. Nan! Comment cela peut-il être possible? Si vous regardez le fichier wp-cron.php
, vous trouverez une ligne
ignore_user_abort(true);
C'est une configuration php.ini
qui définit que si vous arrêtez de charger le site/script, le script ne s'arrêtera pas de s'exécuter.
Si vous regardez le fichier wp-includes/cron.php
, vous trouverez une ligne comme celle-ci:
wp_remote_post( $cron_url,
array('timeout' => 0.01,
'blocking' => false,
'sslverify' => apply_filters('https_local_ssl_verify', true)) );
Cela signifie que WordPress attendra seulement 0.01 seconde pour déclencher l'exécution, puis il abandonnera, mais comme vous avez défini ignore_user_abort
sur true
, le script sera exécuté. Cette fonctionnalité est un avantage énorme pour l'exécution de scripts volumineux dans les tâches cron de WordPress.
Fonctions disponibles pour l'aide:
WordPress Cron vous permet de planifier des tâches, mais celles-ci ne seront exécutées que si une demande est faite au site. Pour chaque demande reçue par WordPress, il vérifiera s'il existe des tâches cron à traiter et, le cas échéant, déclenche une demande de /wp-cron.php?doing_wp_cron
de manière asynchrone pour traiter la tâche. Si le démarrage planifié d'un travail se passe sans demande, le processus cron ne sera pas démarré.
Comme vous pouvez voir et exécuter vos travaux planifiés, il est possible qu'aucune demande ne déclenche le démarrage du travail cron, en particulier si vous utilisez un plug-in de mise en cache. La meilleure option pour décharger cela dans un calendrier plus régulier consiste à désactiver la vérification par défaut dans WordPress et à utiliser crontab
.
Tout d’abord pour désactiver la vérification par défaut (ce qui peut aider un peu aux performances côté client), ajoutez ce qui suit à wp-config.php
:
// Disable default check for WordPress cron jobs on page loads
define( 'DISABLE_WP_CRON', true );
Ensuite, vous créez une tâche pour extraire la page wp-cron.php
une fois par minute afin de traiter les tâches dorsales. À partir de la ligne de commande, entrez crontab -e
, puis ajoutez une ligne semblable à celle-ci:
*/1 * * * * /usr/bin/curl --silent http://example.com/wp-cron.php?doing_wp_cron=$(date +\%s.\%N) >/dev/null
Vérifiez tout plugin qui cache Wordpress.
Comment voir si c'est le problème?
+1 Ne croyez pas les plugins qui "vérifient si cron fonctionne" - par exemple. WP Le plug-in de vérification d'état de Cron a montré que Cron fonctionne. Mais en fait, ce n’est pas le cas.
Conclusion: s’il s’agit d’une erreur 404, désactivez a) non seulement la mise en cache des plugins, comme le suggèrent b), mais aussi les plugins masquant Wordpress.
Vérifiez que DISABLE_WP_CRON n'est pas défini dans votre configuration.
En cas d'échec, essayez de désactiver tous les plug-in (à l'exception du contrôle de base - bien que j'utilise wp-crontrol) et voyez si vos travaux de base fonctionnent. S'ils le font, vous rencontrez des interférences de plug-ins quelque part.
De même, essayez de passer à un thème standard de la vingtaine d'années.
Si rien de tout cela ne fait la différence, il y a de fortes chances que ce soit un problème d'hébergement.