web-dev-qa-db-fra.com

Vérifier avant la publication, s'il existe déjà une publication avec la valeur de champ personnalisée actuelle

J'ai un type de message personnalisé avec seulement 3 champs personnalisés.

$post_types = get_post_meta($post->ID,'post_types',true);
$post_taxonomies = get_post_meta($post->ID,'post_taxonomies',true);
$post_terms = get_post_meta($post->ID,'post_terms',true);

Je veux vérifier s'il existe déjà une publication avec cette valeur $ post_types et, le cas échéant, - afficher un message sans publication.

J'ai créé une metabox pour ces champs personnalisés, qui ont déjà une fonction pour le hook action save_post.

function sidebars_meta_save( $id )  {  
    if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;  

    if( !isset( $_POST['sidebars_nonce'] ) || !wp_verify_nonce( $_POST['sidebars_nonce'], 'save_sidebars_meta' ) ) return;  
    if( !current_user_can( 'edit_post' ) ) return;  

    $allowed = array(  
        'p' => array()  
    );      

    if(isset( $_POST['post_terms'] )){
                    //check_exist_term - simple boolean function which check if 
                    //a post with this term already exist
        if(!check_exist_term($_POST['post_terms'])){
            if( isset( $_POST['post_types'] ) ){  
                update_post_meta( $id, 'post_types', wp_kses( $_POST['post_types'], $allowed ) ); 
            }
            if( isset( $_POST['post_taxonomies'] ) ) { 
                update_post_meta( $id, 'post_taxonomies', wp_kses( $_POST['post_taxonomies'], $allowed ) );
            }
                update_post_meta( $id, 'post_terms', wp_kses( $_POST['post_terms'], $allowed ) );
            }
        }else{
                        //if I will use wp_delete_post here, the message will not show
            //wp_delete_post($id);
            //wp_redirect('post-new.php?post_type=sidebars');
            //exit;
        }
    }
}  
add_action( 'save_post', 'sidebars_meta_save' );  

Ma fonction de localisation de redirection:

function sidebars_redirect_location($location,$post_id){
if( isset( $_POST['post_types'] ) ){  
    if(check_exist_term($_POST['post_terms'])){
        $status = get_post_status( $post_id );
        $location = add_query_arg('message', 21, $location);
                    //if I will use wp_delete_post here, I will be not able 
                    //to return to post edit page, because page will be already deleted
    }
}
return $location;
}
add_filter('redirect_post_location','sidebars_redirect_location',10,2);

Mes messages postés à jour fonctionnent:

function sidebars_custom_messages($messages){
$messages['sidebars'][21] = 'Looks like you tried publishing a post with term which already exist!';
return $messages;
}    
 add_filter('post_updated_messages', 'sidebars_custom_messages');    

1) Où dois-je utiliser wp_delete_post () Si je veux tout d’abord afficher un message indiquant que ce message existe déjà, puis supprimer ce message et rester sur cette page? 2) Comment afficher un message rouge au lieu de jaune?

2
user13250

Vérifier s'il existe des méta-valeurs

Vous pouvez utiliser get_posts() (ou le WP_Query object) pour interroger toutes les publications qui correspondent à la méta de publication que vous souhaitez enregistrer. Vous devrez spécifier le statut de la publication (quels statuts souhaitez-vous ignorer)? Ci-dessous se trouve le code non testé .

(Par souci d'exhaustivité, j'ai laissé des arguments qui pourraient être omis car ils reçoivent leur valeur par défaut). J'exclus également le message actuel, au cas où le message serait mis à jour - sinon, ce message sera renvoyé et nous penserons qu'un message existe déjà avec ces métadonnées.

//Collect the terms
//I'm assuming that each of the values are strings. 
$meta_terms = $_POST['post_terms'];
$meta_taxs = $_POST['post_taxonomies'];
$meta_types = $_POST['post_types'];

//Query post type 'products' to check for posts whose meta values match the POSTed ones
$args = array(
  'post__not_in'=> array($id),
  'post_type' => 'product',
  'post_status' => array('publish','pending','draft','future','private'),
  'meta_query' => array(
      'relation' => 'AND',
      array(
        'key' => 'post_terms',
        'value' => $meta_terms,
        'compare' => '='
      ),
      array(
        'key' => 'post_taxonomies',
        'value' => $meta_taxs,
        'compare' => '='
      ),
      array(
        'key' => 'post_types',
        'value' => $meta_types
        'compare' => '='
      )
  )
);
$existingMeta = get_posts( $args );

if(empty($existingMeta)){
    //Go ahead and save meta data
}else{
    //Revert post back to draft status as shown in linked answer below.
}

Remarques latérales

Les "post_terms" etc. semblent assez génériques. Je leur donnerais des noms plus descriptifs et uniques - événement plus si utilisé comme clé dans la table méta post. De plus, pour éviter les conflits, vous pouvez envoyer les données dans un tableau avec un nom unique: i.e.

<input type="text" name="myplugin[post_terms]" value=""/>

Ensuite, récupérez les données en tant que $_POST['myplugin']['post_terms'] plutôt que $_POST['post_terms']. Vous pouvez être raisonnablement sûr que les données contenues dans $_POST['myplugin'] ont été écrasées par un autre plug-in. De plus, vousdevezutilisez nonces pour vérifier la source/l’intention.

Empêcher la publication de la publication

Vous ne pouvez pas empêcher une publication d'être publiée (sauf si vous utilisez jQuery). Cependant, immédiatement après la publication d'un article, vous pouvez effectuer une vérification et, si vous le souhaitez, le rétablir en tant que brouillon: Voir ma solution à cette question connexe .

Affichage d'un message personnalisé

Dans la solution liée, si un message avait été renvoyé en mode brouillon, je définissais la variable message à "10" afin que le message brouillon soit affiché: ' Brouillon mis à jour .... ':

add_filter('redirect_post_location','my_redirect_location',10,2);
function my_redirect_location($location,$post_id){
    //If post was published...
    if (isset($_POST['publish'])){
        //obtain current post status
        $status = get_post_status( $post_id );

        //The post was 'published', but if it is still a draft, display draft message (10).
        if($status=='draft')
            $location = add_query_arg('message', 10, $location)
    }

    return $location;
}

Vous pouvez cependant spécifier votre propre message. Le 10 fait référence à une clé de tableau où chaque valeur est un message. 0 est vide, 1-9 étant les messages par défaut (publication publiée, mise à jour, etc.)

( Ceci n'est pas testé ) mais vous pouvez ajouter vos propres messages à ce tableau:

add_filter('post_updated_messages', 'my_custom_messages');
function my_custom_messages($messages){
    //$message is an array of arrays. 
    //$message['post_type'] is an array of messages for post type 'post_type'
    //It is a non-assocative array. Value for 0 is blank. Keys 1-9 hold the default messages

    //Add a custom message to key 21 for post type 'my_post_type'
    $messages['my_post_type'][21] = 'Looks like you tried publishing, but something went wrong';

  return $messages
}

Vous pouvez ensuite définir le message sur 21 plutôt que sur 10, comme indiqué ci-dessus.

5
Stephen Harris