Vérifier la mise à jour par rapport au nouveau message sur l'action save_post
-
-
Jene pensepas que ce soitpossible.Voirmon commentaire ci-dessous la réponse de @moralida.Pourquoi avez-vousbesoin de savoir s'il s'agit d'unnouveaumessage ou d'unemise àjour?Ilpeut y avoir une solution de contournement ou une approche alternative.I don't think this is possible. See my comment below @moraleida's answer. Why do you need to know if it's a new post or being updated? There may be a work-around or an alternative approach.
- 0
- 2012-04-12
- Stephen Harris
-
9 réponses
- votes
-
- 2015-04-30
Depuis la version 3.7 de WordPress. - IIRC - le hook
save_post
-plus d'informations sur le hooket son utilisation sur Référence de code:save_post
et Codex:save_post
- a untroisièmeparamètre$ update
quipeut être utilisépour déterminerexactement cela.@param int $post_ID Identifiant dumessage.
@param WP_Post $publier Objet dumessage.
@param booléen $mettre àjour S'il s'agit d'unmessageexistanten cours demise àjour ounon.
Remarque :
$ update
n'estpastoujourstrue
- vouspouvez le voiret letester vous-même avec le code ci-dessous. Iln'est cependantpasbien documenté,peut-être loin d'êtrenommé demanière optimale,et crée donc des attentestrompeuses. Le code ci-dessouspeut être utilisépour certains débogages,jouez avec quandintercepter l'exécution du code,sinon vousne verrezpas lesinformations/messages. Jepense que le coupable d'un comportementtrompeurest lagestion des révisionset des sauvegardes automatiques - quipourraient être désactivées,maisje ne le recommandepaset jene l'aipastesté. Jene saispas si celajustifie un ticket Trac ,doncje n'en aipas ouvert,si vouspensez que oui,veuillez suivre le lienet faites-le vous-même. En dehors de cela,commeindiqué dans les commentaires,si vous avez unproblème spécifique,postez unenouvelle question.add_action ('save_post','debug_save_post_update',10,3); function debug_save_post_update ($ ID,$post,$ update) { echo '& lt;pre >'; print_r ($post);echo '& lt;br >'; echo '$ update=='; echo $ update? 'vraifaux'; //conditions if (! $ update & amp; & amp; $post- >post_status=="auto-draft") { //s'applique à unnouveaumessage echo '& amp; & amp; $post- >post_status=="brouillon automatique" '; //mourir(); }elseif (! $ update) { //s'appliqueessentiellement à la révision (enregistrée automatiquement) //mourir(); } autre { //s'applique à lamise àjour d'un articlepublié //lorsqu'il y a une révision,ce quiestnormalement le cas, //comportement standard de WordPress,alorsilest considéré //unemise àjour,là où la confusion s'installe //ilexiste d'autresméthodes,comme vérifier l'heure ou l'état de lapublication //selon votre cas d'utilisation,celapourrait êtreplus approprié //pour utiliser l'une de ces alternatives //mourir(); } echo '& lt;/pre >'; //mourir(); }
Since WordPress version 3.7. - IIRC - the
save_post
hook - more information about the hook and its usage at Code Reference:save_post
and Codex:save_post
- has a third parameter$update
which can be used to determine just that.@param int $post_ID Post ID.
@param WP_Post $post Post object.
@param bool $update Whether this is an existing post being updated or not.
Note:
$update
is not alwaystrue
– you can see and test it yourself with below code. It is not well documented though, possibly far from optimally named, and hence creates misleading expectations. Below code can be used for some debugging, play around with when to intercept code execution, because otherwise you won't see the information/messages. I think, the culprit in deceptive behavior is the handling of revisions and auto saves – which could be disabled, but I don't recommend it, and haven't tested it. Not sure if this warrants a Trac Ticket, so I didn't open one, if you think so, please follow the link and do it yourself. Aside from that, as stated in the comments, if you have a specific problem, post a new 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(); }
-
Leparamètre `$ update`est TOUJOURS vraimême s'il s'agit d'unnouveaumessage.Donc,ceparamètreestinutile.Jene saispas si cela ajamaisfonctionné,mais celane fonctionne certainementpas commeilest documenté dans la dernière version de wordpress 4.8.The `$update` parameter is ALWAYS true even when it is a new post. So this parameter is useless. Not sure if it ever worked at all, but it sure as hell isn't working the way it's documented in the latest version of wordpress 4.8.
- 3
- 2017-07-20
- Solomon Closson
-
@SolomonClosson Si vous regardez `wp_publish_post`,alors oui.Mais cen'estpas vraipour son utilisation dans `wp_insert_post`.J'ai écrit unefonction de débogage,je l'ajoute à la réponse.@SolomonClosson If you take a look at `wp_publish_post`, then yes. But that isn't true for its usage in `wp_insert_post`. I've written a debug function, I add it to the answer.
- 0
- 2017-07-21
- Nicolai
-
@SolomonClosson Si vous avez unproblème concret,posez unenouvelle question.Jetez un oeil aux révisionspour lafonction de débogage uneexplication.@SolomonClosson If you have a actual concrete problem, please ask a new question. Take a look at the revisions for the debug function an explanation.
- 0
- 2017-07-21
- Nicolai
-
Le hook `save_post` a un 3èmeparamètre quiesttoujours défini sur TRUE,doncpas sûr de ce que cela a à voir avec d'autres hooks,sansparler des autres hooks.Jeparle du crochet dans votre réponse.Ceciest uneerreur.The `save_post` hook has a 3rd parameter that is always set to TRUE, so not sure what this has to do with other hooks, not speaking about other hooks. I'm talking about the hook in your answer. This is incorrect.
- 0
- 2017-07-23
- Solomon Closson
-
@SolomonClosson Commeje l'ai dit,le crochet seproduit deuxfois: [`wp_insert_post ()`] (https://core.trac.wordpress.org/browser/tags/4.8/src/wp-includes/post.php#L3510),[`wp_publish_post ()`] (https://core.trac.wordpress.org/browser/tags/4.8/src/wp-includes/post.php#L3619).Ce derniern'est que des articlesfuturs,là `$ update`est définipour êtretoujours`true`.Sinon,en ce qui concerne `wp_insert_post ()`,`$ update`n'estpastoujours`true`.@SolomonClosson As I said the hook is occurring two times: [`wp_insert_post()`](https://core.trac.wordpress.org/browser/tags/4.8/src/wp-includes/post.php#L3510), [`wp_publish_post()`](https://core.trac.wordpress.org/browser/tags/4.8/src/wp-includes/post.php#L3619). The latter is only future posts, there `$update` is set to be always `true`. Otherwise, in regards to `wp_insert_post()`, `$update` is not always `true`.
- 0
- 2017-07-24
- Nicolai
-
Je suisen retard à lafête,maisbon,pourquoipas,@Nicolai,ce que vous ditesest ce à quoi onpourrait s'attendre,maisje nepeuxpas obtenir que $ update soitfauxmême lorsqueje m'accroche à 'wp_insert_post'.Peuimporte oùje l'accroche,c'esttoujours vrai.Jene comprendspaspourquoi cen'estpas corrigé.I'm late to the party, but hey, why not, @Nicolai, what you are saying is what one would expect to happen, but I can't get $update to be false even when I hook to 'wp_insert_post'. No matter where I hook it, it' always true. I don't understand why this isn't fixed.
- 0
- 2019-02-02
- ColdTuna
-
Lesgars,juste uneinfo.Le crochetest déclenché lors de la restaurationet de la suppression d'unmessage.Guys, just an info. The hook is fired on restoring and deleting a post.
- 0
- 2019-05-09
- melvin
-
- 2015-02-10
Lafaçon dontj'effectue cette vérification (dans unefonction accrochée)est de comparer la date depublicationet la date demodification (en GMTpour lanormalisation)
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 ); $diff = $created->diff( $modified ); $seconds_difference = ((($diff->y * 365.25 + $diff->m * 30 + $diff->d) * 24 + $diff->h) * 60 + $diff->i)*60 + $diff->s; if( $seconds_difference <= 1 ){ // New post }else{ // Updated post } } add_action('save_post', 'check_new_vs_update' );
Celafonctionneparce quemême à la création,lapublication a une date 'modifiée' qui luiest attachée,quiestexactement lamême que la date 'créée',maisnous autorisons une variation de 1 seconde dans les deux cas au cas où une seconde cochependantla création dumessage.
The way I perform this check (within a hooked function) is to compare the post date and modified date (in GMT for standardisation)
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 ); $diff = $created->diff( $modified ); $seconds_difference = ((($diff->y * 365.25 + $diff->m * 30 + $diff->d) * 24 + $diff->h) * 60 + $diff->i)*60 + $diff->s; if( $seconds_difference <= 1 ){ // New post }else{ // Updated post } } add_action('save_post', 'check_new_vs_update' );
This works because even at creation the post has a 'modified' date attached to it, which is exactly the same as the 'created' date, but we allow a variance of 1 second either way in case a second ticks over during the creation of the post.
-
Parfois,le `post_date_gmt`est` 2019-03-12 01: 31: 30`et le `post_modified_gmt`est` 2019-03-12 01: 31: 31`.:(Sometimes the `post_date_gmt` is `2019-03-12 01:31:30` and the `post_modified_gmt` is `2019-03-12 01:31:31`. :(
- 1
- 2019-03-12
- He Yifei 何一非
-
@HeYifei 何 一 非bonpoint,si letraitement commence à lafin d'une seconde donnée,celapeut arriver.J'aimis àjourma réponse,merci@HeYifei何一非 good point, if the processing begins at the end of a given second, this could happen. I've updated my answer, thanks
- 1
- 2019-03-12
- James Cushing
-
Lesgars,juste uneinfo.Le crochetest déclenché lors de la restaurationet de la suppression d'unmessage.Guys, just an info. The hook is fired on restoring and deleting a post.
- 1
- 2019-05-09
- melvin
-
Bon à savoir @melvin,merciGood to know @melvin, thanks
- 0
- 2020-08-17
- James Cushing
-
- 2012-04-17
J'aifini par vérifier simplement l'existence d'une valeurpersonnalisée avant de la définir.De cettefaçon,s'il s'agit d'un articlenouvellement créé,la valeurpersonnaliséen'existeraitpasencore.
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');
I ended up just checking for the existence of a custom value prior to setting it. That way, if it's a newly created post the custom value would not yet exist.
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');
-
Pour que celafonctionne,devez-vous d'abord créer le champpersonnaliséen utilisant add_post_meta?For this to work, do you have to first create the custom field using add_post_meta?
- 0
- 2013-04-09
- MF1
-
Selon le Codex: [update_post_meta]peut être utilisé à laplace de lafonction add_post_meta (). http://codex.wordpress.org/Function_Reference/update_post_metaPer the Codex: [update_post_meta] may be used in place of add_post_meta() function. http://codex.wordpress.org/Function_Reference/update_post_meta
- 0
- 2014-01-20
- hereswhatidid
-
Celapeut échouer si lespublications ont été créées avant l'activation du code hook via une activation duplugin.Les articlesplus anciensn'ontpas leméta-ensemble,par conséquent,lapremièremise àjourpoureux sera considérée commenouvelle.This might fail, if posts were created before the code hook gets enabled via a plugin activation. Older posts dont have the meta set, hence the first update for them will be considered as new.
- 0
- 2018-05-05
- Vasu Chawla
-
@VasuChawla donc dans ce cas,ilestpeut-êtreplusfiable de vérifier l'existence `isset ()` (parexemple) de ceméta-terme spécifiqueplutôt que de savoir s'ilest vrai oufaux.Commetroisième condition.(`if`,`elseif`,... `else`)@VasuChawla so in that case maybe its more reliable to check the existence `isset()` (for example) of that specific meta term instead of whether its true or false. As a third condition. (`if`, `elseif`, ...`else`)
- 0
- 2020-08-01
- Viktor Borítás
-
- 2015-12-01
Exemple de réponseialocin avec leparamètre "update":
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 );
Example to ialocin answer with "update" paremeter:
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 );
-
Unemeilleurefaçon de structurer cela serait soit demettre lebloc demise àjouren premier,permettant simplement defaire `if ($ update)` ou degarder lenouveaublocen premiermaisen utilisant `if (! $ Update)`.Ce dernier obtiendra unemeilleurepratique OPet estpréféré à votreméthodepar lesnormes de codage WordPress dans des cas comme [l'opérateurternaire] (https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/# opérateurternaire)A better way to structure this would be either putting the update block first, allowing to just do `if($update)` or keeping the new block first but using `if( ! $update )`. The latter will get OP into better practice and is preferred over your method by WordPress coding standards in cases like the [ternary operator](https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/#ternary-operator)
- 2
- 2016-11-17
- James Cushing
-
- 2012-08-06
Vouspouvez utiliser le hook d'actionpre_post_updatepour le code demise àjouret save_postpour lenouveau codepostal.Celafonctionne avant lamise àjour d'un article.
You can use pre_post_update action hook for the update code and save_post for the new post code. It works before a post is updated.
-
Le hook `save_post`est déclenché ** les deux ** lorsqu'un articleest crééet mis àjour (après que WordPress l'aenregistré dans labase de données).`pre_post_update`est déclenché lorsqu'unmessageestmis àjour,mais * avant * lemessageen cours demise àjour - celapeut êtreimportant.`save_post` hook is fired **both** when a post is created and updated (after WordPress has saved it to the database). `pre_post_update` is fired when a post is updated, but *prior* to the post being updated - this can be important.
- 4
- 2012-08-12
- Stephen Harris
-
- 2015-01-06
Comme l'a laisséentendre Darshan Thanki (et Stephen Harris aexpliquéplusen détail),vouspouvez 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 raisonpour laquellej'ai utilisé desglobalsestparce que
function is_new_post() use ( &$new_post )
n'estpas valideen PHP (choquant ...) donctirer cette variable dans laportée de lafonctionnene fonctionnepas - d'où leglobal.Notez que celane peut vraiment être utilisé demanièrefiable que dans/après l'événement
save_post
(ce quiestgénéralement suffisant,dumoinspour ce quenousen faisons).As Darshan Thanki hinted (and Stephen Harris further elaborated), you can use
pre_post_update
to your advantage.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; }
The reason why I used globals is because
function is_new_post() use ( &$new_post )
is not valid in PHP (shocking...) so pulling in that variable into the function scope doesn't work -- hence the global.Note that this can really only reliably be used within/after the
save_post
event (which is usually sufficient, at least for what we're doing with it). -
- 2012-04-12
Lorsque save_postest déclenché,toutes lesinformations sur cemessage sont déjà disponibles,doncen théorie,vouspouvez 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');
celan'apas ététesté,cependant.=)
When save_post is triggered, all information about that post is already available, so in theory you could use
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');
this is untested, though. =)
-
Aumoment où vous arrivez à `save_post`,lapublicationelle-même aurait déjà étéenregistrée dans labase de données - donc`get_posts` renverrait lapublication actuelle.By the time you get to `save_post` the post itself would have already been saved to database - so `get_posts` would return the current post.
- 3
- 2012-04-12
- Stephen Harris
-
C'est vrai,je viens de le vérifier dans le Codex.Mercipour l'information.True, just checked it in the Codex. Thanks for the heads-up.
- 0
- 2012-04-12
- moraleida
-
Celane fonctionnepas avec `get_posts`mais celafonctionne avec`get_post`.This does not work with `get_posts` but it works with `get_post`.
- 0
- 2020-08-18
- Gavin
-
- 2014-12-12
Une autre approche qui utilise unefonctionintégréeet aucun ajout à labase de donnéesimpliquerait
get_post_status()
.$post_status = get_post_status(); if ( $post_status != 'draft' ) { //draft } else { //not a draft: can be published, pending, etc. }
Notez cependant que celapourraitne pas être approprié si vousprévoyez de redéfinir ultérieurement le statut sur "brouillon" - vosinstructions seront répétées laprochainefois que vousmettrez àjour lemessage. Selon le contexte,vous voudrezpeut-être considérer les différentes chaînes quipeuvent être retournéespar
get_post_status()
pour construire un scénarioplus approprié.Voir Codexpour get_post_status () et État dumessage
Les valeurspossibles sont:
- 'publier' - Un article ou unepagepublié
- 'en attente' - lemessageesten attente d'examen
- "brouillon" - unmessage à l'étatbrouillon
- "brouillon automatique" - unmessagenouvellement créé,sans contenu
- 'future' - un article àpublier dans lefutur
- 'privé' -non visiblepour les utilisateurs quine sontpas connectés
- 'inherit' - une révision. voirget_children.
- 'corbeille' - lemessageest dans la corbeille. ajouté avec la version 2.9.
Another approach that uses a built-in function and no addition to the database would involve
get_post_status()
.$post_status = get_post_status(); if ( $post_status != 'draft' ) { //draft } else { //not a draft: can be published, pending, etc. }
Note however that it might not be appropriate if you plan to later set the status back to "draft" – your instructions would be repeated the next time you will update the post. Depending on the context, you might want to consider the various strings that can be returned by
get_post_status()
to build a more appropriate scenario.See Codex for get_post_status() and Post Status
Possible values are:
- 'publish' - A published post or page
- 'pending' - post is pending review
- 'draft' - a post in draft status
- 'auto-draft' - a newly created post, with no content
- 'future' - a post to publish in the future
- 'private' - not visible to users who are not logged in
- 'inherit' - a revision. see get_children.
- 'trash' - post is in trashbin. added with Version 2.9.
-
Jene pensepas que celafasse ce qui a été demandé.Sije crée unnouveaumessageet queje clique sur 'Publier',`save_post ()`estexécutépour lapremièrefois,maispendant cetteexécution `get_post_status ()` retourne déjà 'publier'et non 'brouillon',même si cen'est queen cours depublication.I don't think this does what was asked for. If I create a new post and then hit 'Publish', `save_post()` is executed for the first time, but during that execution `get_post_status()` already returns 'publish' and not 'draft', even though it is only in the process of being published.
- 0
- 2017-11-25
- cgogolin
-
- 2020-05-03
Je viens de rencontrer le
save_post
sur lesnouveautéset lesmises àjour. Après avoir lu le code sourcepour comprendre leflux. J'aitrouvé que laméthode suivantepourrait être utile. Puisqu'iln'estpasencorementionné auparavant. Voyez si celaest utile à quelqu'un. (Letestest le Core 5.3.3)Leflux depost-créationest approximativement:
- Après avoir appuyé sur Ajouter unnouveau (message)
- $post=get_default_post_to_edit ($post_type,true); sera appelé où
- get_default_post_to_edit () reçoit l'argument $ create_in_db=true
- afin que wp_insert_post () soitimmédiatement appelé,unmessage
auto-draft
esten cours de création,même s'iln'estpasenregistré,chaquefois que vous cliquez surAdd New
,unauto-draft
est créé - $ updateesttoujours vraipour Publish. Ainsi,lorsque vouspubliez unnouveaumessage,c'est vrai.
En comparant l'objet $ _POSTpour unnouvel articleet mettre àjour l'article ou republier l'article,laprincipale différenceest la valeur
_wp_http_referer
,lenouvel articleest/wp-admin/post-new.php
Hypothèse: on suppose que l'articleestpublié/ajouté àpartir de l'interface utilisateur. Si celaestfaitpar un autremécanisme,codepersonnalisé,la vérificationestnécessairepour ajuster.
add_action( 'save_post', 'test_save_post_check', 0, 3 ); function test_save_post_check( $post_ID, $post, $update ) { // other tests + this // checking the 'post-new' position from the '_wp_http_referer' if( strpos( wp_get_raw_referer(), 'post-new' ) > 0 ) { // new } else { // update } }
I have just encountered the
save_post
about new and update. After reading the source code to understand the flow. I found that the following method might be useful. Since it is not yet mentioned before. See if it is useful to anyone. (The test is Core 5.3.3)The Post creation flow is approximately:
- After pressing Add New (Post)
- $post = get_default_post_to_edit( $post_type, true ); will be called where
- get_default_post_to_edit() receive argument $create_in_db = true
- so wp_insert_post() is immediately being called,
auto-draft
post is being created, even it is not saved, every time clickingAdd New
, anauto-draft
is created - $update is always true for Publish. So when Publish a new post, it is true.
By comparing the $_POST object for new post and update post or republish post, the prominent difference is value
_wp_http_referer
, the new post is/wp-admin/post-new.php
Assumption: assumed the post is published/added from UI. If it is done by other mechanism, custom code, the checking is needed to adjust.
add_action( 'save_post', 'test_save_post_check', 0, 3 ); function test_save_post_check( $post_ID, $post, $update ) { // other tests + this // checking the 'post-new' position from the '_wp_http_referer' if( strpos( wp_get_raw_referer(), 'post-new' ) > 0 ) { // new } else { // update } }
Est-ilpossible,dans l'action save_post,de déterminer s'il s'agit d'unnouveauposten cours de création ou d'unpostexistanten cours demise àjour?