it-swarm.com.de

benutzerdefinierte XMLRPC-Methode plus Authentifizierung der Benutzer- und WooCommerce-Bestellung

Ich arbeite mit einer benutzerdefinierten XML-RPC-Methode, um einige Informationen für ein von mir erstelltes Plugin zu erfassen. Bei Aktivierung muss sich der Benutzer authentifizieren, indem er den Benutzer/das Passwort eingibt, der/das ihm beim Kauf des Plugins auf meiner WP Site gegeben wurde.

Das Plugin benutzt diesen Code:

if ( isset( $_POST['username'] ) && isset( $_POST['password'] ) ) {

        /* check against remote server */
        require_once( ABSPATH . WPINC . '/class-IXR.php' );
        $this->client = new IXR_Client( trailingslashit( CUSTOMLOGIN_UPDATE_API ) . 'xmlrpc.php' ); //*/

        $url = ( ( is_multisite() ) ? network_site_url() : site_url() );

        $client_request_args = array(
            'username'  => $_POST['username'],
            'password'  => $_POST['password'],
            'plugin'    => CUSTOMLOGINPRO_BASENAME,
            'url'       => $url
        );

        if ( !$this->client->query( 'thefrosty.is_user_authorized', $client_request_args ) ) {
            add_action( 'admin_notices', array( $this, 'error_notice' ) );
            return false;
        }

        $this->settings = get_option( CUSTOMLOGINPRO . '_settings', array() );
        $this->settings['api-key'] = $this->client->getResponse();
        update_option( CUSTOMLOGINPRO . '_settings', $this->settings );
        header( 'Location: ' . admin_url( 'options-general.php?page=' . CUSTOMLOGINPRO ) );
        die();

    } 

Das Formular wird gesendet und sieht so aus, als würde es funktionieren. Beim lokalen Arbeiten wird ein Fehler von 200 angezeigt, der jedoch mit einem anderen Plug-in getestet wurde, das denselben Fehlercode sendet, jedoch Antworten vom Host sendet (noch keine Bedenken).

Woran ich festhalte, ist der Back-End-Code. Ich habe eine Klasse in einem Kern-Plugin in meiner WP -Installation erstellt. Ich gehe davon aus, dass dies der Ort ist, an dem es sein muss. Ich vermisse einige Antworten auf Fehlercodes und Fehlermeldungen und weiß nicht, wie ich diese ausführen soll. Nur auf der Suche nach einem kleinen Push in die richtige Richtung ..

Wie Sie sehen, teste ich den Benutzer auch anhand einer WooCommerce-Bestellung (Code aus WC sollte gut sein), aber wenn ich dann versuche, die Meta-Meta-Bestellung zu aktualisieren, müssen möglicherweise Korrekturen vorgenommen werden, um die URLs des Benutzers zu speichern.

