Search code examples
wordpressfile-uploadxml-rpc

Conditionally change upload directory on XMLRPC call according to username


I've searched seemingly every relevant question on this but I'm stuck, as none of them address the particular case of uploads through XML RPC.

I want to conditionally change the Wordpress file upload directory, only if the file is coming in through an XML RPC call and only if the call is coming in from a particular user.

My approach is based on a combination of this Answer, this Answer and the Codex.

Here's what I tried with no luck:

    add_filter( 'xmlrpc_methods', 'call_intercept1' );
    function call_intercept1( $methods ) {

    $methods[ 'metaWeblog.newMediaObject' ] = 'custom_upload1';

    return $methods;}

function custom_upload1( $args ) {
    global $wpdb;

        $username = $this->escape( $args[1] );
        $password = $this->escape( $args[2] );
        $data     = $args[3];

        $name = sanitize_file_name( $data['name'] );
        $type = $data['type'];
        $bits = $data['bits'];

    if ( !$user = $this->login($username, $password) )
            return $this->error;

    if ( $username = "XXX" ) {
    add_filter('upload_dir', 'custom_upload_dir1');

}
$upload = wp_upload_bits($name, null, $bits);
        if ( ! empty($upload['error']) ) {
            /* translators: 1: file name, 2: error message */
            $errorString = sprintf( __( 'Could not write file %1$s (%2$s).' ), $name, $upload['error'] );
            return new IXR_Error( 500, $errorString );
            }
    return $upload;
}

function custom_upload_dir1( $param ){
    $custom_dir = '/the-desired-directory';

    $param['path'] = $param['path'] . $custom_dir;
    $param['url'] = $param['url'] . $custom_dir;

    error_log("path={$param['path']}");  
    error_log("url={$param['url']}");
    error_log("subdir={$param['subdir']}");
    error_log("basedir={$param['basedir']}");
    error_log("baseurl={$param['baseurl']}");
    error_log("error={$param['error']}"); 

    return $param;
}

The file is being uploaded correctly, but the conditional directory change isn't happening.

Does someone know why that would be?


Solution

  • I was able to get this worked out, essentially using Ulf B's Custom Upload Dir as a model and simplifying it from there.

    For anyone else facing the same problem, here's what works:

        // XMLRPC Conditional Upload Directory
        add_action('xmlrpc_call', 'redirect_xmlrpc_call'); 
    
        function redirect_xmlrpc_call($call){
            if($call !== 'metaWeblog.newMediaObject'){return;}      
            global $wp_xmlrpc_server; 
            $username = $wp_xmlrpc_server->message->params[1];
            $data = $wp_xmlrpc_server->message->params[3];
            if($username !== "XXX"){return;}
            else {custom_pre_upload($data);}}
    
        function custom_pre_upload($data){  
            add_filter('upload_dir', 'custom_upload_dir');
            return $data;}
    
        function custom_post_upload($fileinfo){ 
            remove_filter('upload_dir', 'custom_upload_dir');
            return $fileinfo;}
    
        function custom_upload_dir($path){      
            if(!empty($path['error'])) { return $path; } //error; do nothing.   
            $customdir = '/' . 'your-directory-name';   
            $path['subdir']  = $customdir;
            $path['path']   .= $customdir; 
            $path['url']    .= $customdir;  
            return $path;}