367 lines
13 KiB
Plaintext
367 lines
13 KiB
Plaintext
<?php
|
|
|
|
// $Id$
|
|
|
|
function blogapi_help($section) {
|
|
switch ($section) {
|
|
case 'admin/help#blogapi':
|
|
return t('This module adds support for several XML-RPC based blogging APIs. Specifically, it currently implements the %bloggerAPI, %metaweblogAPI, and most of the %moveabletype extensions. This allows users to contribute to drupal using external GUI applications, which can often offer richer functionality that online forms based editing', array('%bloggerAPI' => '<a href="http://www.blogger.com/developers/api/1_docs/">Blogger API</a>', '%metaweblogAPI' => '<a href="http://www.xmlrpc.com/metaWeblogApi">MetaWeblog API</a>', '%moveabletype' => '<a href="http://www.movabletype.org/docs/mtmanual_programmatic.html">Moveable Type API</a>'));
|
|
case 'admin/system/modules#description':
|
|
return t('Enable users to post using applications that support XML-RPC blog APIs');
|
|
}
|
|
}
|
|
|
|
function blogapi_xmlrpc() {
|
|
$methods = array('blogger.getUsersBlogs' => array('function' => 'blogapi_get_users_blogs'),
|
|
'blogger.getUserInfo' => array('function' => 'blogapi_get_user_info'),
|
|
'blogger.newPost' => array('function' => 'blogapi_new_post'),
|
|
'blogger.editPost' => array('function' => 'blogapi_edit_post'),
|
|
'blogger.deletePost' => array('function' => 'blogapi_delete_post'),
|
|
'blogger.getRecentPosts' => array('function' => 'blogapi_get_recent_posts'),
|
|
'metaWeblog.newPost' => array('function' => 'blogapi_new_post'),
|
|
'metaWeblog.editPost' => array('function' => 'blogapi_edit_post'),
|
|
'metaWeblog.getPost' => array('function' => 'blogapi_get_post'),
|
|
'metaWeblog.newMediaObject' => array('function' => 'blogapi_new_media_object'),
|
|
'metaWeblog.getCategories' => array('function' => 'blogapi_get_categories'),
|
|
'metaWeblog.getRecentPosts' => array('function' => 'blogapi_get_recent_posts'),
|
|
'mt.getCategoryList' => array('function' => 'blogapi_get_category_list'),
|
|
'mt.getPostCategories' => array('function' => 'blogapi_get_post_categories'),
|
|
'mt.setPostCategories' => array('function' => 'blogapi_set_post_categories')
|
|
);
|
|
|
|
return $methods;
|
|
}
|
|
|
|
/** api functions */
|
|
|
|
function blogapi_get_users_blogs($req_params) {
|
|
$params = blogapi_convert($req_params);
|
|
// Remove unused appkey from bloggerAPI.
|
|
if (count($params) == 6) {
|
|
$params = array_slice($params, 1);
|
|
}
|
|
|
|
$user = blogapi_validate_user($params[1], $params[2]);
|
|
if ($user->uid) {
|
|
$struct = new xmlrpcval(array('url' => new xmlrpcval(url('blog/' . $user->uid)),
|
|
'blogid' => new xmlrpcval($user->uid),
|
|
'blogName' => new xmlrpcval($user->name . "'s blog")),
|
|
'struct');
|
|
$resp = new xmlrpcval(array($struct), "array");
|
|
return new xmlrpcresp($resp);
|
|
}
|
|
else {
|
|
return blogapi_error($user);
|
|
}
|
|
}
|
|
|
|
function blogapi_get_user_info($req_params) {
|
|
$params = blogapi_convert($req_params);
|
|
|
|
$user = blogapi_validate_user($params[1], $params[2]);
|
|
|
|
if ($user->uid) {
|
|
$name = explode(' ', $user->realname ? $user->realname : $user->name, 2);
|
|
$struct = new xmlrpcval(array('userid' => new xmlrpcval($user->uid, 'string'),
|
|
'lastname' => new xmlrpcval($name[1], 'string'),
|
|
'firstname' => new xmlrpcval($name[0], 'string'),
|
|
'nickname' => new xmlrpcval($user->name, 'string'),
|
|
'email' => new xmlrpcval($user->mail, 'string'),
|
|
'url' => new xmlrpcval(url('blog/view/' . $user->uid), 'string')),
|
|
'struct');
|
|
return new xmlrpcresp($struct);
|
|
}
|
|
else {
|
|
return blogapi_error($user);
|
|
}
|
|
}
|
|
|
|
function blogapi_new_post($req_params) {
|
|
$params = blogapi_convert($req_params);
|
|
|
|
// Remove unused appkey from bloggerAPI.
|
|
if (count($params) == 6) {
|
|
$params = array_slice($params, 1);
|
|
}
|
|
|
|
$user = blogapi_validate_user($params[1], $params[2]);
|
|
if (!$user->uid) {
|
|
return blogapi_error($user);
|
|
}
|
|
|
|
$promote = variable_get("node_promote_blog", 0);
|
|
$comment = variable_get("node_comment_blog", 2);
|
|
$moderate = variable_get("node_moderate_blog", 0);
|
|
$revision = variable_get("node_revision_blog", 0);
|
|
|
|
// check for bloggerAPI vs. metaWeblogAPI
|
|
if (is_array($params[3])) {
|
|
$title = $params[3]['title'];
|
|
$body = $params[3]['description'];
|
|
}
|
|
else {
|
|
$title = blogapi_blogger_title($params[3]);
|
|
$body = $params[3];
|
|
}
|
|
|
|
if (!valid_input_data($title, $body)) {
|
|
return blogapi_error(t("Terminated request because of suspicious input data."));
|
|
}
|
|
|
|
$node = node_validate(array('type' => 'blog',
|
|
'uid' => $user->uid,
|
|
'name' => $user->name,
|
|
'title' => $title,
|
|
'body' => $body,
|
|
'status' => $params[4],
|
|
'promote' => $promote,
|
|
'comment' => $comment,
|
|
'moderate' => $moderate,
|
|
'revision' => $revision
|
|
), $error);
|
|
|
|
if (count($error) > 0) {
|
|
return blogapi_error($error);
|
|
}
|
|
|
|
if (!node_access("create", $node)) {
|
|
return blogapi_error(message_access());
|
|
}
|
|
|
|
$nid = node_save($node);
|
|
if ($nid) {
|
|
watchdog("special", "$node->type: added '$node->title' using blog API", l(t("view post"), "node/view/$nid"));
|
|
return new xmlrpcresp(new xmlrpcval($nid, 'string'));
|
|
}
|
|
|
|
return blogapi_error(t('error storing post'));
|
|
}
|
|
|
|
function blogapi_edit_post($req_params) {
|
|
$params = blogapi_convert($req_params);
|
|
if (count($params) == 6) {
|
|
$params = array_slice($params, 1);
|
|
}
|
|
|
|
$user = blogapi_validate_user($params[1], $params[2]);
|
|
|
|
if (!$user->uid) {
|
|
return blogapi_error($user);
|
|
}
|
|
|
|
$node = node_load(array('nid' => $params[0]));
|
|
if (!$node) {
|
|
return blogapi_error(message_na());
|
|
}
|
|
|
|
if (!node_access('update', $node)) {
|
|
return blogapi_error(message_access());
|
|
}
|
|
|
|
// check for bloggerAPI vs. metaWeblogAPI
|
|
if (is_array($params[3])) {
|
|
$title = $params[3]['title'];
|
|
$body = $params[3]['description'];
|
|
}
|
|
else {
|
|
$title = blogapi_blogger_title($params[3]);
|
|
$body = $params[3];
|
|
}
|
|
|
|
if (!valid_input_data($title, $body)) {
|
|
return blogapi_error(t("Terminated request because of suspicious input data."));
|
|
}
|
|
|
|
$node->title = $title;
|
|
$node->body = $body;
|
|
$node->status = $params[4];
|
|
$node = node_validate($node, $error);
|
|
|
|
if (count($error) > 0) {
|
|
return blogapi_error($error);
|
|
}
|
|
|
|
$terms = module_invoke('taxonomy', 'node_get_terms', $node->nid, 'tid');
|
|
foreach ($terms as $term) {
|
|
$node->taxonomy[] = $term->tid;
|
|
}
|
|
$nid = node_save($node);
|
|
if ($nid) {
|
|
watchdog("special", "$node->type: updated '$node->title' using blog API", l(t("view post"), "node/view/$nid"));
|
|
return new xmlrpcresp(new xmlrpcval(true, "boolean"));
|
|
}
|
|
|
|
return blogapi_error(t('error storing node'));
|
|
}
|
|
|
|
function blogapi_get_post($req_params) {
|
|
$params = blogapi_convert($req_params);
|
|
$user = blogapi_validate_user($params[1], $params[2]);
|
|
if (!$user->uid) {
|
|
return blogapi_error($user);
|
|
}
|
|
|
|
$node = node_load(array('nid' => $params[0]));
|
|
$blog = new xmlrpcval(array('userid' => new xmlrpcval($node->name, 'string'),
|
|
'dateCreated' => new xmlrpcval(iso8601_encode($node->created), "dateTime.iso8601"),
|
|
'title' => new xmlrpcval($node->title, 'string'),
|
|
'description' => new xmlrpcval($node->body, 'string'),
|
|
'postid' => new xmlrpcval($node->nid, 'string')),
|
|
'struct');
|
|
|
|
return new xmlrpcresp($blog);
|
|
}
|
|
|
|
function blogapi_delete_post($req_params) {
|
|
$params = blogapi_convert($req_params);
|
|
|
|
$user = blogapi_validate_user($params[2], $params[3]);
|
|
if (!$user->uid) {
|
|
return blogapi_error($user);
|
|
}
|
|
|
|
$ret = node_delete(array('nid' => $params[1], 'confirm' => 1));
|
|
return new xmlrpcresp(new xmlrpcval(true, "boolean"));
|
|
}
|
|
|
|
function blogapi_new_media_object($req_params) {
|
|
return blogapi_error('not implemented');
|
|
}
|
|
|
|
function blogapi_get_category_list($req_params) {
|
|
$vocabularies = module_invoke('taxonomy', 'get_vocabularies', 'blog', 'vid');
|
|
$categories = array();
|
|
if ($vocabularies) {
|
|
foreach ($vocabularies as $vocabulary) {
|
|
$terms = module_invoke('taxonomy', 'get_tree', $vocabulary->vid, 0, -1, 'tid');
|
|
foreach ($terms as $term) {
|
|
$term_name = $term->name;
|
|
foreach (module_invoke('taxonomy', 'get_parents', $term->tid, 'tid') as $parent) {
|
|
$term_name = $parent->name . '/' . $term_name;
|
|
}
|
|
$categories[] = new xmlrpcval(array('categoryName' => new xmlrpcval($term_name, 'string'),
|
|
'categoryId' => new xmlrpcval($term->tid, 'string')),
|
|
'struct');
|
|
}
|
|
}
|
|
}
|
|
return new xmlrpcresp(new xmlrpcval($categories, "array"));
|
|
}
|
|
|
|
function blogapi_get_post_categories($req_params) {
|
|
$params = blogapi_convert($req_params);
|
|
$user = blogapi_validate_user($params[1], $params[2]);
|
|
if (!$user->uid) {
|
|
return blogapi_error($user);
|
|
}
|
|
|
|
$terms = module_invoke('taxonomy', 'node_get_terms', $params[0], 'tid');
|
|
$categories = array();
|
|
foreach ($terms as $term) {
|
|
$term_name = $term->name;
|
|
foreach (module_invoke('taxonomy', 'get_parents', $term->tid, 'tid') as $parent) {
|
|
$term_name = $parent->name . '/' . $term_name;
|
|
}
|
|
$categories[] = new xmlrpcval(array('categoryName' => new xmlrpcval($term_name, 'string'),
|
|
'categoryId' => new xmlrpcval($term->tid, 'string'),
|
|
'isPrimary' => new xmlrpcval(true, 'boolean')),
|
|
'struct');
|
|
}
|
|
return new xmlrpcresp(new xmlrpcval($categories, "array"));
|
|
}
|
|
|
|
function blogapi_set_post_categories($req_params) {
|
|
$params = blogapi_convert($req_params);
|
|
$user = blogapi_validate_user($params[1], $params[2]);
|
|
if (!$user->uid) {
|
|
return blogapi_error($user);
|
|
}
|
|
|
|
$nid = $params[0];
|
|
$terms = array();
|
|
foreach ($params[3] as $category) {
|
|
$terms[] = $category['categoryId']->scalarval();
|
|
}
|
|
module_invoke('taxonomy', 'node_save', $nid, $terms);
|
|
return new xmlrpcresp(new xmlrpcval(true, 'boolean'));
|
|
}
|
|
|
|
function blogapi_get_recent_posts($req_params) {
|
|
$params = blogapi_convert($req_params);
|
|
|
|
// Remove unused appkey (from bloggerAPI).
|
|
if (count($params) == 5) {
|
|
$params = array_slice($params, 1);
|
|
}
|
|
$user = blogapi_validate_user($params[1], $params[2]);
|
|
if (!$user->uid) {
|
|
return blogapi_error($user);
|
|
}
|
|
|
|
$result = db_query_range("SELECT n.nid, n.title, n.body, n.created, u.name FROM {node} n, {users} u WHERE n.uid=u.uid AND n.type = 'blog' AND n.uid = %d ORDER BY n.created DESC", $user->uid, 0, $params[3]);
|
|
while ($blog = db_fetch_object($result)) {
|
|
$blogs[] = new xmlrpcval(array('userid' => new xmlrpcval($blog->name, 'string'),
|
|
'dateCreated' => new xmlrpcval(iso8601_encode($blog->created), "dateTime.iso8601"),
|
|
'content' => new xmlrpcval("<title>$blog->title</title>$blog->body", 'string'),
|
|
'title' => new xmlrpcval($blog->title, 'string'),
|
|
'description' => new xmlrpcval($blog->body, 'string'),
|
|
'postid' => new xmlrpcval($blog->nid, 'string')),
|
|
'struct');
|
|
}
|
|
return new xmlrpcresp(new xmlrpcval($blogs, "array"));
|
|
}
|
|
|
|
/** helper functions */
|
|
|
|
function blogapi_convert($params) {
|
|
$cparams = array();
|
|
$num_params= $params->getNumParams();
|
|
|
|
for ($i = 0; $i < $num_params; $i++) {
|
|
$sn = $params->getParam($i);
|
|
$cparams[] = $sn->getval();
|
|
}
|
|
|
|
return $cparams;
|
|
}
|
|
|
|
function blogapi_error($message) {
|
|
global $xmlrpcusererr;
|
|
|
|
if (is_array($message)) {
|
|
$message = implode('', $message);
|
|
}
|
|
|
|
return new xmlrpcresp(0, $xmlrpcusererr + 1, strip_tags($message));
|
|
}
|
|
|
|
function blogapi_validate_user($username, $password) {
|
|
global $user;
|
|
|
|
$user = user_load(array('name' => $username, 'pass' => $password, 'status' => 1));
|
|
|
|
if ($user->uid) {
|
|
if (user_access('maintain personal blog')) {
|
|
return $user;
|
|
}
|
|
else {
|
|
return message_access();
|
|
}
|
|
}
|
|
else {
|
|
return t('Wrong username or password.');
|
|
}
|
|
}
|
|
|
|
function blogapi_blogger_title(&$contents) {
|
|
if (eregi("<title>([^<]*)</title>", $contents, $title)) {
|
|
$title = strip_tags($title[0]);
|
|
$contents = ereg_replace("<title>[^<]*</title>", "", $contents);
|
|
}
|
|
else {
|
|
list($title, $rest) = explode("\n", $contents, 2);
|
|
}
|
|
return $title;
|
|
}
|
|
?>
|