class frosty_core {

function __construct() {
    add_filter( 'xmlrpc_methods', array( $this, 'xmlrpc_methods' ) );
}

/**
 * Create our custom XML-rpc method.
 * @ref http://kovshenin.com/2010/04/custom-xml-rpc-methods-in-wordpress-2151/
 */
function xmlrpc_methods( $methods ) {
    $methods['thefrosty.is_user_authorized'] = array( $this, 'thefrosty_plugin_callback' );
    return $methods;
}

/**
 * XML-prc mothod
 */
function thefrosty_plugin_callback( $args ) {

    // Parse the arguments, assuming they're in the correct order
    $username       = $args[0];
    $password       = $args[1];
    $plugin_name    = $args[2];
    $url            = $args[3];

    global $wp_xmlrpc_server;

    // Let's run a check to see if credentials are okay
    if ( !$user = $wp_xmlrpc_server->login($username, $password) ) {
        return $wp_xmlrpc_server->error;
    }

    if ( !class_exists( 'woocommerce' ) ) return 'error, please try again later';

    /* Get the user ID by name */
    $current_user_id = get_userdatabylogin( $username );

    /* woocommerce/shortcodes/shortcode-my_account.php */
    $args = array(
        'numberposts'     => -1,
        'meta_key'        => '_customer_user',
        'meta_value'      => $current_user_id,
        'post_type'       => 'shop_order',
        'post_status'     => 'publish' 
    );
    $customer_orders = get_posts( $args );      
    $match = false;

    foreach ( $customer_orders as $customer_order ) :
        $order = &new woocommerce_order();
        $order->populate( $customer_order );

        $status = get_term_by( 'slug', $order->status, 'shop_order_status' );
        if ( 'completed' !== $status->name ) return; //error, order not completed //*/

        if ( $plugin_name !== $order->items->name ) return; // you have not purchased this plugin //*/

        $match  = true;
        $apikey = $order->order_key;
    endforeach;

    if ( isset( $match ) && $match ) {
        /* woocommerce/admin/writepanels/writepanel-order_data.php */
        add_filter( 'update_order_item', create_function( '$order_items', '
            $new_meta   = &new order_item_meta();
            $meta_name  = "active_urls";
            $meta_value = esc_url( $url );

            $new_meta->add( $meta_name, $meta_value );
            return $order_items["item_meta"] => $new_meta->meta;' ) );

        return $apikey;
    }
    else return false;
}

}

5
Austin Passy

Ich habe es dir auf Twitter geschickt, aber hier ist es wieder.

Ich habe diese kleine Klasse erstellt, um XML-RPC schneller zu machen.

abstract class MZAXMLRPC {
    protected $calls = Array();
    protected $namespace = "myxmlrpc";

    function __construct($namespace){
        $this->namespace = $namespace;
        $reflector = new ReflectionClass($this);
        foreach ( $reflector->getMethods(ReflectionMethod::IS_PUBLIC) as $method){
            if ($method->isUserDefined() && $method->getDeclaringClass()->name != get_class()){
                $this->calls[] = $method->name;
            }
        }
        add_filter('xmlrpc_methods', array($this, 'xmlrpc_methods'));
    }

    public function xmlrpc_methods($methods)
    {
        foreach ($this->calls as $call){
            $methods[$this->namespace . "." . $call] = array($this, "dispatch");
        }
        return $methods;
    }

    public function dispatch($args){
        global $wp_xmlrpc_server;

        $username   = $args[1];
        $password   = $args[2];
        $data = $args[3];

        if ( !$wp_xmlrpc_server->login($username, $password) )
            return $wp_xmlrpc_server->error;

        $call = $this->get_called_method();

        if (method_exists($this, $call)){
            $status = call_user_func_array(array($this, $call), array($data));
            return $status;
        }else{
            return "Method not allowed";
        }

    }

    private function get_called_method(){
        global $wp_xmlrpc_server;
        $call = $wp_xmlrpc_server->message->methodName;
        $pieces = explode(".", $call);
        return $pieces[1];
    }

}

Dies ist eine abstrakte Klasse. Sie werden keine Objekte daraus instanziieren. Sie erstellen eine neue Klasse, die von MZAXMLRPC erbt, und stellen darin öffentliche Methoden für jeden XML-RPC-Aufruf bereit, den Sie verfügbar machen möchten.

Der Konstruktor verwendet Reflection, um alle benutzerdefinierten öffentlichen Methoden der untergeordneten Klasse zu finden, die von ihr erbt. Dann wird WordPress mitgeteilt, dass wir XML-RPC-Aufrufe für diese Methoden akzeptieren. Die XML-RPC-Methoden werden mit dem Namen $ Namespace. $ Public_method_name verfügbar gemacht.

Alle diese neuen XML-RPCs werden auf dieselbe Weise versendet. Diese Methode validiert zuerst den Benutzer/Pass für den Remote-Aufruf und prüft dann, ob tatsächlich eine Methode deklariert ist, die den XML-RPC-Aufruf erledigt. Wenn alles ok ist, wird der Aufruf an die entsprechende Methode der untergeordneten Klasse weitergeleitet, wobei alle Daten weitergeleitet werden, die über den XML-RPC-Server eingegangen sind.

Genug Kauderwelsch schon! Das einzige, was Sie tun müssen, ist:

class MY_XMLRPC extends MZAXMLRPC{

    public function QuoteUpload($data){

        if (!isset($data["author"]))
            return "Missing 'author' parameter";

        if (!isset($data["quote"]))
            return "Missing 'quote' parameter";

        $author = $data["author"];
        $quote = $data["quote"];

        $new_post = array(
            'post_status' => 'publish',
            'post_type' => 'mzaquotes',
            'post_title' => $quote
        );

        $new_post_id = wp_insert_post($new_post);
        wp_set_post_terms( $new_post_id, $author, 'quote_author' );

        return "OK";
    }
}

new MY_XMLRPC('my_function');

Dieses kleine Stück Code wird eine XML-RPC-Methode mit dem Namen my_function.QuoteUpload verfügbar machen. Die übergeordnete Klasse kümmert sich für Sie um die Authentifizierung und die WordPress-APIs.

1
MZAweb

An Ihrem Code sieht nichts falsch aus. Sie fügen den XMLRPC-Endpunkt definitiv korrekt hinzu. Das einzige Problem, das ich sehe, ist mit diesem Code:

 if ( isset( $match ) && $match ) {
    /* woocommerce/admin/writepanels/writepanel-order_data.php */
    add_filter( 'update_order_item', create_function( '$order_items', '
        $new_meta   = &new order_item_meta();
        $meta_name  = "active_urls";
        $meta_value = esc_url( $url );

        $new_meta->add( $meta_name, $meta_value );
        return $order_items["item_meta"] => $new_meta->meta;' ) );

    return $apikey;
}

Es kann sein, dass ich WooCommerce nicht gut genug kenne ... aber Sie sollten hier eine Funktion aufrufen, ohne einen Filter hinzuzufügen. Ihr Code wird nur angewendet, wenn der Filter aktiviert ist. In einer typischen XMLRPC-Anforderung wird dies nicht der Fall sein.

0
EAMann