Implementing file support via XML-RPC for Kapost

If you are implementing "XML-RPC" support from scratch in your own custom CMS, before going any further, please consult the "Implementing XML-RPC for Kapost" guide by clicking here.

By exposing and implementing these methods, Kapost will be able to push individual files (i.e Word or PDF documents) to your CMS instance.

Once you exposed these methods on your XML-RPC endpoint, be sure to refresh the connection by hitting 'save' in order for Kapost to update its exposed method cache.

All methods are expected to throw XML-RPC compliant (appropriate) error messages in case of any errors.

WARNING: Kapost cannot debug any potential issues that can arise in your custom code, which can prevent Kapost from being able to successfully push content to your CMS instance.

Kapost provides a sample reference implementation for Wordpress. The provided code is NOT production ready, therefore please do not use it as such.

kapost.newFile (required)

kapost.newFile(blog_id=string, username=string, password=string, content=hash, publish=boolean)

The content hash contains at least the following:

{
    'title'     => 'hello',
    'mt_keywords'   => 'hello, world',
    'mt_excerpt'    => 'hello world excerpt',
    'categories'    => ['apples', 'oranges'],
    'custom_fields' => 
    [
        {'key' => 'custom_field_one', 'value' => 'value one'},
        {'key' => 'custom_field_two', 'value' => 'value two'}
    ],
    'name' => 'panda.pdf',
    'type' => 'application/pdf',
    'bits' => 'XYZYZ.........=='
}

blog_id = id of the current "blog", applicable if your CMS has multisite capabilities, otherwise you can ignore this parameter

name = filename of the file (with proper extension, no path)

type = standard MIME type (application/pdf)

bits = base64 encoded binary blob of the file

If the publish boolean is 'true', the file should be 'stored' as published, otherwise as draft.

Returns a string which is the 'internal file id' of the file that has been inserted into the database.

This 'internal file id' will be used later when calling kapost.editFile, kapost.getFile or kapost.getFilePermalink as illustrated below.

kapost.editFile (required)

kapost.editFile(file_id=string, username=string, password=string, content=hash, publish=boolean)

The content hash contains at least the following:

{
    'title'     => 'hello',
    'mt_keywords'   => 'hello, world',
    'mt_excerpt'    => 'hello world excerpt',
    'categories'    => ['apples', 'oranges'],
    'custom_fields' => 
    [
        {'key' => 'custom_field_one', 'value' => 'value one'},
        {'key' => 'custom_field_two', 'value' => 'value two'}
    ],
    'name' => 'panda.pdf',
    'type' => 'application/pdf',
    'bits' => 'XYZYZ.........=='
}

name = filename of the file (with proper extension, no path)

type = standard MIME type (application/pdf)

bits = base64 encoded binary blob of the file

If the publish boolean is 'true', the file should be 'stored' as published, otherwise as draft.

Returns a string which is the 'internal file id' of the file that has been inserted into/updated in the database. In most cases it will just return the file_id it received.

This 'internal file id' will be used later when calling kapost.getFile or kapost.getFilePermalink as illustrated below.

kapost.getFile (required)

kapost.getFile(file_id=string, username=string, password=string) 

Returns a hash with a least the following:

{
    'name'          => 'panda.pdf',
    'type'          => 'application/pdf',
    'permaLink'     => 'http://yourdomain.com/uploads/2017/01/panda.pdf', 
    'custom_fields' =>
    [
      {'id' => 'custom_field_id', 'key' => 'custom_field_one', 'value' => 'value one'},
      {'id' => 'custom_field_id', 'key' => 'custom_field_two', 'value' => 'value two'}
    ]
}

permaLink (case sensitive) = permalink to the given file

kapost.getFilePermalink (required)

kapost.getFilePermalink(file_id=string, username=string, password=string)

Returns the permalink to the given file as a string.

Reference Implementation

<?php
/*
  Plugin Name: Kapost XMLRPC Files Sample
  Plugin URI: http://www.kapost.com/
  Description: Kapost XMLRPC Files Sample
  Version: 1.0.0
  Author: Kapost
  Author URI: http://www.kapost.com
  License: Public Domain. No warranties expressed or implied. Use at your own risk.
*/
define('KAPOST_XMLRPC_FILES_SAMPLE_VERSION', '1.0.0');

function kapost_xmlrpc_files_sample_new_file($args)
{
  global $wp_xmlrpc_server;

  $_args = $args;
  $wp_xmlrpc_server->escape($_args);

  $blog_id  = intval($_args[0]);
  $username = $_args[1];
  $password = $_args[2];
  $data   = $_args[3];
  $publish  = $_args[4];

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

  if(!current_user_can('upload_files'))
    return new IXR_Error(401, __('You are not allowed to upload files to this site.'));

  $file = $wp_xmlrpc_server->mw_newMediaObject($args);

  if(is_array($file) && isset($file['id']))
    return (string) $file['id'];
  else
    return $file;
}

function kapost_xmlrpc_files_sample_edit_file($args)
{
  return kapost_xmlrpc_files_sample_new_file($args);
}

function kapost_xmlrpc_files_sample_get_file($args)
{
  global $wp_xmlrpc_server;

  $_args = $args;
  $wp_xmlrpc_server->escape($args);

  $post_id  = intval($_args[0]);
  $username = $_args[1];
  $password = $_args[2];

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

  if(!current_user_can('edit_post', $post_id))
    return new IXR_Error(401, __('Sorry, you cannot edit this post.'));

  $file = $wp_xmlrpc_server->mw_getPost($args);

  if(is_array($file) && isset($file['postid']))
    $file['permaLink'] = wp_get_attachment_url($post_id);

  return $file;
}

function kapost_xmlrpc_files_sample_get_file_permalink($args)
{
  global $wp_xmlrpc_server;
  $wp_xmlrpc_server->escape($args);

  $post_id  = intval($args[0]);
  $username = $args[1];
  $password = $args[2];

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

  if(!current_user_can('edit_post', $post_id))
    return new IXR_Error(401, __('Sorry, you cannot edit this post.'));

  $post = get_post($post_id);
  if(!is_object($post) || !isset($post->ID))
    return new IXR_Error(401, __('Sorry, you cannot edit this post.'));

  return wp_get_attachment_url($post_id);
}

function kapost_xmlrpc_patch_methods($methods)
{
  $methods['kapost.newFile']    = 'kapost_xmlrpc_files_sample_new_file';
  $methods['kapost.editFile']   = 'kapost_xmlrpc_files_sample_edit_file';
  $methods['kapost.getFile']    = 'kapost_xmlrpc_files_sample_get_file';
  $methods['kapost.getFilePermalink']   = 'kapost_xmlrpc_files_sample_get_file_permalink';
  return $methods;
}
add_filter('xmlrpc_methods', 'kapost_xmlrpc_patch_methods');
?>