web-dev-qa-db-fra.com

Comment mettre à jour toutes les publications sauf la version actuelle (post__not_in ne fonctionne pas?)

J'essaie d'annuler la publication (définir post_status sur brouillon) de toutes les publications lorsqu'un nouveau (avec des conditions spécifiques qui importent peu à l'heure actuelle) est publié.

Voici ce que j'ai actuellement:

function rsc_unpublish_all_ads( $post_id ) {

    // don't do anything if the post is not an ad
    $post_type = get_post_type($post_id);
    if ( 'rsc-ads' != $post_type ) return;

    // select all ads other than the current one
    $args = array(
        'posts_per_page' => -1,
        'post__not_in' => array($post_id),
        'post_type' => 'rsc-ads',
        'post_status' => 'publish',
    );

    $published_ads = get_posts( $args );

    if ( !empty($published_ads) ) {

        // set each of the published ads as draft
        foreach ($published_ads as $published_ad) {

            // check again just for the sake of it?
            if ( $published_ad->ID == $post_id ) return;

            $unpublish = array(
                'ID' => $published_ad->ID,
                'post_status' => 'draft'
            );

            wp_update_post( $unpublish );
        }

    }

}

add_action( 'save_post', 'rsc_unpublish_all_ads' );

Ce qui se passe, c’est que toutes les publications rsc-ads sont définies sur brouillon , y compris celui que je sauvegarde/mets à jour - même si je le vérifie deux fois ( post__not_in dans le $args ET en comparant l’ID dans la boucle foreach).

Je sais que $post_id est correct parce que je vérifie le type de message au début de ma fonction et que cela fonctionne bien.

Des idées pour exclure la publication de la publication actuellement sauvegardée?

1
Jusi

Il existe un moyen plus élégant de mettre à jour vos messages en utilisant le $wpdb global.

function rsc_unpublish_all_ads( $post_id, $post, $update ) {

// select all ads other than the current one
$args = array(
    'nopaging' => true,
    'post__not_in' => array($post_id),
    'post_type' => 'rsc-ads',
    'post_status' => 'publish',
    'fields'=>'ids'
);

$query = new WP_Query($args);

$published_ads = $query->posts;//array of post ids

 if ( !empty($published_ads) ) {

    global $wpdb;

    $ids = implode(',', $published_ads);

    $wpdb->query("UPDATE $wpdb->posts SET post_status = 'draft' WHERE ID IN ($ids)");

 }

}
    add_action( 'save_post_rsc-ads', 'rsc_unpublish_all_ads', 10, 3 );

Je pense que vous aviez un problème pour appeler wp_update_post() alors que la fonction était toujours en cours d'exécution. Dans cette implémentation, si le $query renvoie correctement les ID de publication, vous effectuez un voyage vers la base de données et corrigez toutes les publications sans exécuter de boucle. Remarque J'ai modifié votre hook pour qu'il soit spécifique au type de message "rsc-ads" afin qu'il ne se déclenche que sur ce type de message.

0
jdp

Vous l'avez terminée par return, votre fonction sera donc arrêtée une fois la publication trouvée qui ne devrait pas (ou devrait?) Être mise à jour, mais la retourne à la place:

        if ( $published_ad->ID == $post_id ) return;

vous pouvez:

            if ( $published_ad->ID != $post_id ) {
// unpublishing ads
}

pour obtenir l'identifiant actuel du post en début de session:

get_the_ID();

dans l'éditeur wp admin:

$_GET['post'];

n'oubliez pas d'ajouter la condition is_admin pour vous assurer de l'exécuter dans l'admin wp

0
Asisten