web-dev-qa-db-fra.com

Crochet pour traiter une nouvelle balise de taxonomie avant sa création?

Je travaille sur un site Web où existe une taxonomie personnalisée pour les lieux, qui peuvent être des villes ou des États. Les utilisateurs sont supposés étiqueter chaque message avec une ville et un état. Pour traiter des villes ambiguës portant le même nom dans plusieurs États, ces balises portent le nom de cet État (par exemple, "Miami, Floride" porte le nom "Miami Florida" et "Miami, Ohio" s'appelle "Miami Ohio").

Les utilisateurs ont été incapables de maîtriser ce système, malgré la saisie semi-automatique, et continuent à saisir "Miami, Floride", ce qui crée une nouvelle balise "Miami" avec la balise Florida existante.

J'aimerais intercepter les entrées de l'utilisateur lorsque la publication est enregistrée et qu'une nouvelle balise est sur le point d'être créée pour voir si la combinaison cité-État existe déjà (c'est-à-dire que si une balise est Miami et l'autre Floride, " Miami Florida "existe déjà). Ensuite, j'aimerais bloquer la création de la nouvelle balise et appliquer à la place la balise existante.

Quel crochet utiliserais-je et comment pourrais-je modifier les tags sur le message?

4
Joel

Le crochet que vous recherchez est created_{$taxonomy} mais il y a un autre problème. Je pense que le plus gros défaut de la logique est de mettre les deux États et les villes dans la même taxonomie. Vous ne pourrez jamais différencier les deux termes (qui est la ville et qui est l'état). Ceci ouvre à l'utilisateur certaines des actions suivantes qui sont toutes incorrectes

  • Entrez la ville sans état
  • Entrez Etat sans ville
  • État ou ville de Misspell

Je pense que la solution ici est de diviser les États et les villes en deux taxonomies différentes. tax_states et tag_cities. Cela garantira que chaque message a un état et que chaque balise de ville porte le préfixe. Je vais commencer le code ci-dessous en supposant que les deux taxonomies sont enregistrées.

Tout d’abord, ajoutons un peu de jQuery pour s’assurer qu’un état est défini - vous voudrez peut-être envisager mettre en file d'attente il s’agit d’un petit script:

function post_type_custom_script() {
    global $post_type;

    if( 'post' === $post_type ) {
      ?>

        <script type="text/javascript">
            /* Checks if cat is selected when publish button is clicked */
            jQuery( '#submitdiv' ).on( 'click', '#publish', function( e ) {
                var $checked = jQuery( '#category-all li input:checked' );

                //Checks if cat is selected
                if( $checked.length <= 0 ) {
                    alert( "Please select a State" );
                    return false;
                } else { 
                    return true;
                }
            } );
        </script>

      <?php
    }
}
add_action( 'admin_footer', 'post_type_custom_script' );

Le plus gros problème avec le script ci-dessus est qu'il suppose que votre taxonomie est hiérarchique (cases à cocher) - mais puisque, en théorie, un seul État doit être sélectionné, aucune taxonomie n'est un choix optimal. Au lieu de cela, vous pouvez créer une liste de termes et utiliser save_post pour enregistrer le terme ou (ce que je suggérerais) changer les cases à cocher hiérarchiques en boutons radio ( PHP Classe , boutons radio pour taxonomies) ).

Nous devrions maintenant avoir une taxonomie pour les États qui doit être sélectionnée afin de publier et une zone de balises pour les villes. L'étape suivante consiste à ajouter l'état à la balise city chaque fois qu'il a été publié. C'est une longue liste de conditions donc j'ai ajouté des commentaires si nécessaire. Si, d'une manière ou d'une autre, aucun état n'est sélectionné, nous transformons la publication en brouillon en dernier résultat:

/**
 * This function runs whenever a post is saved
 *
 * @param Int $post_id
 *
 * @return void
 */
function state_appended_tags( $post_id ) {
    global $post;

    if( ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || ( ! current_user_can( 'edit_post', $post_id ) || ! is_object( $post ) ) ) {
        return $post_id;
    }

    if( 'post' === $post->post_type ) {
        $state      = false;
        $set_draft  = false;

        if( isset( $_POST['tax_input'] ) && ! empty( $_POST['tax_input'] ) ) {

            // Grab State
            // If using the Radio Buttons Plugin linked above, use this conditional
                // if( isset( $_POST['radio_tax_input']['tax_states'] ) && ! empty( $_POST['radio_tax_input']['tax_states'] ) && 0 !== $_POST['radio_tax_input']['tax_states'][0] ) {
                    // $state_obj  = get_term_by( 'id', $_POST['radio_tax_input']['tax_states'][0], 'tax_states' ); // Grab Term Object
                    // $state_slug = $state_obj->slug;
            if( isset( $_POST['tax_input']['tax_states'] ) && ! empty( $_POST['tax_input']['tax_states'] ) && 0 !== $_POST['tax_input']['tax_states'][0] ) {
                $state_obj  = get_term_by( 'id', $_POST['tax_input']['tax_states'][0], 'tax_states' );  // Grab Term Object
                $state_slug = $state_obj->slug;
            } else {
                $set_draft = true;
            }

            // Prefix Cities
            if( ! empty( $state_slug ) && isset( $_POST['tax_input']['tag_cities'] ) && ! empty( $_POST['tax_input']['tag_cities'] ) ) {
                $new_tags = array();

                foreach( $_POST['tax_input']['tag_cities'] as $city ) {
                    $city_obj   = false;
                    $city_slug  = '';

                    // Post tags come in two forms - slugs and integers
                    if( is_numeric( $city ) ) {
                        $city_obj  = get_term_by( 'id', $city, 'tag_cities' );  // Grab Term Object
                        $city_slug = $city_obj->slug;
                    } else {
                        $city_obj  = get_term_by( 'slug', $city, 'tag_cities' );    // Grab Term Object
                        $city_slug = $city_obj->slug;
                    }

                    // If user has already entered the correct state-city formatted tag, skip it
                    // Otherwise we'll enter the conditional
                    if( 0 !== strcmp( "{$state_slug}-{$city_slug}", $city_slug ) ) {
                        $new_tags[] = "{$state_slug}-{$city_slug}";
                        wp_delete_term( $city_obj->term_id, 'tag_cities' );     // Delete Term
                    }
                }

                // Set New State Appended Tags
                if( ! empty( $new_tags ) ) {
                    wp_set_object_terms( $post_id, $new_tags, 'tag_cities', false );
                }
            }
        } else {
            $set_draft = true;
        }

        // Finally, should something have failed, don't publish the post and investigate
        if( $set_draft ) {
            remove_action( 'save_post', 'state_appended_tags' );
            wp_update_post( array(
                'ID'            => $post_id,
                'post_status'   => 'draft',
            ) );
            add_action( 'save_post', 'state_appended_tags' );
        }
    }
}
add_action( 'save_post', 'state_appended_tags' );

Vous devrez changer tag_cities et tax_states avec vos taxonomies réelles, mais cela devrait fonctionner pour vous.

2
Howdy_McGee