it-swarm.com.de

wp_insert_post () gibt die korrekte Beitrags-ID zurück, kein Fehler, aber der Beitragsinhalt wird nicht aktualisiert

Ich habe also ein Plugin, das Ajax verwendet, um den Inhalt eines Beitrags Stück für Stück für einen benutzerdefinierten Beitragstyp dynamisch zu erstellen. Sobald der Benutzer seine Seite erstellt hat, klickt er auf Aktualisieren/Veröffentlichen und Ajax sendet die gesamte erstellte Seite an eine PHP Datei des Haupt-Plugins, in der ich versuche, wp_insert_post() aufzurufen.

Hier ist mein relevanter Code (und ja, der var new_content ist gesetzt und korrekt):

jQuery.ajax({
    url: ajaxurl,
    method: 'POST',
    data : {
        update_or_create: '1',
        post_content: new_content,
        post_title: jQuery('#title').val(),
        pid: jQuery('#post_ID').val(),
        action : "update_or_save_zen_page"
    } , 
    success : function(data, textStatus, XMLHttpRequest) {
            //alert(data);
            console.log(data);           // the data sent to the php file is correct
            console.log(textStatus);     // reads 'success'
            console.log(XMLHttpRequest); // normal from what I can tell, "readyState: 4"
    },
    error : function(XMLHttpRequest, textStatus, errorThrown) {
            alert("An unknown error has occurred"); // this does not fire
            //console.log(data);
            //console.log(textStatus);
            //console.log(errorThrown);
            //console.log(XMLHttpRequest);
    }
});

Hier ist der PHP-Code, in den dieser Beitrag geschrieben wird:

function pbfcz_save_zen_page() {

    $pid = ( is_numeric($_POST['pid']) ? $_POST['pid'] : 0);
    $the_content = sanitize_post_field ('post_content', $_POST['post_content'], $pid);
    $the_title = sanitize_text_field ( $_POST['post_title'] );

    $post_array = array (
        'ID'           => $pid,
        'post_title'   => $the_title,
        'post_content' => $the_content, // at this point, $the_content is correct
        'post_status'  => 'publish',
        'post_type'    => 'zen_page'
    );

    $insert = wp_insert_post( $post_array, true ); // this returns the ID every time, meaning successful update, but it is not always successful

    //echo $insert;      // this is always the post ID, meaning success
    echo $the_content; // this is still correc

   wp_die();}

Wenn der Benutzer "Speichern" auswählt, habe ich die Daten bis zum Argument für wp_insert_post() verfolgt. Es ist immer richtig. Die Funktion gibt IMMER die Beitrags-ID zurück, was bedeutet, dass der Vorgang erfolgreich war. Ich erhalte keinen WP_Error oder HTML-Codefehler wie 404 oder 500 oder ähnliches.

Ich bekomme auch keine Fehler in der Chrome Developer Tools-Konsole. Aber es wird manchmal erfolgreich aktualisiert - vielleicht funktioniert jeder zehnte Versuch.

Ich habe versucht, GET anstelle von POST zu verwenden

Ich habe versucht, den 'post_status' => 'publish' aus den Argumenten zu entfernen.

Ich habe versucht, den post_content mithilfe von utf8_encode() in UTF8 zu konvertieren.

Ich habe versucht, post_content_filtered anstelle von post_content zu verwenden.

Nichts scheint zu funktionieren und es funktioniert zufällig und ich kann kein Muster finden.

Die einzige andere Information, die ich habe, ist, dass Bilder auf derselben Seite nur schwer geladen werden können. Wenn der Seiteninhalt ein Bild enthält, erhalte ich Fehler wie

"net :: ERR_SPDY_PING_FAILED" oder "net :: ERR_CONNECTION_RESET"

oder:

"net :: ERR_CONNECTION_CLOSED"

manchmal beim laden von seiten. Der Server versucht, das Bild für mehr als eine Minute zu laden, dann wird das Zeitlimit überschritten (das Bild wird jedoch bereits für die gesamte Minute auf der Seite angezeigt, und wenn das Zeitlimit überschritten wird, wird das Bild ausgeblendet).

Kann jemand vorschlagen, warum dies nicht funktioniert (mit null Fehlern), aber funktioniert es manchmal? Vielen Dank im Voraus und lassen Sie mich wissen, wenn Sie mehr Code oder Hintergrund benötigen.

1
Jeremy Muckel

Beheben Sie Ihren AJAX -Rückruf nicht, da bereits ein REST -API-Endpunkt vorhanden ist, der bereits getestet wurde und all dies sofort erledigt:

example.com/wp-json/wp/v2/zen_page

Lassen Sie uns also ein Hilfsskript einreihen, um uns die URL und ein Sicherheitstoken/Nonce zu geben:

wp_enqueue_script( 'wp-api' );

Sie werden müssen die REST API für Ihren benutzerdefinierten Beitragstyp aktivieren, indem Sie diese Option bei der Registrierung Ihres Beitragstyps hinzufügen. Wenn Sie dies nicht tun, werden die zen_page rest-Endpunkte nicht von core erstellt:

'show_in_rest' => true

Stellen Sie dann den JS ein:

