it-swarm.com.de

Wie kann ich einem benutzerdefinierten Beitragstyp programmgesteuert benutzerdefinierte Taxonomiebegriffe hinzufügen, wenn Beiträge gespeichert werden?

Szenario: Auf der Website gibt es einen Abschnitt mit den empfohlenen Büchern, der den benutzerdefinierten Post-Typ 'Buch' und die benutzerdefinierte Taxonomie 'Autor' verwendet. Ich verwende die Amazon Product Advertising API zum Abrufen von Buchdaten und Deckblättern. Beim Hinzufügen eines neuen "Buches" in WordPress kopiert der Benutzer die Buch-ID (ASIN) in das Feld "Nachbearbeitung" und klickt auf "Veröffentlichen". Beim Speichern des Beitrags sollten dann der Beitragstitel (Buchtitel) und der Taxonomiebegriff des Autors programmgesteuert über Amazon eingegeben werden. (Diese werden verwendet, um "Bestellen nach" -Funktionalität am Front-End anzubieten.)

Momentan verwende ich wp_insert_post_data, um mich in den 'Buch'-Speichervorgang einzuklinken, und die wp_set_object_terms-Funktion, um zu versuchen, den benutzerdefinierten Taxonomiebegriff zum' Buch 'hinzuzufügen.

Das Problem ist: Die Funktion wp_set_object_terms scheint nicht zu funktionieren. Es wird nichts hinzugefügt, obwohl es ein Array zurückgibt, das laut Codex Erfolg bedeuten sollte. Obwohl das zurückgegebene Array seltsam ist (soweit ich das sehe). Bei Verwendung der Post-ID 107 und der Term-ID 3 (anstelle einer Autorenzeichenfolge zu Testzwecken) zeigt das zurückgegebene Array Folgendes mit print_r an:

Array
(
[0] => 3
)

(Auch mit wp_set_post_terms ausprobiert, und es macht keinen Unterschied.)

Meine vollständige Funktion:

// 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

Um meine eigene Frage zu beantworten:

Ich habe in wp_insert_post_data keine Lösung gefunden. Ich vermute, dass das Problem damit zusammenhängt, dass der betreffende Beitrag beim Ausführen von wp_insert_post_data noch nicht in der Datenbank vorhanden ist. Und obwohl ich es nicht geschafft habe, es in taxonomy.php zu finden, ist es logisch anzunehmen, dass die wp_set_post_terms-Funktion über einen Überprüfungsmechanismus verfügt, um das Einfügen von Termbeziehungen mit beliebigen/nicht vorhandenen Post-IDs zu vermeiden.

Jedenfalls habe ich in wp_insert_post_data eine globale Variable definiert, um den Steuerbegriff zu speichern, der hinzugefügt werden muss (anstatt zu versuchen, ihn lokal hinzuzufügen). Dann habe ich mich in save_post eingebunden, der ausgeführt wird, nachdem der Beitrag gespeichert wurde, und den Begriff von dort abgerufen/eingefügt.

Scheint gut zu funktionieren.

Der relevante Codeteil in 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';
}

...

Und der Code für 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