diff options
Diffstat (limited to 'xmlrpc.php')
-rw-r--r-- | xmlrpc.php | 246 |
1 files changed, 190 insertions, 56 deletions
@@ -9,6 +9,13 @@ if(empty($request_xml)) { exit('XML-RPC server accepts POST requests only.'); } // load config require_once(__DIR__.DIRECTORY_SEPARATOR.'config.php'); +if(!function_exists('str_starts_with')) { + function str_starts_with($haystack, $needle) { + if(empty($needle)) return true; + return mb_substr($haystack, 0, mb_strlen($needle)) === $needle; + } +} + function check_credentials($username, $password) { global $config; @@ -28,16 +35,17 @@ function say_hello($method_name, $args) { return 'Hello'; } -function mw_make_post($post) { +function make_post($post, $method='metaWeblog') { global $config; $date_created = date('Y-m-d\TH:i:s', $post['post_timestamp']).$config['local_time_offset']; $date_created_gmt = gmdate('Y-m-d\TH:i:s', $post['post_timestamp']).'Z'; - if(!empty($post['post_edited']) && $post['post_edited'] > 0) { + if(!empty($post['post_edited']) && !is_null($post['post_edited'])) { $date_modified = date('Y-m-d\TH:i:s', $post['post_edited']).$config['local_time_offset']; $date_modified_gmt = gmdate('Y-m-d\TH:i:s', $post['post_edited']).'Z'; } else { $date_modified = date('Y-m-d\TH:i:s', 0).$config['local_time_offset']; + $date_modified = null; $date_modified_gmt = gmdate('Y-m-d\TH:i:s', 0).'Z'; } @@ -46,31 +54,57 @@ function mw_make_post($post) { @xmlrpc_set_type($date_modified, 'datetime'); @xmlrpc_set_type($date_modified_gmt, 'datetime'); - // convert the post format to a standard metaWeblog post - $mw_post = [ - 'postid' => (int) $post['id'], - 'title' => '', - 'description' => ($post['post_content']), // Post content - 'link' => $config['url'].'/'.$post['id'], // Post URL - // string userid†: ID of post author. - 'dateCreated' => $date_created, - 'date_created_gmt' => $date_created_gmt, - 'date_modified' => $date_modified, - 'date_modified_gmt' => $date_modified_gmt, - // string wp_post_thumbnail† - 'permalink' => $config['url'].'/'.$post['id'], // Post URL, equivalent to link. - 'categories' => [], // Names of categories assigned to the post. - 'mt_keywords' => '', // Names of tags assigned to the post. - 'mt_excerpt' => '', - 'mt_text_more' => '', // Post "Read more" text. - ]; + if(str_starts_with($method, 'microblog')) { + // convert the post format to a microblog post + // similar to metaWeblog.recentPosts but with offset parameter for paging, + // consistent field names + $mb_post = [ + 'id' => (int) $post['id'], + 'date_created' => $date_created, + 'date_modified' => $date_modified, + 'permalink' => $config['url'].'/'.$post['id'], + 'title' => '', + 'description' => ($post['post_content']), + 'categories' => [], + 'post_status' => 'published', + 'author' => [ + 'name' => $config['microblog_account'], + 'username' => $config['admin_user'] + ] + ]; - return $mw_post; + return $mb_post; + } else { + // convert the post format to a standard metaWeblog post + $mw_post = [ + 'postid' => (int) $post['id'], + 'title' => '', + 'description' => ($post['post_content']), // Post content + 'link' => $config['url'].'/'.$post['id'], // Post URL + // string userid†: ID of post author. + 'dateCreated' => $date_created, + 'date_created_gmt' => $date_created_gmt, + 'date_modified' => $date_modified, + 'date_modified_gmt' => $date_modified_gmt, + // string wp_post_thumbnail† + 'permalink' => $config['url'].'/'.$post['id'], // Post URL, equivalent to link. + 'categories' => [], // Names of categories assigned to the post. + 'mt_keywords' => '', // Names of tags assigned to the post. + 'mt_excerpt' => '', + 'mt_text_more' => '', // Post "Read more" text. + ]; + + return $mw_post; + } } function mw_get_recent_posts($method_name, $args) { list($_, $username, $password, $amount) = $args; + $offset = 0; + if($method_name == 'microblog.getPosts' && !empty($args[4])) { + $offset = $args[4]; + } if(!check_credentials($username, $password)) { return [ @@ -80,9 +114,27 @@ function mw_get_recent_posts($method_name, $args) { } if(!$amount) $amount = 25; - - $posts = db_select_posts(time()+10, $amount); - $mw_posts = array_map('mw_make_post', $posts); + $amount = min($amount, 200); // cap the max available posts at 200 (?) + + $posts = db_select_posts(null, $amount, 'asc', $offset); + var_dump($posts); + if(empty($posts)) return []; + + if($method_name == 'microblog.getPosts') { + // currently the same as metaWeblog + /* + $mw_posts = array_map( + function($posts) { + return make_post($posts, 'microblog'); + }, + $posts + ); + */ + // https://stackoverflow.com/a/22735187/3625228 + $mw_posts = array_map('make_post', $posts, array_fill(0, count($posts), $method_name)); + } else { + $mw_posts = array_map('make_post', $posts); + } return $mw_posts; } @@ -100,7 +152,12 @@ function mw_get_post($method_name, $args) { $post = db_select_post($post_id); if($post) { - $mw_post = mw_make_post($post); + if($method_name == 'microblog.getPost') { + $mw_post = make_post($post, $method_name); + } else { + $mw_post = make_post($post); + } + return $mw_post; } else { return [ @@ -112,10 +169,11 @@ function mw_get_post($method_name, $args) { function mw_delete_post($method_name, $args) { - if($method_name == 'blogger.deletePost') { - list($_, $post_id, $username, $password, $_) = $args; - } else { + if($method_name == 'microblog.deletePost') { list($post_id, $username, $password) = $args; + } else { + // blogger.deletePost + list($_, $post_id, $username, $password, $_) = $args; } if(!check_credentials($username, $password)) { @@ -150,17 +208,32 @@ function mw_new_post($method_name, $args) { ]; } - $post = [ - // 'post_hp' => $content['flNotOnHomePage'], - 'post_timestamp' => time(), - // 'post_title' => $content['title'], - 'post_content' => $content['description'], - // 'post_url' => $content['link'], - ]; + if($method_name == 'microblog.newPost') { + $post = [ + // 'post_title' => $content['title'], + 'post_content' => $content['description'], + 'post_timestamp' => time(), + // 'post_categories' => $content['categories'], + // 'post_status' => $content['post_status'], + ]; - // use a specific timestamp, if provided - if(isset($content['dateCreated'])) { - $post['post_timestamp'] = $content['dateCreated']->timestamp; + // use a specific timestamp, if provided + if(isset($content['date_created'])) { + $post['post_timestamp'] = $content['date_created']->timestamp; + } + } else { + $post = [ + // 'post_hp' => $content['flNotOnHomePage'], + 'post_timestamp' => time(), + // 'post_title' => $content['title'], + 'post_content' => $content['description'], + // 'post_url' => $content['link'], + ]; + + // use a specific timestamp, if provided + if(isset($content['dateCreated'])) { + $post['post_timestamp'] = $content['dateCreated']->timestamp; + } } $insert_id = db_insert($post['post_content'], $post['post_timestamp']); @@ -182,7 +255,7 @@ function mw_new_post($method_name, $args) { function mw_edit_post($method_name, $args) { - // post_id, unknown, unknown, array of post content, unknown + // post_id, unknown, unknown, array of post content list($post_id, $username, $password, $content, $_) = $args; if(!check_credentials($username, $password)) { @@ -192,13 +265,31 @@ function mw_edit_post($method_name, $args) { ]; } - $post = [ - // 'post_hp' => $content['flNotOnHomePage'], - 'post_timestamp' => $content['dateCreated']->timestamp, - // 'post_title' => $content['title'], - 'post_content' => $content['description'], - // 'post_url' => $content['link'], - ]; + if($method_name == 'microblog.editPost') { + $post = [ + // 'post_title' => $content['title'], + 'post_content' => $content['description'], + 'post_timestamp' => null, + // 'post_categories' => $content['categories'], + // 'post_status' => $content['post_status'], + ]; + + if(!empty($content['date_created'])) { + $post['post_timestamp'] = $content['date_created']->timestamp; + } + } else { + $post = [ + // 'post_hp' => $content['flNotOnHomePage'], + // 'post_title' => $content['title'], + 'post_timestamp' => null, + 'post_content' => $content['description'], + // 'post_url' => $content['link'], + ]; + + if(empty($content['dateCreated'])) { + $post['post_timestamp'] = $content['dateCreated']->timestamp; + } + } $update = db_update($post_id, $post['post_content'], $post['post_timestamp']); if($update && $update > 0) { @@ -226,15 +317,24 @@ function mw_get_categories($method_name, $args) { } // we don't support categories, so only return a fake one - $categories = [ - [ - 'description' => 'Default', - 'htmlUrl' => '', - 'rssUrl' => '', - 'title' => 'default', - 'categoryid' => '1', - ] - ]; + if($method_name == 'microblog.getCategories') { + $categories = [ + [ + 'id' => '1', + 'name' => 'default', + ] + ]; + } else { + $categories = [ + [ + 'description' => 'Default', + 'htmlUrl' => '', + 'rssUrl' => '', + 'title' => 'default', + 'categoryid' => '1', + ] + ]; + } return $categories; } @@ -284,6 +384,20 @@ function mw_get_user_info($method_name, $args) { return $userinfo; } +// micro.blog API methods +// https://help.micro.blog/t/micro-blog-xml-rpc-api/108 + +// currently, the functions can be reused directly (disabled) +/* +use function mw_get_recent_posts as mb_get_posts; +use function mw_get_post as mb_get_post; +use function mw_delete_post as mb_delete_post; +use function mw_get_categories as mb_get_categories; +use function mw_new_post as mb_new_post; +use function mw_edit_post as mb_edit_post; +*/ +// use function mw_new_mediaobject as mb_new_mediaobject; // unsupported + // https://codex.wordpress.org/XML-RPC_MetaWeblog_API // https://community.devexpress.com/blogs/theprogressbar/metablog.ashx // idea: http://www.hixie.ch/specs/pingback/pingback#TOC3 @@ -293,12 +407,31 @@ xmlrpc_server_register_method($server, 'blogger.getUsersBlogs', 'mw_get_users_bl xmlrpc_server_register_method($server, 'blogger.getUserInfo', 'mw_get_user_info'); xmlrpc_server_register_method($server, 'metaWeblog.getCategories', 'mw_get_categories'); xmlrpc_server_register_method($server, 'metaWeblog.getRecentPosts', 'mw_get_recent_posts'); +xmlrpc_server_register_method($server, 'metaWeblog.getPosts', 'mw_get_recent_posts'); // convenience xmlrpc_server_register_method($server, 'metaWeblog.newPost', 'mw_new_post'); xmlrpc_server_register_method($server, 'metaWeblog.editPost', 'mw_edit_post'); xmlrpc_server_register_method($server, 'metaWeblog.getPost', 'mw_get_post'); xmlrpc_server_register_method($server, 'blogger.deletePost', 'mw_delete_post'); xmlrpc_server_register_method($server, 'metaWeblog.deletePost', 'mw_delete_post'); // does this exist? -// xmlrpc_server_register_method($server, 'metaWeblog.newMediaObject', 'say_hello'); // todo +// xmlrpc_server_register_method($server, 'metaWeblog.newMediaObject', 'mw_new_mediaobject'); // todo + +// micro.blog methods +xmlrpc_server_register_method($server, 'microblog.getPosts', 'mw_get_recent_posts'); +xmlrpc_server_register_method($server, 'microblog.getPost', 'mw_get_post'); +xmlrpc_server_register_method($server, 'microblog.newPost', 'mw_new_post'); +xmlrpc_server_register_method($server, 'microblog.editPost', 'mw_edit_post'); +xmlrpc_server_register_method($server, 'microblog.deletePost', 'mw_delete_post'); +xmlrpc_server_register_method($server, 'microblog.getCategories', 'mw_get_categories'); +// xmlrpc_server_register_method($server, 'microblog.newMediaObject', 'mb_new_mediaobject'); + +/* +// pages are not supported +xmlrpc_server_register_method($server, 'microblog.getPages', 'say_hello'); +xmlrpc_server_register_method($server, 'microblog.getPage', 'say_hello'); +xmlrpc_server_register_method($server, 'microblog.newPage', 'say_hello'); +xmlrpc_server_register_method($server, 'microblog.editPage', 'say_hello'); +xmlrpc_server_register_method($server, 'microblog.deletePage', 'say_hello'); +*/ // https://docstore.mik.ua/orelly/webprog/pcook/ch12_08.htm $response = xmlrpc_server_call_method($server, $request_xml, null, [ @@ -308,5 +441,6 @@ $response = xmlrpc_server_call_method($server, $request_xml, null, [ if($response) { header('Content-Type: text/xml; charset=utf-8'); + // error_log($request_xml."\n\n".$response."\n", 3, __DIR__.'/log.txt'); echo($response); } |