'Blogger API', '%metaweblogAPI' => 'MetaWeblog API', '%moveabletype' => 'Moveable Type API')); 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, NULL, NULL, true)), '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, NULL, NULL, true), '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("$blog->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('edit own blog')) { return $user; } else { return message_access(); } } else { return t('Wrong username or password.'); } } function blogapi_blogger_title(&$contents) { if (eregi("([^<]*)", $contents, $title)) { $title = strip_tags($title[0]); $contents = ereg_replace("[^<]*", "", $contents); } else { list($title, $rest) = explode("\n", $contents, 2); } return $title; } ?>