Wie kann ich die XML-RPC-Post-Erstellung validieren und bei Bedarf abbrechen?

7

Ich habe ein IFTTT-Rezept , das gelegentlich Posts für mich erstellt, aber aus irgendeinem seltsamen Grund werden drei, manchmal vier Posts mit demselben Inhalt erstellt.

Ich möchte einen add_actionHook / Callback hinzufügen, um zu überprüfen, was ein neuer Beitrag sein wird, und, falls er bereits vorhanden ist, den Beitrag abzubrechen oder in den Papierkorb oder ähnliches zu verschieben.

Ich habe das gefunden, xmlrpc_prepare_postaber ich glaube nicht, dass ich es von dort aus stornieren kann. Es sei denn, ich kann ein Attribut aktualisieren und auf Papierkorb setzen?

Aktualisieren.

Ich habe Folgendes versucht und es gelangt immer nur in den xmlrpc_call, aber niemals in xmlrpc_wp_insert_post_meta. Ich habe sogar einen fest codierten Aufruf von add_filter hinzugefügt (nicht nur für den Fall, dass newPost), und meine Protokolle zeigen niemals eine solche Protokollierungsnachricht an.

Hier ist der Code:

function hueman_xmlrpc_call( $method )
{
    error_log("XMLRPC | hueman_xmlrpc_call Method = $method \n" , 3, '/home/.../debug.log');
    if( 'wp.newPost' === $method || 'metaWeblog.newPost' === $method )
    {
        error_log("XMLRPC | hueman_xmlrpc_call  method = " . $method . " \n" , 3, '/home/.../debug.log');
        add_filter( 'xmlrpc_wp_insert_post_data', 'hueman_xmlrpc_wp_insert_post_data' );
    }
}
add_action('xmlrpc_call', 'hueman_xmlrpc_call', 1 );


add_filter( 'xmlrpc_wp_insert_post_data', 'hueman_xmlrpc_wp_insert_post_data' );

function hueman_xmlrpc_wp_insert_post_data( $post_data )
{
    error_log("XMLRPC | hueman_xmlrpc_wp_insert_post_data  \n" , 3, '/home/.../debug.log');
    // Check if the post title exists:
    $tmp = get_page_by_title( 
        $post_data['post_title'], 
        OBJECT, 
        $post_data['post_type'] 
    );

    if( is_object ( $tmp ) )
    {
        // Go from 'insert' to 'update' mode within wp_insert_post():
        //$post_data['ID'] = $tmp->ID; 

        $post_data['post_status'] = 'trash';
        error_log("XMLRPC | hueman_xmlrpc_wp_insert_post_data I TRASHED IT! \n" , 3, '/home/.../debug.log');
    }

    return $post_data;  
}

In den Protokollen habe ich diese Art von Protokollanweisungen:

XMLRPC | hueman_xmlrpc_call Method = mt.supportedMethods 
XMLRPC | hueman_xmlrpc_call Method = metaWeblog.getRecentPosts 
XMLRPC | hueman_xmlrpc_call Method = mt.supportedMethods 
XMLRPC | hueman_xmlrpc_call Method = metaWeblog.getRecentPosts 
XMLRPC | hueman_xmlrpc_call Method = mt.supportedMethods 
XMLRPC | hueman_xmlrpc_call Method = metaWeblog.getRecentPosts 
XMLRPC | hueman_xmlrpc_call Method = metaWeblog.getCategories 
XMLRPC | hueman_xmlrpc_call Method = metaWeblog.newPost 
XMLRPC | hueman_xmlrpc_call  method = metaWeblog.newPost 

Dann werden andere Filter angezeigt, die ich beim Erstellen eines Artikels hinzugefügt habe. Ich weiß, dass ich wahrscheinlich die Artikel dort reparieren werde, aber ich bin sicher, dass diese XMLRPC-Filter / -Aktionen funktionieren sollten.

