it-swarm.com.de

Wie validiere ich die Erstellung von XML-RPC-Posts und brich sie bei Bedarf ab?

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

Ich möchte einen add_action Hook/Callback hinzufügen, um zu überprüfen, was ein neuer Beitrag sein wird, und den Beitrag abzubrechen, oder in den Papierkorb zu verschieben.

Ich habe den xmlrpc_prepare_post gefunden, aber ich glaube nicht, dass ich ihn von dort aus stornieren kann. Kann ich ein Attribut nicht aktualisieren und in den Papierkorb verschieben?

Update.

Ich habe Folgendes versucht und es wird immer nur in xmlrpc_call angezeigt, aber nie in xmlrpc_wp_insert_post_meta. Ich habe sogar einen hartcodierten add_filter-Aufruf hinzugefügt (nicht nur im Falle von 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 sehe ich, dass es in den if newPost geht und den Filter 'xmlrpc_wp_insert_post_data' hinzufügt, aber niemals die Funktion hueman_xmlrpc_wp_insert_post_data ausführt ... :(

7
Vallieres

Es sieht so aus, als würde der xmlrpc_prepare_post-Filter nur auf die Ausgabe der wp_getPost- und wp_getRevision-Methoden der wp_xmlrpc_server-Klasse 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.

Mögliche Problemumgehungen:

Hier sind einige ungetestete Ideen mit den Filtern xmlrpc_call und xmlrpc_wp_insert_post_data.

Eingabedaten ändern, bevor sie mit wp_insert_posts() eingefügt werden:

/**
 * 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.newPost-Aufrufen einen vorhandenen Beitrag mit demselben Titel zu finden. Wenn wir eine finden, fügen wir sie ID zum $post_data-Array hinzu, damit sie stattdessen aktualisiert wird.

Beachten Sie, dass wir stattdessen auch den post_status ändern könnten mit:

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

daher werden alle zusätzlichen Einfügungen in den Papierkorb geleitet.

Sie können auch versuchen, eine eigeneEinfügen -Methode über den xmlrpc_methods -Filter zu erstellen.

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 die duplizierten Beiträge entweder in den Papierkorb werfen oder sie direkt aktualisieren.

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

7
birgire

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 erstelle 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);
    */
}
1