web-dev-qa-db-fra.com

Comment ajouter des termes de taxonomie personnalisés par programme à une publication de type personnalisée lors de la sauvegarde des publications?

Scénario: Le site Web comporte une section "Livres recommandés" qui utilise le type de publication personnalisé "livre" et la taxonomie personnalisée "auteur". J'utilise Amazon Product Advertising API pour récupérer des données de livre et des couvertures. Lors de l'ajout d'un nouveau "livre" dans WordPress, l'utilisateur copie l'ID du livre (ASIN) dans le champ de modification de publication, puis clique sur "Publier". Ensuite, lors de la sauvegarde de l'article, le titre de l'article (titre du livre) et le terme de taxonomie de l'auteur doivent être renseignés par programme via Amazon. (Ils sont utilisés pour offrir la fonctionnalité 'Order by' sur le front-end.)

J'utilise actuellement wp_insert_post_data pour accéder au processus de sauvegarde du 'livre' et la fonction wp_set_object_terms pour essayer d'ajouter le terme de taxonomie personnalisé au 'livre'.

Le problème est le suivant: la fonction wp_set_object_terms ne semble pas fonctionner. Cela n'ajoute rien, mais renvoie un tableau qui, selon le Codex, devrait signifier le succès. Bien que le tableau de retour soit étrange (autant que je vois). Lors de l'utilisation de l'ID de publication 107 et de l'ID de terme 3 (au lieu d'une chaîne d'auteur, à des fins de test), le tableau renvoyé affiche les informations suivantes avec print_r:

Array
(
[0] => 3
)

(Également essayé avec wp_set_post_terms, et cela ne fait aucune différence.)

Ma fonction complète:

// Function to automatically retrieve and store Amazon Book data (title and author) when adding 'book' type posts
if( function_exists('asa_item') ) {
    add_filter( 'wp_insert_post_data', 'filter_handler', '99', 2 );
    function filter_handler( $data , $postarr ) {

        // Proceed only if book is added/edited
        if ( $postarr['post_type'] !== 'book')
            return $data;

        // Try to Extract ASIN from post body; ignore everything else
        if ( preg_match( '/([0-9A-Z]{10})/', $data['post_content'],  $matches) ) {
            // Successful, store ASIN
            $book_asin = $matches[0];
            // Wrap ASIN in AmazonSimpleAdmin shortcode (with 'cover' template) automatically for user convenience
            $data['post_content'] = '[asa cover]' . $matches[0] . '[/asa]';
        } else {
            // Unsuccessful: set to draft, return and show error message
            $data['post_status'] = 'draft';
            add_filter('redirect_post_location', 'my_redirect_post_location_filter_1', 99);
            return $data;
        }

        // Retrieve and store book data from Amazon with AmazonSimpleAdmin plugin
        $book_data = explode( "<sep>", asa_get_item( $book_asin, 'book_data' ) );
        /******************
         * index 0 = title
         * index 1 = author
         ******************/

        // Check data; if no data, set to draft, return and show error message
        if ( $book_data[0] == '' ) {
            $data['post_status'] = 'draft';
            add_filter('redirect_post_location', 'my_redirect_post_location_filter_2', 99);
            return $data;
        }

        // Fill in Post Title with Amazon data if empty
        if ( $data['post_title'] == '' )
            $data['post_title'] = $book_data[0];

        // Fill in Author tag with Amazon data if missing
        if ( ! has_term( $book_data[1], 'author', $postarr['ID'] ) ) {
            wp_set_object_terms( $postarr['ID'], $book_data[1], 'author' );
        }

        return $data;
    }
}
3
MrValueType

Donc, pour répondre à ma propre question:

Je n'ai trouvé aucune solution dans wp_insert_post_data. Je soupçonne que le problème est lié au fait que lorsque wp_insert_post_data est exécuté, le message en question ne se trouve pas encore dans la base de données. Et bien que je n’aie pas réussi à le trouver dans taxonomy.php, il est logique de supposer que la fonction wp_set_post_terms dispose d’un mécanisme de vérification pour éviter d’insérer des relations de terme avec des identifiants de publication arbitraires/non existants.

Quoi qu'il en soit, dans wp_insert_post_data, j'ai défini une variable globale pour stocker le terme de taxe à ajouter (au lieu d'essayer de l'ajouter localement). Ensuite, je me suis connecté à save_post, qui est exécuté après que la publication ait été enregistrée, et j'ai récupéré/inséré le terme à partir de là.

Semble fonctionner très bien.

La partie de code pertinente dans wp_insert_post_data:

...

// Fill in Author tag with Amazon data if missing
if ( ! has_term( $book_data[1], 'author', $postarr['ID'] ) ) {
    global $add_this_tax_term_to_book;
    $add_this_tax_term_to_book[] = $book_data[1];
    $add_this_tax_term_to_book[] = 'author';
}

...

Et le code pour save_post:

add_action('save_post', 'add_my_tax_term');
function add_my_tax_term( $post_id ) {
    global $add_this_tax_term_to_book;

    if ( !(empty( $add_this_tax_term_to_book )) ) {
        wp_set_object_terms( $post_id, $add_this_tax_term_to_book[0], $add_this_tax_term_to_book[1] );
}
3
MrValueType