Aus den Protokollen geht hervor, dass es in die Datei if newPost geht und den Filter 'xmlrpc_wp_insert_post_data' hinzufügt, aber die Funktion hueman_xmlrpc_wp_insert_post_data niemals ausführt ... :(

Vallieres
quelle
4
Eine sehr gute (und interessante) Frage. Könnten Sie bitte eine Bearbeitung einreichen und erklären, wie IFTTT mit WP zusammenarbeitet, wie Sie es einrichten und wie Sie auf die XML-RPLC-Schnittstelle verweisen? Bitte seien Sie so ausführlich wie möglich, da dies zu einer sehr epischen Frage werden kann. Vielen Dank.
Kaiser
Es ist eigentlich sehr einfach. Ich habe IFTTT mit dem RSS 2 Wordpress-Rezept verwendet. Steckte meinen Autor RSS-Feed von der externen Seite. In Wordpress habe ich meinen regulären Wordpress-Benutzer angemeldet. Hier ist der Kanal: ifttt.com/wordpress und das Rezept: ifttt.com/recipes/19382-rss-feed-to-wordpress-blog
Vallieres

Antworten:

7

Es sieht so aus, als würde der xmlrpc_prepare_postFilter nur auf die Ausgabe der wp_getPostund wp_getRevision-Methoden der wp_xmlrpc_serverKlasse angewendet .

Es wäre toll, wenn diese Codezeile:

do_action( 'xmlrpc_call', 'wp.newPost' );

würde durch zusätzliche Eingabeargumente ersetzt werden, zum Beispiel:

do_action( 'xmlrpc_call', 'wp.newPost', ..., $content_struct );

aber das wird nach diesem Ticket nicht passieren .

Wir müssen also einen anderen Weg finden, um dies zu umgehen.

Mögliche Problemumgehungen:

Hier sind einige ungetestete Ideen, die xmlrpc_calldie xmlrpc_wp_insert_post_dataFilter und verwenden.

Ändern Sie die Eingabedaten, bevor sie eingefügt werden mit wp_insert_posts():

/**
 * Prevent duplicate posts when doing wp.newPost via XML-RPC
 *
 * @see http://wordpress.stackexchange.com/a/157261/26350
 */

add_action( 'xmlrpc_call', 'wpse_xmlrpc_call' );

function wpse_xmlrpc_call( $method )
{
    if( 'wp.newPost' === $method )
        add_filter( 'xmlrpc_wp_insert_post_data', 'wpse_xmlrpc_wp_insert_post_data' );
}

function wpse_xmlrpc_wp_insert_post_data( $post_data )
{
    // Check if the post title exists:
    $tmp = get_page_by_title( 
        $post_data['post_title'], 
        OBJECT, 
        $post_data['post_type'] 
    );

    // Go from 'insert' to 'update' mode within wp_insert_post():
    if( is_object ( $tmp ) )
        $post_data['ID'] = $tmp->ID; 

    return $post_data;  
}

Hier versuchen wir, bei wp.newPostAnrufen einen vorhandenen Beitrag mit demselben Titel zu finden . Wenn wir eines finden, fügen wir es IDdem $post_dataArray hinzu, sodass es stattdessen aktualisiert wird.

Beachten Sie, dass wir post_statusstattdessen auch Folgendes ändern könnten :

    $post_data['post_status'] = 'trash'; 

Alle zusätzlichen Einsätze werden also in den Papierkorb geleitet .

Sie können auch versuchen, über den Filter eine eigene Einfügemethode zu erstellenxmlrpc_methods .

Ich hoffe, Sie können dies an Ihre Bedürfnisse anpassen, vorausgesetzt, dies wird funktionieren ;-)

Update : Ich habe diese Idee jetzt getestet und sie funktioniert. Ich kann sowohl die duplizierten Beiträge in den Papierkorb werfen als auch direkt aktualisieren.

Vielen Dank an @DavidPeterson, dass er meine albernen PHP-Syntaxfehler bemerkt hat, als ich den Code im WPSE-Editor bearbeitet habe ;-)

Birgire
quelle
Genau das habe ich gesucht! Ich habe Ihre Lösung implementiert, hoffentlich funktioniert sie ordnungsgemäß und legt alle Duplikate in den Papierkorb. Ich werde es wissen, wenn der XMLRPC das nächste Mal ausgelöst wird!
Vallieres
Hallo, es hat nicht wie vorgesehen funktioniert. Sehen Sie unten, was ich getan habe. :(
Vallieres
Hallo @vallieres, danke für die Rückmeldung. Hoffentlich kann ich das Problem finden.
Birgire
Dank @birgire scheint es wirklich ein Bereich zu sein, in dem Dokumentation und / oder Beispiele nicht zu finden sind. Sie könnten denken, ich bin nicht der einzige, der XMLRPC-Artikel filtern möchte ...
Vallieres
Konnten Sie es zum Laufen bringen? Meiner Meinung nach scheint es überhaupt nicht zu funktionieren :(
Vallieres
1

In der Datei wp-includes / class-wp-xmlrpc-server.php

Innerhalb der Funktion mw_newPost () nach diesen Zeilen:

$post_title = isset( $content_struct['title'] ) ? $content_struct['title'] : null;
$post_content = isset( $content_struct['description'] ) ? $content_struct['description'] : null;

Hinzufügen:

global $wpdb;
$some_post = $wpdb->get_row("
    SELECT ID
    FROM {$wpdb->posts}
    WHERE post_title = '{$post_title}'
");

Und erstellen Sie eine Erklärung:

if (!empty($some_post->ID) and $some_post->ID > 0) {
    return 0;
} else {
    // the rest of the code that already exists in the function
    /*
    $post_status = $publish ? 'publish' : 'draft';
    ...
    return strval($post_ID);
    */
}
Brynner Ferreira
quelle
1
Hallo, geniale Lösung, aber das würde durch jedes Wordpress-Update nach der Änderung leicht außer Kraft gesetzt werden. Gibt es eine Möglichkeit, es über ein Plugin oder eine functions.php zum Laufen zu bringen?
Vallieres
1
@Vallieres, ja, du hast recht, dann habe ich WordPress-Updates deaktiviert. Ich möchte bald ein Plugin erstellen.
Brynner Ferreira