var post_id = 1;
jQuery.ajax({
    url: wpApiSettings.root + 'wp/v2/zen_page/'+post_id,
    method: 'POST',
    beforeSend: function ( xhr ) {
        xhr.setRequestHeader( 'X-WP-Nonce', wpApiSettings.nonce );
    },
    data : {
        content: 'post content goes here',
        title:   'test post',
        status:  'publish'
    }
}).fail( function( response ) {
    // failure
    console.log( 'failure' );
    console.log( response );
}).done( function( response ) {
    // success!
    console.log( 'success' );
    console.log( response );
}).;

WP schließt das Objekt wpApiSettings automatisch ein, wenn Sie wp-api in die Warteschlange einreihen, und datanimmt diese Werte an . Sie benötigen dazu ein aktives Login-Cookie. Wenn dies nicht möglich ist, können Sie neue Ruheendpunkte erstellen

Wenn Sie ein neues erstellen möchten, senden Sie hier eine POST -Anforderung:

example.com/wp-json/wp/v2/zen_page

Wenn Sie eine aktualisieren möchten, senden Sie hier eine POST -Anforderung:

example.com/wp-json/wp/v2/zen_page/2

Wobei 2 die Beitrags-ID ist, die Sie aktualisieren möchten. Senden Sie eine DELETE-Anfrage, um sie zu löschen. In einer REST -API übergeben Sie keine Post-IDs oder -Aktionen, sondern verwenden URLs. Unterschiedliche URLs laden unterschiedliche Seiten, unterschiedliche Endpunkte führen unterschiedliche Aktionen aus. Sie können GET/POST/DELETE/PUT auswählen. Hierbei handelt es sich um die Standardtypen für HTTP-Anforderungen, nicht um einen in der Anforderung übergebenen Parameter.

Follow-up-Hinweise

rest_base

Auf diese Weise können Sie ändern, mit welchem ​​Core der Endpunkt erstellt wird, z.

'rest_base' => 'bananas'

ändert die URL Ihrer Endpunkte in wp/v2/bananas. Beachten Sie, dass Sie diese pages nicht benennen möchten, da von core bereits ein pages-Endpunkt bereitgestellt wird.

zen_page

Dies ist möglicherweise sogar besser, wenn Sie nur den Post-Typ page und eine benutzerdefinierte Taxonomie verwendet haben, um die zen_page von normalen Seiten zu unterscheiden.

Es funktioniert nicht

Die REST -API gibt an, warum sie nicht funktioniert hat, z. Wenn ich versuche, wp-json/wp/v2/skjlfnvlkdjfv zu besuchen, bekomme ich:

{"code":"rest_no_route","message":"No route was found matching the URL and request method","data":{"status":404}}

und wenn ich versuche, den wp-json/wp/v2/settings-Endpunkt im Inkognito-Modus zu verwenden:

{"code":"rest_forbidden","message":"Sorry, you are not allowed to do that.","data":{"status":403}}

Admin AJAX gibt in all diesen Szenarien 0 zurück. Seien Sie also dankbar, aber achten Sie auf Fehler oder Fehlermeldungen. Hier haben wir gesehen, dass ich versucht habe, eine Anfrage an einen nicht existierenden Endpunkt zu richten, und dann noch einmal an einen Endpunkt, für den ich keine Berechtigung hatte, als ich abgemeldet war.

2
Tom J Nowell

Dank @TomJNowell konnte ich mit wp_insert_post () umgehen, was nicht funktionieren würde, und meine Posts mit der PHP-Version der REST API aktualisieren.

Ich musste:

1) Fügen Sie 'show_in_rest' => true in die Registrierung meines benutzerdefinierten Beitragstyps ein.

2) Rufen Sie das Hilfsskript auf: wp_enqueue_script( 'wp-api' );

3) Verwenden Sie dieses PHP, um die jquery-Post-Anfrage zu bearbeiten

add_action('wp_ajax_update_or_save_zen_page', 'pbfcz_save_zen_page', 99999);
function pbfcz_save_zen_page() {
    $pid = $_POST['pid'];
    $the_content = sanitize_post_field ('post_content', $_POST['post_content'], $pid);
    $the_title = sanitize_text_field ( $_POST['post_title'] );  
    $the_content = str_replace('\"', '"', $the_content);

    $_rest = new WP_REST_Request('PUT', '/wp/v2/zen_page/' . $pid);
    $_rest->set_param( 'title', $the_title);
    $_rest->set_param( 'status', 'publish');
    $_rest->set_param( 'content', $the_content);

    $response = rest_do_request($_rest);
    echo 'done';

    wp_die(); // do not remove
}

Meine jQuery hat sich gegenüber der ursprünglichen Frage nicht wesentlich verändert. Der Übersichtlichkeit halber hier posten:

jQuery.ajax({
        url: ajaxurl,
        method: 'POST',
        data : {
            post_content : new_content,
            post_title   : jQuery('#title').val(),
            pid          : post_id,
            action       : "update_or_save_zen_page"
        } , 
        success : function(data, textStatus, XMLHttpRequest) {
            //console.log(data);          
        },
        error : function(XMLHttpRequest, textStatus, errorThrown) {
            alert("An unknown error has occurred and the ajax request to create/update the post has failed.");
        }
});
0
Jeremy Muckel