Est-il possible dans l'action save_post de déterminer s'il s'agit d'une nouvelle publication en cours de création ou d'une publication existante en cours de mise à jour?
Est-il possible dans l'action save_post de déterminer s'il s'agit d'une nouvelle publication en cours de création ou d'une publication existante en cours de mise à jour?
Réponses:
Depuis la version 3.7 de WordPress. - IIRC - le save_post
crochet - plus d'informations sur le crochet et son utilisation dans Code Reference:save_post
et Codex:save_post
- a un troisième paramètre $update
qui peut être utilisé pour déterminer exactement cela.
@param int $ post_ID ID de publication.
@param WP_Post $ post Objet Post.
@param bool $ update Qu'il s'agisse d'une publication existante en cours de mise à jour ou non.
Remarque:
$update
n'est pas toujours true
- vous pouvez le voir et le tester vous-même avec le code ci-dessous. Cependant, il n'est pas bien documenté, peut-être loin d'être nommé de manière optimale, et crée donc des attentes trompeuses. Le code ci-dessous peut être utilisé pour certains débogages, essayez de savoir quand intercepter l'exécution du code, sinon vous ne verrez pas les informations / messages. Je pense que le coupable d'un comportement trompeur est la gestion des révisions et des sauvegardes automatiques - qui pourraient être désactivées, mais je ne le recommande pas et je ne l'ai pas testé. Je ne sais pas si cela justifie un ticket Trac , donc je n'en ai pas ouvert un, si vous le pensez, veuillez suivre le lien et le faire vous-même. En dehors de cela, comme indiqué dans les commentaires, si vous avez un problème spécifique, posez une nouvelle question.
add_action( 'save_post', 'debug_save_post_update', 10, 3 );
function debug_save_post_update( $ID, $post, $update ) {
echo '<pre>';
print_r( $post ); echo '<br>';
echo '$update == ';
echo $update ? 'true' : 'false';
//conditions
if( ! $update && $post->post_status == "auto-draft" ) {
// applies to new post
echo ' && $post->post_status == "auto-draft"';
//die();
} else if ( ! $update ) {
// applies basically to the (auto saved) revision
//die();
} else {
// applies to updating a published post
// when there is a revision, which is normally the case,
// standard behavior of WordPress, then it is considered
// an update, which is where the confusion sets in
// there are other methods, like checking time or post status
// depending on your use case it might be more appropriate
// to use one of those alternatives
//die();
}
echo '</pre>';
//die();
}
$update
paramètre est TOUJOURS vrai même s'il s'agit d'un nouveau message. Ce paramètre est donc inutile. Je ne sais pas si cela a déjà fonctionné, mais c'est sûr que l'enfer ne fonctionne pas comme il est documenté dans la dernière version de wordpress 4.8.
wp_publish_post
, alors oui. Mais ce n'est pas vrai pour son utilisation dans wp_insert_post
. J'ai écrit une fonction de débogage, je l'ajoute à la réponse.
save_post
hook a un 3ème paramètre qui est toujours défini sur TRUE, donc vous ne savez pas ce que cela a à voir avec les autres hooks, sans parler des autres hooks. Je parle du crochet dans votre réponse. Ceci est une erreur.
wp_insert_post()
, wp_publish_post()
. Ce dernier n'est que de futurs postes, il $update
devrait y en avoir toujours true
. Sinon, en ce qui concerne wp_insert_post()
, $update
n'est pas toujours true
.
La façon dont j'effectue cette vérification (dans une fonction accrochée) consiste à comparer la date de publication et la date de modification (en GMT pour la normalisation)
function check_new_vs_update( $post_id ){
$myPost = get_post($post_id);
$post_created = new DateTime( $myPost->post_date_gmt );
$post_modified = new DateTime( $myPost->post_modified_gmt );
if( abs( $post_created->diff( $post_modified )->s ) <= 1 ){
// New post
}else{
// Updated post
}
}
add_action('save_post', 'check_new_vs_update' );
Cela fonctionne parce que même à la création, le post a une date «modifiée» qui lui est attachée, ce qui est exactement la même que la date «créée», mais nous autorisons un écart de 1 seconde dans les deux cas au cas où une seconde se déclenche pendant la création de la poste.
post_date_gmt
est 2019-03-12 01:31:30
et l' post_modified_gmt
est 2019-03-12 01:31:31
. :(
J'ai fini par vérifier l'existence d'une valeur personnalisée avant de la définir. De cette façon, s'il s'agit d'une publication nouvellement créée, la valeur personnalisée n'existerait pas encore.
function attributes_save_postdata($post_id) {
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
if (!wp_verify_nonce($_POST['_attributes_noncename'], plugin_basename(__FILE__))) return;
if ('page' == $_POST['post_type']) {
if (!current_user_can('edit_page', $post_id)) return;
} else {
if (!current_user_can('edit_post', $post_id)) return;
}
$termid = get_post_meta($post_id, '_termid', true);
if ($termid != '') {
// it's a new record
$termid = 'update';
} else {
// it's an existing record
}
update_post_meta($post_id, '_termid', $termid);
}
add_action('save_post', 'attributes_save_postdata');
Exemple de réponse à l'ialocine avec le paramètre "mise à jour":
function save_func($ID, $post,$update) {
if($update == false) {
// do something if its first time publish
} else {
// Do something if its update
}
}
add_action( 'save_post', 'save_func', 10, 3 );
if($update)
ou de garder le nouveau bloc en premier mais en utilisant if( ! $update )
. Ce dernier mettra l'OP en meilleure pratique et est préféré à votre méthode par les normes de codage WordPress dans des cas comme l' opérateur ternaire
Vous pouvez utiliser le crochet d'action pre_post_update pour le code de mise à jour et save_post pour le nouveau code postal. Cela fonctionne avant la mise à jour d'un article.
save_post
le crochet est déclenché à la fois lorsqu'un article est créé et mis à jour (après que WordPress l'a enregistré dans la base de données). pre_post_update
est renvoyé lorsqu'un article est mis à jour, mais avant sa mise à jour - cela peut être important.
Comme Darshan Thanki l'a laissé entendre (et Stephen Harris a précisé), vous pouvez utiliser pre_post_update
à votre avantage.
global $___new_post;
$___new_post = true;
add_action(
'pre_post_update',
function() {
global $___new_post;
$___new_post = false;
},
0
);
function is_new_post() {
global $___new_post;
return $___new_post;
}
La raison pour laquelle j'ai utilisé des globaux est parce que function is_new_post() use ( &$new_post )
n'est pas valide en PHP (choquant ...) donc tirer cette variable dans la portée de la fonction ne fonctionne pas - d'où le global.
Notez que cela ne peut vraiment être utilisé de manière fiable que pendant / après l' save_post
événement (ce qui est généralement suffisant, au moins pour ce que nous en faisons).
Lorsque save_post est déclenché, toutes les informations sur cette publication sont déjà disponibles, donc en théorie, vous pouvez utiliser
function f4553265_check_post() {
if (!get_posts($post_id)) {
// if this is a new post get_posts($post_id) should return null
} else {
// $post_id already exists on the database
}
}
add_action('save_post','f4553265_check_post');
ce n'est pas testé, cependant. =)
save_post
message lui-même, il aurait déjà été enregistré dans la base de données - il en get_posts
serait de même pour le message actuel.
Une autre approche qui utilise une fonction intégrée et aucun ajout à la base de données n'impliquerait get_post_status()
.
$post_status = get_post_status();
if ( $post_status != 'draft' ) {
//draft
} else {
//not a draft: can be published, pending, etc.
}
Notez cependant qu'il peut ne pas être approprié si vous envisagez de redéfinir ultérieurement le statut sur "brouillon" - vos instructions seront répétées la prochaine fois que vous mettrez à jour le message. Selon le contexte, vous souhaiterez peut-être prendre en compte les différentes chaînes qui peuvent être renvoyées par get_post_status()
pour créer un scénario plus approprié.
Voir Codex pour get_post_status () et Post Status
Les valeurs possibles sont:
- 'publier' - Une publication ou une page publiée
- 'en attente' - la publication est en attente de révision
- 'draft' - un poste en statut de brouillon
- 'auto-draft' - un article nouvellement créé, sans contenu
- 'future' - un article à publier dans le futur
- «privé» - non visible pour les utilisateurs non connectés
- «hériter» - une révision. voir get_children.
- 'corbeille' - le message est dans la corbeille. ajouté avec la version 2.9.
save_post()
est exécuté pour la première fois, mais pendant cette exécution, il get_post_status()
renvoie déjà «publier» et non «brouillon», même s'il n'est qu'en cours de publication.