diff --git a/xmlrpc.php b/xmlrpc.php index ee05245dd..0bd9a4ef7 100644 --- a/xmlrpc.php +++ b/xmlrpc.php @@ -67,6 +67,18 @@ class wp_xmlrpc_server extends IXR_Server { function wp_xmlrpc_server() { $this->methods = array( + // WordPress API + 'wp.getPage' => 'this:wp_getPage', + 'wp.getPages' => 'this:wp_getPages', + 'wp.newPage' => 'this:wp_newPage', + 'wp.deletePage' => 'this:wp_deletePage', + 'wp.editPage' => 'this:wp_editPage', + 'wp.getPageList' => 'this:wp_getPageList', + 'wp.getAuthors' => 'this:wp_getAuthors', + 'wp.getCategories' => 'this:mw_getCategories', // Alias + 'wp.newCategory' => 'this:wp_newCategory', + 'wp.suggestCategories' => 'this:wp_suggestCategories', + // Blogger API 'blogger.getUsersBlogs' => 'this:blogger_getUsersBlogs', 'blogger.getUserInfo' => 'this:blogger_getUserInfo', @@ -146,6 +158,388 @@ class wp_xmlrpc_server extends IXR_Server { } } + /** + * WordPress XML-RPC API + * wp_getPage + */ + function wp_getPage($args) { + $this->escape($args); + + $blog_id = $args[0]; + $page_id = $args[1]; + $username = $args[2]; + $password = $args[3]; + + if(!$this->login_pass_ok($username, $password)) { + return($this->error); + } + + // Lookup page info. + $page = get_page($page_id); + + // If we found the page then format the data. + if($page->ID && ($page->post_type == "page")) { + // Get all of the page content and link. + $full_page = get_extended($page->post_content); + $link = post_permalink($page->ID); + + // Determine comment and ping settings. + $allow_comments = ("open" == $page->comment_status) ? 1 : 0; + $allow_pings = ("open" == $page->ping_status) ? 1 : 0; + + // Format page date. + $page_date = mysql2date("Ymd\TH:i:s", $page->post_date); + + // Pull the categories info together. + $categories = array(); + foreach(wp_get_post_categories($page->ID) as $cat_id) { + $categories[] = get_cat_name($cat_id); + } + + // Get the users nicename. + $nicename = get_profile("user_nicename", $username); + + $page_struct = array( + "dateCreated" => new IXR_Date($page_date), + "userid" => $page->post_author, + "page_id" => $page->ID, + "description" => $full_page["main"], + "title" => $page->post_title, + "link" => $link, + "permaLink" => $link, + "categories" => $categories, + "excerpt" => $page->post_excerpt, + "text_more" => $full_page["extended"], + "mt_allow_comments" => $allow_comments, + "mt_allow_pings" => $allow_pings, + "wp_slug" => $page->post_name, + "wp_password" => $page->post_password, + "wp_author" => $nicename, + "wp_page_parent_id" => $page->post_parent, + "wp_page_order" => $page->menu_order + ); + + return($page_struct); + } + // If the page doesn't exist indicate that. + else { + return(new IXR_Error(404, "Sorry, no such page.")); + } + } + + /** + * WordPress XML-RPC API + * wp_getPages + */ + function wp_getPages($args) { + $this->escape($args); + + $blog_id = $args[0]; + $username = $args[1]; + $password = $args[2]; + + if(!$this->login_pass_ok($username, $password)) { + return($this->error); + } + + // Lookup info on pages. + $pages = array(); + $pages = get_pages(); + $num_pages = count($pages); + + // If we have pages, put together their info. + if($num_pages >= 1) { + $pages_struct = array(); + + for($i = 0; $i < $num_pages; $i++) { + $page = wp_xmlrpc_server::wp_getPage(array( + $blog_id, $pages[$i]->ID, $username, $password + )); + $pages_struct[] = $page; + } + + return($pages_struct); + } + // If no pages were found return an error. + else { + return(new IXR_Error(404, "Sorry, no pages were found.")); + } + } + + /** + * WordPress XML-RPC API + * wp_newPage + */ + function wp_newPage($args) { + $this->escape($args); + + $blog_id = $args[0]; + $username = $args[1]; + $password = $args[2]; + $page = $args[3]; + $publish = $args[4]; + + if(!$this->login_pass_ok($username, $password)) { + return($this->error); + } + + // Set the user context and check if they are allowed + // to add new pages. + $user = set_current_user(0, $username); + if(!current_user_can("publish_pages")) { + return(new IXR_Error(401, "Sorry, you can not add new pages.")); + } + + // Mark this as content for a page. + $args[3]["post_type"] = "page"; + + // Let mw_newPost do all of the heavy lifting. + return($this->mw_newPost($args)); + } + + /** + * WordPress XML-RPC API + * wp_deletePage + */ + function wp_deletePage($args) { + $this->escape($args); + + $blog_id = $args[0]; + $username = $args[1]; + $password = $args[2]; + $page_id = $args[3]; + + if(!$this->login_pass_ok($username, $password)) { + return($this->error); + } + + // Get the current page based on the page_id and + // make sure it is a page and not a post. + $actual_page = wp_get_single_post($page_id, ARRAY_A); + if( + !$actual_page + || ($actual_page["post_type"] != "page") + ) { + return(new IXR_Error(404, "Sorry, no such page.")); + } + + // Set the user context and make sure they can delete pages. + set_current_user(0, $username); + if(!current_user_can("delete_page", $page_id)) { + return(new IXR_Error(401, "Sorry, you do not have the right to delete this page.")); + } + + // Attempt to delete the page. + $result = wp_delete_post($page_id); + if(!$result) { + return(new IXR_Error(500, "Failed to delete the page.")); + } + + return(true); + } + + /** + * WordPress XML-RPC API + * wp_editPage + */ + function wp_editPage($args) { + $this->escape($args); + + $blog_id = $args[0]; + $page_id = $args[1]; + $username = $args[2]; + $password = $args[3]; + $content = $args[4]; + $publish = $args[5]; + + if(!$this->login_pass_ok($username, $password)) { + return($this->error); + } + + // Get the page data and make sure it is a page. + $actual_page = wp_get_single_post($page_id, ARRAY_A); + if( + !$actual_page + || ($actual_page["post_type"] != "page") + ) { + return(new IXR_Error(404, "Sorry, no such page.")); + } + + // Set the user context and make sure they are allowed to edit pages. + set_current_user(0, $username); + if(!current_user_can("edit_page", $page_id)) { + return(new IXR_Error(401, "Sorry, you do not have the right to edit this page.")); + } + + // Mark this as content for a page. + $content["post_type"] = "page"; + + // Arrange args in the way mw_editPost understands. + $args = array( + $page_id, + $username, + $password, + $content, + $publish + ); + + // Let mw_editPost do all of the heavy lifting. + return($this->mw_editPost($args)); + } + + /** + * WordPress XML-RPC API + * wp_getPageList + */ + function wp_getPageList($args) { + global $wpdb; + + $this->escape($args); + + $blog_id = $args[0]; + $username = $args[1]; + $password = $args[2]; + + if(!$this->login_pass_ok($username, $password)) { + return($this->error); + } + + // Get list of pages ids and titles + $page_list = $wpdb->get_results(" + SELECT ID page_id, + post_title page_title + FROM {$wpdb->posts} + WHERE post_type = 'page' + ORDER BY ID + "); + + return($page_list); + } + + /** + * WordPress XML-RPC API + * wp_getAuthors + */ + function wp_getAuthors($args) { + global $wpdb; + + $this->escape($args); + + $blog_id = $args[0]; + $username = $args[1]; + $password = $args[2]; + + if(!$this->login_pass_ok($username, $password)) { + return($this->error); + } + + // Get basic info on all users. + $all_users = $wpdb->get_results(" + SELECT u.ID id, + u.user_login username + FROM {$wpdb->users} u + ORDER BY u.user_login + "); + + return($all_users); + } + + /** + * WordPress XML-RPC API + * wp_newCategory + */ + function wp_newCategory($args) { + $this->escape($args); + + $blog_id = $args[0]; + $username = $args[1]; + $password = $args[2]; + $category = $args[3]; + + if(!$this->login_pass_ok($username, $password)) { + return($this->error); + } + + // Set the user context and make sure they are + // allowed to add a category. + set_current_user(0, $username); + if(!current_user_can("manage_categories", $page_id)) { + return(new IXR_Error(401, "Sorry, you do not have the right to add a category.")); + } + + // We need this to make use of the wp_insert_category() + // funciton. + require_once(ABSPATH . "wp-admin/admin-db.php"); + + // If no slug was provided make it empty so that + // WordPress will generate one. + if(empty($category["slug"])) { + $category["slug"] = ""; + } + + // If no parent_id was provided make it empty + // so that it will be a top level page (no parent). + if(empty($category["parent_id"])) { + $category["parent_id"] = ""; + } + + // If no description was provided make it empty. + if(empty($category["description"])) { + $category["description"] = ""; + } + + $new_category = array( + "cat_name" => $category["name"], + "category_nicename" => $category["slug"], + "category_parent" => $category["parent_id"], + "category_description" => $category["description"] + ); + + $cat_id = wp_insert_category($new_category); + if(!$cat_id) { + return(new IXR_Error(500, "Sorry, the new category failed.")); + } + + return($cat_id); + } + + /** + * WordPress XML-RPC API + * wp_suggestCategories + */ + function wp_suggestCategories($args) { + global $wpdb; + + $this->escape($args); + + $blog_id = $args[0]; + $username = $args[1]; + $password = $args[2]; + $category = $args[3]; + $max_results = $args[4]; + + if(!$this->login_pass_ok($username, $password)) { + return($this->error); + } + + // Only set a limit if one was provided. + $limit = ""; + if(!empty($max_results)) { + $limit = "LIMIT {$max_results}"; + } + + $category_suggestions = $wpdb->get_results(" + SELECT cat_ID category_id, + cat_name category_name + FROM {$wpdb->categories} + WHERE cat_name LIKE '{$category}%' + {$limit} + "); + + return($category_suggestions); + } + + /* Blogger API functions * specs on http://plant.blogger.com/api and http://groups.yahoo.com/group/bloggerDev/ */ @@ -514,6 +908,37 @@ class wp_xmlrpc_server extends IXR_Server { if ( !current_user_can('publish_posts') ) return new IXR_Error(401, 'Sorry, you can not post on this weblog or category.'); + // The post_type defaults to post, but could also be page. + $post_type = "post"; + if( + !empty($content_struct["post_type"]) + && ($content_struct["post_type"] == "page") + ) { + $post_type = "page"; + } + + // Let WordPress generate the post_name (slug) unless + // one has been provided. + $post_name = ""; + if(!empty($content_struct["wp_slug"])) { + $post_name = $content_struct["wp_slug"]; + } + + // Only use a password if one was given. + if(!empty($content_struct["wp_password"])) { + $post_password = $content_struct["wp_password"]; + } + + // Only set a post parent if one was provided. + if(!empty($content_struct["wp_page_parent_id"])) { + $post_parent = $content_struct["wp_page_parent_id"]; + } + + // Only set the menu_order if it was provided. + if(!empty($content_struct["wp_page_order"])) { + $menu_order = $content_struct["wp_page_order"]; + } + $post_author = $user->ID; $post_title = $content_struct['title']; @@ -559,7 +984,7 @@ class wp_xmlrpc_server extends IXR_Server { } // We've got all the data -- post it: - $postdata = compact('post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt', 'comment_status', 'ping_status', 'to_ping'); + $postdata = compact('post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt', 'comment_status', 'ping_status', 'to_ping', 'post_type', 'post_name', 'post_password', 'post_parent', 'menu_order'); $post_ID = wp_insert_post($postdata); @@ -613,6 +1038,36 @@ class wp_xmlrpc_server extends IXR_Server { extract($postdata); $this->escape($postdata); + // The post_type defaults to post, but could also be page. + $post_type = "post"; + if( + !empty($content_struct["post_type"]) + && ($content_struct["post_type"] == "page") + ) { + $post_type = "page"; + } + + // Let WordPress manage slug if none was provided. + $post_name = ""; + if(!empty($content_struct["wp_slug"])) { + $post_name = $content_struct["wp_slug"]; + } + + // Only use a password if one was given. + if(!empty($content_struct["wp_password"])) { + $post_password = $content_struct["wp_password"]; + } + + // Only set a post parent if one was given. + if(!empty($content_struct["wp_page_parent_id"])) { + $post_parent = $content_struct["wp_page_parent_id"]; + } + + // Only ste the menu_order if it was given. + if(!empty($content_struct["wp_page_order"])) { + $menu_order = $content_struct["wp_page_order"]; + } + $post_title = $content_struct['title']; $post_content = apply_filters( 'content_save_pre', $content_struct['description'] ); $catnames = $content_struct['categories']; @@ -655,7 +1110,7 @@ class wp_xmlrpc_server extends IXR_Server { } // We've got all the data -- post it: - $newpost = compact('ID', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt', 'comment_status', 'ping_status', 'post_date', 'post_date_gmt', 'to_ping'); + $newpost = compact('ID', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt', 'comment_status', 'ping_status', 'post_date', 'post_date_gmt', 'to_ping', 'post_name', 'post_password', 'post_parent', 'menu_order'); $result = wp_update_post($newpost); if (!$result) {