J'enregistre mon CPT dans _ STATUTprivate
. La transition serait donc de pending
à private
. Le fait est que, lorsque le message a été soumis pour la première fois et est en attente, sa date de soumission est indiquée dans le champ post_date
de la base de données. Mais lorsque la publication a été publiée, la date a été mise à jour avec la date du jour.
Je souhaite conserver la date originale de soumission du message, même le message publié ultérieurement à titre privé.
Alors j'ai fait quelque chose comme ci-dessous:
function mycpt_keep_pending_date_on_publishing( $new_status, $old_status, $post ) {
if( 'mycpt' === $post->post_type && 'pending' === $old_status && 'private' === $new_status ) :
$pending_datetime = get_post_field( 'post_date', $post->ID, 'raw' );
// Update the post
$modified_post = array(
'ID' => $post->ID,
'post_date' => $pending_datetime,
'post_date_gmt' => get_gmt_from_date( $pending_datetime )
);
// Update the post into the database
wp_update_post( $modified_post );
endif;
}
add_action( 'transition_post_status', 'mycpt_keep_pending_date_on_publishing' );
Mais ça ne marche pas. Quelle peut être la raison?
@Howdy_McGee est sur la bonne voie dans son commentaire: au moment où transition_post_status est déclenché, la publication a déjà été mise à jour (c'est-à-dire écrite sur la base de données) .
Ce que vous devez faire, c'est vous connecter à wp_insert_post_data , au lieu de transition_post_status
, comme suit:
add_filter ('wp_insert_post_data', 'mycpt_keep_pending_date_on_publishing', 10, 2) ;
function
mycpt_keep_pending_date_on_publishing ($data, $postarr)
{
if ($data['post_type'] != 'mycpt') {
return ($data) ;
}
// this check amounts to the same thing as transition_post_status(private, pending)
if ('private' != $data['post_status'] || 'pending' != $postarr['original_post_status']) {
return ($data) ;
}
$pending_datetime = get_post_field ('post_date', $data['ID'], 'raw') ;
$data['post_date'] = $pending_datetime ;
$data['post_date_gmt'] = get_gmt_from_date ($pending_datetime) ;
return ($data) ;
}
Remarque: J'ai utilisé le même nom de fonction que vous, mais le corps de cette fonction est différent.
En plus des autres réponses, voici un petit plugin qui garantit que le code n'est exécuté qu'une seule fois. Si les données sont réinitialisées par un plugin exécuté ultérieurement, essayez d'utiliser PHP_INT_MAX -1
comme priorité (pas pour les plugins distribués publiquement). Dans ce cas, vous devrez définir la même valeur pour remove_filter()
, sinon le rappel ne sera pas supprimé.
<?php
/**
* Plugin Name: (WPSE) Static post date
* Description: Keep the post date as the original date for posts published as private
*/
namespace WPSE;
add_filter( 'wp_insert_post_data', '\WPSE\save', 10, 2 );
function save( $post, $raw ) {
if ( ! in_array( $post['post_status'], [ 'private', 'pending', ] ) ) {
return $post;
}
if ( 'your_post_type' !== $post['post_type'] ) {
return $post;
}
$date = get_post_field( 'post_date', $post['ID'], 'raw' );
$post['post_date'] = $date;
$post['post_date_gmt'] = get_gmt_from_date( $date );
return $post;
}
add_action( 'transition_post_status', function() {
# Make sure above callback is only triggered once
remove_filter( 'wp_insert_post_data', '\WPSE\save' );
} );
Le problème principal rencontré par IIRC avec le code ci-dessus est que le filtre private_to_published
était obsolète. Il n’ya donc rien de plus spécifique à part un filtre d’état de type de publication . Essayez le plugin suivant et voyez si cela fonctionne (si votre type de publication s'appelle vraiment mycpt
):
<?php
/* Plugin Name: (WPSE) Test post type status actions */
add_action( 'private_mycpt', function( $ID, \WP_Post $post ) {
var_dump( current_filter() );
exit;
}, 10, 2 );