Changeset 1685 for trunk/xmlrpc.php
- Timestamp:
- 09/17/2004 08:53:18 PM (22 years ago)
- File:
-
- 1 edited
-
trunk/xmlrpc.php (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/xmlrpc.php
r1684 r1685 4 4 $HTTP_RAW_POST_DATA = trim($HTTP_RAW_POST_DATA); 5 5 6 include('wp-config.php'); 7 8 include_once (ABSPATH . WPINC . '/class-xmlrpc.php'); 9 include_once (ABSPATH . WPINC . '/class-xmlrpcs.php'); 10 include_once (ABSPATH . WPINC . '/functions-post.php'); 6 include('../wp-config.php'); 7 include_once(ABSPATH . WPINC . '/class-IXR.php'); 8 include_once(ABSPATH . WPINC . '/functions-post.php'); 11 9 12 10 // Turn off all warnings and errors. 13 error_reporting(0);11 // error_reporting(0); 14 12 15 13 $post_default_title = ""; // posts submitted via the xmlrpc interface get that title … … 21 19 global $xmlrpc_logging; 22 20 if ($xmlrpc_logging) { 23 $fp = fopen(". /xmlrpc.log","a+");21 $fp = fopen("../xmlrpc.log","a+"); 24 22 $date = gmdate("Y-m-d H:i:s "); 25 23 $iot = ($io == "I") ? " Input: " : " Output: "; … … 38 36 39 37 40 41 /**** B2 API ****/ 42 43 44 # note: the b2 API currently consists of the Blogger API, 45 # plus the following methods: 46 # 47 # b2.newPost , b2.getCategories 48 49 # Note: the b2 API will be replaced by the standard Weblogs.API once the specs are defined. 50 51 52 ### b2.newPost ### 53 54 $wpnewpost_sig=array(array($xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcBoolean, $xmlrpcString, $xmlrpcString, $xmlrpcString)); 55 56 $wpnewpost_doc='Adds a post, blogger-api like, +title +category +postdate'; 57 58 function b2newpost($m) { 59 global $wpdb; 60 61 global $xmlrpcerruser; // import user errcode value 62 global $blog_ID,$cache_userdata,$use_rss; 63 global $post_default_title,$post_default_category; 64 global $cafelogID, $sleep_after_edit; 65 $err=""; 66 67 68 $username=$m->getParam(2); 69 $password=$m->getParam(3); 70 $content=$m->getParam(4); 71 $title=$m->getParam(6); 72 $category=$m->getParam(7); 73 $postdate=$m->getParam(8); 74 75 $username = $username->scalarval(); 76 $password = $password->scalarval(); 77 $content = $content->scalarval(); 78 $title = $title->scalarval(); 79 $post_category = $category->scalarval(); 80 $postdate = $postdate->scalarval(); 81 82 83 if (user_pass_ok($username,$password)) { 84 85 $userdata = get_userdatabylogin($username); 86 $post_author = $userdata->ID; 87 $user_level = $userdata->user_level; 88 if ($user_level < 1) { 89 return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1 90 "Sorry, level 0 users can not post"); 91 } 92 93 94 $post_content = format_to_post($content); 95 $post_title = addslashes($title); 96 97 98 if ($postdate != "") { 99 $post_date = $postdate; 100 $post_date_gmt = get_gmt_from_date($postdate); 101 } else { 102 $post_date = current_time('mysql'); 103 $post_date_gmt = current_time('mysql', 1); 104 } 105 106 $post_data = compact('post_content','post_title','post_date','post_date_gmt','post_author','post_category'); 38 function printr($var, $do_not_echo = false) { 39 // from php.net/print_r user contributed notes 40 ob_start(); 41 print_r($var); 42 $code = htmlentities(ob_get_contents()); 43 ob_clean(); 44 if (!$do_not_echo) { 45 echo "<pre>$code</pre>"; 46 } 47 return $code; 48 } 49 50 function mkdir_p($target) { 51 // from php.net/mkdir user contributed notes 52 if (file_exists($target)) { 53 if (!is_dir($target)) { 54 return false; 55 } else { 56 return true; 57 } 58 } 59 60 // Attempting to create the directory may clutter up our display. 61 if (@mkdir($target)) { 62 return true; 63 } 64 65 // If the above failed, attempt to create the parent node, then try again. 66 if (mkdir_p(dirname($target))) { 67 return mkdir_p($target); 68 } 69 70 return false; 71 } 72 73 74 class wp_xmlrpc_server extends IXR_Server { 75 76 function wp_xmlrpc_server() { 77 $this->methods = array( 78 // Blogger API 79 'blogger.getUsersBlogs' => 'this:blogger_getUsersBlogs', 80 'blogger.getUserInfo' => 'this:blogger_getUserInfo', 81 'blogger.getPost' => 'this:blogger_getPost', 82 'blogger.getRecentPosts' => 'this:blogger_getRecentPosts', 83 'blogger.getTemplate' => 'this:blogger_getTemplate', 84 'blogger.setTemplate' => 'this:blogger_setTemplate', 85 'blogger.newPost' => 'this:blogger_newPost', 86 'blogger.editPost' => 'this:blogger_editPost', 87 'blogger.deletePost' => 'this:blogger_deletePost', 88 89 // MetaWeblog API (with MT extensions to structs) 90 'metaWeblog.newPost' => 'this:mw_newPost', 91 'metaWeblog.editPost' => 'this:mw_editPost', 92 'metaWeblog.getPost' => 'this:mw_getPost', 93 'metaWeblog.getRecentPosts' => 'this:mw_getRecentPosts', 94 'metaWeblog.getCategories' => 'this:mw_getCategories', 95 'metaWeblog.newMediaObject' => 'this:mw_newMediaObject', 96 97 // MetaWeblog API aliases for Blogger API 98 // see http://www.xmlrpc.com/stories/storyReader$2460 99 'metaWeblog.deletePost' => 'this:blogger_deletePost', 100 'metaWeblog.getTemplate' => 'this:blogger_getTemplate', 101 'metaWeblog.setTemplate' => 'this:blogger_setTemplate', 102 'metaWeblog.getUsersBlogs' => 'this:blogger_getUsersBlogs', 103 104 // MovableType API 105 'mt.getCategoryList' => 'this:mt_getCategoryList', 106 'mt.getRecentPostTitles' => 'this:mt_getRecentPostTitles', 107 'mt.getPostCategories' => 'this:mt_getPostCategories', 108 'mt.setPostCategories' => 'this:mt_setPostCategories', 109 'mt.supportedMethods' => 'this:mt_supportedMethods', 110 'mt.supportedTextFilters' => 'this:mt_supportedTextFilters', 111 'mt.getTrackbackPings' => 'this:mt_getTrackbackPings', 112 'mt.publishPost' => 'this:mt_publishPost', 113 114 // PingBack 115 'pingback.ping' => 'this:pingback_ping', 116 'pingback.extensions.getPingbacks' => 'this:pingback_extensions_getPingbacks', 117 118 'demo.sayHello' => 'this:sayHello', 119 'demo.addTwoNumbers' => 'this:addTwoNumbers' 120 ); 121 $this->IXR_Server($this->methods); 122 } 123 124 function sayHello($args) { 125 return 'Hello!'; 126 } 127 128 function addTwoNumbers($args) { 129 $number1 = $args[0]; 130 $number2 = $args[1]; 131 return $number1 + $number2; 132 } 133 134 function login_pass_ok($user_login, $user_pass) { 135 if (!user_pass_ok($user_login, $user_pass)) { 136 $this->error = new IXR_Error(403, 'Bad login/pass combination.'); 137 return false; 138 } 139 return true; 140 } 141 142 143 144 145 /* Blogger API functions 146 * specs on http://plant.blogger.com/api and http://groups.yahoo.com/group/bloggerDev/ 147 */ 148 149 150 /* blogger.getUsersBlogs will make more sense once we support multiple blogs */ 151 function blogger_getUsersBlogs($args) { 152 153 $user_login = $args[1]; 154 $user_pass = $args[2]; 155 156 if (!$this->login_pass_ok($user_login, $user_pass)) { 157 return $this->error; 158 } 159 160 $user_data = get_userdatabylogin($user_login); 161 $is_admin = $user_data->user_level > 3; 162 163 $struct = array( 164 'isAdmin' => $is_admin, 165 'url' => get_settings('home') .'/'.get_settings('blogfilename'), 166 'blogid' => '1', 167 'blogName' => get_settings('blogname') 168 ); 169 170 return array($struct); 171 } 172 173 174 /* blogger.getUsersInfo gives your client some info about you, so you don't have to */ 175 function blogger_getUserInfo($args) { 176 177 $user_login = $args[1]; 178 $user_pass = $args[2]; 179 180 if (!$this->login_pass_ok($user_login, $user_pass)) { 181 return $this->error; 182 } 183 184 $user_data = get_userdatabylogin($user_login); 185 186 $struct = array( 187 'nickname' => $user_data->user_nickname, 188 'userid' => $user_data->ID, 189 'url' => $user_data->user_url, 190 'email' => $user_data->user_email, 191 'lastname' => $user_data->user_lastname, 192 'firstname' => $user_data->user_firstname 193 ); 194 195 return $struct; 196 } 197 198 199 /* blogger.getPost ...gets a post */ 200 function blogger_getPost($args) { 201 202 $post_ID = $args[1]; 203 $user_login = $args[2]; 204 $user_pass = $args[3]; 205 206 if (!$this->login_pass_ok($user_login, $user_pass)) { 207 return $this->error; 208 } 209 210 $user_data = get_userdatabylogin($user_login); 211 $post_data = wp_get_single_post($post_ID, ARRAY_A); 212 213 $categories = implode(',', wp_get_post_cats(1, $post_ID)); 214 215 $content = '<title>'.stripslashes($post_data['post_title']).'</title>'; 216 $content .= '<category>'.$categories.'</category>'; 217 $content .= stripslashes($post_data['post_content']); 218 219 $struct = array( 220 'userid' => $post_data['post_author'], 221 'dateCreated' => new IXR_Date(mysql2date('Ymd\TH:i:s', $post_data['post_date'])), 222 'content' => $content, 223 'postid' => $post_data['ID'] 224 ); 225 226 return $struct; 227 } 228 229 230 /* blogger.getRecentPosts ...gets recent posts */ 231 function blogger_getRecentPosts($args) { 232 233 global $wpdb; 234 235 $blog_ID = $args[1]; /* though we don't use it yet */ 236 $user_login = $args[2]; 237 $user_pass = $args[3]; 238 $num_posts = $args[4]; 239 240 if (!$this->login_pass_ok($user_login, $user_pass)) { 241 return $this->error; 242 } 243 244 $posts_list = wp_get_recent_posts($num_posts); 245 246 if (!$posts_list) { 247 $this->error = new IXR_Error(500, 'Either there are no posts, or something went wrong.'); 248 return $this->error; 249 } 250 251 foreach ($posts_list as $entry) { 252 253 $post_date = mysql2date('Ymd\TH:i:s', $entry['post_date']); 254 $categories = implode(',', wp_get_post_cats(1, $entry['ID'])); 255 256 $content = '<title>'.stripslashes($entry['post_itle']).'</title>'; 257 $content .= '<category>'.$categories.'</category>'; 258 $content .= stripslashes($entry['post_content']); 259 260 $struct[] = array( 261 'userid' => $entry['post_author'], 262 'dateCreated' => new IXR_Date($post_date), 263 'content' => $content, 264 'postid' => $entry['ID'], 265 ); 266 267 } 268 269 $recent_posts = array(); 270 for ($j=0; $j<count($struct); $j++) { 271 array_push($recent_posts, $struct[$j]); 272 } 273 274 return $recent_posts; 275 } 276 277 278 /* blogger.getTemplate returns your blog_filename */ 279 function blogger_getTemplate($args) { 280 281 $blog_ID = $args[1]; 282 $user_login = $args[2]; 283 $user_pass = $args[3]; 284 $template = $args[4]; /* could be 'main' or 'archiveIndex', but we don't use it */ 285 286 if (!$this->login_pass_ok($user_login, $user_pass)) { 287 return $this->error; 288 } 289 290 $user_data = get_userdatabylogin($user_login); 291 292 if ($user_data->user_level < 3) { 293 return new IXR_Error(401, 'Sorry, users whose level is less than 3, can not edit the template.'); 294 } 295 296 /* warning: here we make the assumption that the weblog's URI is on the same server */ 297 $filename = get_settings('home').'/'.get_settings('blogfilename'); 298 $filename = preg_replace('#http://.+?/#', $_SERVER['DOCUMENT_ROOT'].'/', $filename); 299 300 $f = fopen($filename, 'r'); 301 $content = fread($f, filesize($filename)); 302 fclose($f); 303 304 /* so it is actually editable with a windows/mac client */ 305 // FIXME: (or delete me) do we really want to cater to bad clients at the expense of good ones by BEEPing up their line breaks? commented. $content = str_replace("\n", "\r\n", $content); 306 307 return $content; 308 } 309 310 311 /* blogger.setTemplate updates the content of blog_filename */ 312 function blogger_setTemplate($args) { 313 314 $blog_ID = $args[1]; 315 $user_login = $args[2]; 316 $user_pass = $args[3]; 317 $content = $args[4]; 318 $template = $args[5]; /* could be 'main' or 'archiveIndex', but we don't use it */ 319 320 if (!$this->login_pass_ok($user_login, $user_pass)) { 321 return $this->error; 322 } 323 324 $user_data = get_userdatabylogin($user_login); 325 326 if ($user_data->user_level < 3) { 327 return new IXR_Error(401, 'Sorry, users whose level is less than 3, can not edit the template.'); 328 } 329 330 /* warning: here we make the assumption that the weblog's URI is on the same server */ 331 $filename = get_settings('home').'/'.get_settings('blogfilename'); 332 $filename = preg_replace('#http://.+?/#', $_SERVER['DOCUMENT_ROOT'].'/', $filename); 333 334 if ($f = fopen($filename, 'w+')) { 335 fwrite($f, $content); 336 fclose($f); 337 } else { 338 return new IXR_Error(500, 'Either the file is not writable, or something wrong happened. The file has not been updated.'); 339 } 340 341 return true; 342 } 343 344 345 /* blogger.newPost ...creates a new post */ 346 function blogger_newPost($args) { 347 348 global $wpdb; 349 350 $blog_ID = $args[1]; /* though we don't use it yet */ 351 $user_login = $args[2]; 352 $user_pass = $args[3]; 353 $content = $args[4]; 354 $publish = $args[5]; 355 356 if (!$this->login_pass_ok($user_login, $user_pass)) { 357 return $this->error; 358 } 359 360 $user_data = get_userdatabylogin($user_login); 361 if (!user_can_create_post($user_data->ID, $blog_ID)) { 362 return new IXR_Error(401, 'Sorry, you can not post on this weblog or category.'); 363 } 364 365 $post_status = ($publish) ? 'publish' : 'draft'; 366 367 $post_author = $user_data->ID; 368 369 $post_title = xmlrpc_getposttitle($content); 370 $post_category = xmlrpc_getpostcategory($content); 371 372 $content = xmlrpc_removepostdata($content); 373 $post_content = format_to_post($content); 374 375 $post_date = current_time('mysql'); 376 $post_date_gmt = current_time('mysql', 1); 377 378 $post_data = compact('blog_ID', 'post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_title', 'post_category', 'post_status'); 379 380 $post_ID = wp_insert_post($post_data); 381 382 if (!$post_ID) { 383 return new IXR_Error(500, 'Sorry, your entry could not be posted. Something wrong happened.'); 384 } 385 386 logIO('O', "Posted ! ID: $post_ID"); 387 388 return $post_ID; 389 } 390 391 392 /* blogger.editPost ...edits a post */ 393 function blogger_editPost($args) { 394 395 global $wpdb; 396 397 $post_ID = $args[1]; 398 $user_login = $args[2]; 399 $user_pass = $args[3]; 400 $new_content = $args[4]; 401 $publish = $args[5]; 402 403 if (!$this->login_pass_ok($user_login, $user_pass)) { 404 return $this->error; 405 } 406 407 $actual_post = wp_get_single_post($post_ID,ARRAY_A); 408 409 if (!$actual_post) { 410 return new IXR_Error(404, 'Sorry, no such post.'); 411 } 412 413 $post_author_data = get_userdata($actual_post['post_author']); 414 $user_data = get_userdatabylogin($user_login); 415 416 if (!user_can_edit_post($user_data->ID, $post_ID)) { 417 return new IXR_Error(401, 'Sorry, you do not have the right to edit this post.'); 418 } 419 420 extract($actual_post); 421 $content = $newcontent; 422 423 $post_title = xmlrpc_getposttitle($content); 424 $post_category = xmlrpc_getpostcategory($content); 425 426 $content = xmlrpc_removepostdata($content); 427 $post_content = format_to_post($content); 428 429 $postdata = compact('ID', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt'); 430 431 $result = wp_update_post($postdata); 432 433 if (!$result) { 434 return new IXR_Error(500, 'For some strange yet very annoying reason, this post could not be edited.'); 435 } 436 437 return true; 438 } 439 440 441 /* blogger.deletePost ...deletes a post */ 442 function blogger_deletePost($args) { 443 444 global $wpdb; 445 446 $post_ID = $args[1]; 447 $user_login = $args[2]; 448 $user_pass = $args[3]; 449 $publish = $args[4]; 450 451 if (!$this->login_pass_ok($user_login, $user_pass)) { 452 return $this->error; 453 } 454 455 $actual_post = wp_get_single_post($post_ID,ARRAY_A); 456 457 if (!$actual_post) { 458 return new IXR_Error(404, 'Sorry, no such post.'); 459 } 460 461 $user_data = get_userdatabylogin($user_login); 462 463 if (!user_can_delete_post($user_data->ID, $post_ID)) { 464 return new IXR_Error(401, 'Sorry, you do not have the right to delete this post.'); 465 } 466 467 $result = wp_delete_post($post_ID); 468 469 if (!$result) { 470 return new IXR_Error(500, 'For some strange yet very annoying reason, this post could not be deleted.'); 471 } 472 473 return true; 474 } 475 476 477 478 /* MetaWeblog API functions 479 * specs on wherever Dave Winer wants them to be 480 */ 481 482 /* metaweblog.newPost creates a post */ 483 function mw_newPost($args) { 484 485 global $wpdb; 486 487 $blog_ID = $args[0]; // we will support this in the near future 488 $user_login = $args[1]; 489 $user_pass = $args[2]; 490 $content_struct = $args[3]; 491 $publish = $args[4]; 492 493 if (!$this->login_pass_ok($user_login, $user_pass)) { 494 return $this->error; 495 } 496 497 $user_data = get_userdatabylogin($user_login); 498 if (!user_can_create_post($user_data->ID, $blog_ID)) { 499 return new IXR_Error(401, 'Sorry, you can not post on this weblog or category.'); 500 } 501 502 $post_author = $user_data->ID; 503 504 $post_title = $content_struct['title']; 505 $post_content = format_to_post($content_struct['description']); 506 $post_status = $publish ? 'publish' : 'draft'; 507 508 $post_excerpt = $content_struct['mt_excerpt']; 509 $post_more = $content_struct['mt_text_more']; 510 511 $comment_status = (empty($content_struct['mt_allow_comments'])) ? 512 get_settings('default_comment_status') 513 : $content_struct['mt_allow_comments']; 514 515 $ping_status = (empty($content_struct['mt_allow_pings'])) ? 516 get_settings('default_ping_status') 517 : $content_struct['mt_allow_pings']; 518 519 if ($post_more) { 520 $post_content = $post_content . "\n<!--more-->\n" . $post_more; 521 } 107 522 108 $result = wp_insert_post($post_data); 109 110 if (!$result) 111 return new xmlrpcresp(0, $xmlrpcerruser+2, // user error 2 112 "For some strange yet very annoying reason, your entry couldn't be posted."); 113 114 115 $post_ID = $result; 116 117 if (!isset($blog_ID)) { $blog_ID = 1; } 523 // Do some timestamp voodoo 524 $dateCreatedd = $content_struct['dateCreated']; 525 $dateCreated = $dateCreatedd->getIso(); 526 if (!empty($dateCreated)) { 527 $post_date = get_date_from_gmt(iso8601_to_datetime($dateCreated)); 528 $post_date_gmt = iso8601_to_datetime($dateCreated, GMT); 529 } else { 530 $post_date = current_time('mysql'); 531 $post_date_gmt = current_time('mysql', 1); 532 } 533 534 $catnames = $content_struct['categories']; 535 logio('O', 'Post cats: ' . printr($catnames,true)); 536 $post_category = array(); 537 538 if ($catnames) { 539 foreach ($catnames as $cat) { 540 $post_category[] = get_cat_ID($cat); 541 } 542 } else { 543 $post_category[] = 1; 544 } 118 545 119 if (isset($sleep_after_edit) && $sleep_after_edit > 0) { 120 sleep($sleep_after_edit); 121 } 122 123 124 125 pingback($content, $post_ID); 126 127 128 return new xmlrpcresp(new xmlrpcval("$post_ID")); 129 130 } else { 131 132 return new xmlrpcresp(0, $xmlrpcerruser+3, // user error 3 133 'Wrong username/password combination '.$username.' / '.starify($password)); 134 } 135 } 136 137 138 139 ### b2.getCategories ### 140 141 $wpgetcategories_sig=array(array($xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString)); 142 143 $wpgetcategories_doc='given a blogID, gives a struct that list categories in that blog, using categoryID and categoryName. categoryName is there so the user would choose a category name from the client, rather than just a number. however, when using b2.newPost, only the category ID number should be sent.'; 144 145 function b2getcategories($m) { 146 global $wpdb; 147 global $xmlrpcerruser; 148 149 150 $blogid=$m->getParam(0); 151 $blogid = $blogid->scalarval(); // we dot not use that yet, that will be used with multiple blogs 152 153 $username=$m->getParam(1); 154 $username = $username->scalarval(); 155 156 $password=$m->getParam(2); 157 $password = $password->scalarval(); 158 159 $userdata = get_userdatabylogin($username); 160 161 162 if (user_pass_ok($username,$password)) { 163 164 $results = $wpdb->get_results("SELECT * FROM $wpdb->categories ORDER BY cat_ID ASC"); 165 if (!$results) die("Error getting data"); 166 $i = 0; 167 foreach($results as $row) { 168 $cat_name = $row->cat_name; 169 $cat_ID = $row->cat_ID; 170 171 $struct[$i] = new xmlrpcval(array("categoryID" => new xmlrpcval($cat_ID), 172 "categoryName" => new xmlrpcval($cat_name) 173 ),"struct"); 174 $i = $i + 1; 175 } 176 177 $data = array($struct[0]); 178 for ($j=1; $j<$i; $j++) { 179 array_push($data, $struct[$j]); 180 } 181 182 $resp = new xmlrpcval($data, "array"); 183 184 return new xmlrpcresp($resp); 185 186 } else { 187 return new xmlrpcresp(0, $xmlrpcerruser+3, // user error 3 188 'Wrong username/password combination '.$username.' / '.starify($password)); 189 } 190 } 191 192 193 194 ### b2.getPostURL ### 195 196 $wp_getPostURL_sig = array(array($xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString)); 197 198 $wp_getPostURL_doc = 'Given a blog ID, username, password, and a post ID, returns the URL to that post.'; 199 200 function b2_getPostURL($m) { 201 global $wpdb; 202 global $xmlrpcerruser; 203 global $querystring_start, $querystring_equal, $querystring_separator; 204 205 206 // ideally, this would be used: 207 // $blog_ID = $m->getParam(0); 208 // $blog_ID = $blog_ID->scalarval(); 209 // but right now, b2 handles only one blog, so... :P 210 $blog_ID = 1; 211 212 $username=$m->getParam(2); 213 $username = $username->scalarval(); 214 215 $password=$m->getParam(3); 216 $password = $password->scalarval(); 217 218 $post_ID = $m->getParam(4); 219 $post_ID = intval($post_ID->scalarval()); 220 221 $userdata = get_userdatabylogin($username); 222 223 if ($userdata->user_level < 1) { 224 return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1 225 "Sorry, users whose level is zero, can not use this method."); 226 } 227 228 if (user_pass_ok($username,$password)) { 229 $blog_URL = get_settings('home') .'/' . get_settings('blogfilename'); 230 $post_URL = get_permalink($post_ID); 231 232 if ($err) { 233 return new xmlrpcresp(0, $xmlrpcerruser, $err); 234 } else { 235 return new xmlrpcresp(new xmlrpcval($post_URL));; 236 } 237 238 } else { 239 return new xmlrpcresp(0, $xmlrpcerruser+3, // user error 3 240 'Wrong username/password combination '.$username.' / '.starify($password)); 241 } 242 243 } 244 245 /**** /B2 API ****/ 246 247 248 249 /**** Blogger API ****/ 250 251 # as described on http://plant.blogger.com/api and in various messages in http://groups.yahoo.com/group/bloggerDev/ 252 # 253 # another list of these methods is there http://www.tswoam.co.uk/blogger_method_listing.html 254 # so you won't have to browse the eGroup to find all the methods 255 # 256 # special note: Evan please keep _your_ API page up to date :p 257 258 259 260 ### blogger.newPost ### 261 262 $bloggernewpost_sig=array(array($xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcBoolean)); 263 264 $bloggernewpost_doc='Adds a post, blogger-api like'; 265 266 function bloggernewpost($m) { 267 global $wpdb; 268 269 global $xmlrpcerruser; // import user errcode value 270 global $blog_ID,$cache_userdata,$use_rss; 271 global $post_default_title,$post_default_category; 272 global $cafelogID, $sleep_after_edit; 273 $err=""; 274 275 276 $username=$m->getParam(2); 277 $password=$m->getParam(3); 278 $content=$m->getParam(4); 279 $publish=$m->getParam(5); 280 281 $username = $username->scalarval(); 282 $password = $password->scalarval(); 283 $content = $content->scalarval(); 284 // publish flag sets post status appropriately 285 $post_status = $publish->scalarval()?'publish':'draft'; 546 // We've got all the data -- post it: 547 $postdata = compact('post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt', 'comment_status', 'ping_status'); 548 549 $post_ID = wp_insert_post($postdata); 550 551 if (!$post_ID) { 552 return new IXR_Error(500, 'Sorry, your entry could not be posted. Something wrong happened.'); 553 } 554 555 logIO('O', "Posted ! ID: $post_ID"); 556 557 // FIXME: do we pingback always? pingback($content, $post_ID); 558 trackback_url_list($content_struct['mt_tb_ping_urls'],$post_ID); 559 560 return strval($post_ID); 561 } 562 563 564 /* metaweblog.editPost ...edits a post */ 565 function mw_editPost($args) { 566 567 global $wpdb; 568 569 $post_ID = $args[0]; 570 $user_login = $args[1]; 571 $user_pass = $args[2]; 572 $content_struct = $args[3]; 573 $publish = $args[4]; 574 575 if (!$this->login_pass_ok($user_login, $user_pass)) { 576 return $this->error; 577 } 578 579 $user_data = get_userdatabylogin($user_login); 580 if (!user_can_edit_post($user_data->ID, $post_ID)) { 581 return new IXR_Error(401, 'Sorry, you can not edit this post.'); 582 } 583 584 $postdata = wp_get_single_post($post_ID, ARRAY_A); 585 extract($postdata); 586 587 $post_title = $content_struct['title']; 588 $post_content = format_to_post($content_struct['description']); 589 $catnames = $content_struct['categories']; 590 591 if ($catnames) { 592 foreach ($catnames as $cat) { 593 $post_category[] = get_cat_ID($cat); 594 } 595 } 596 597 $post_excerpt = $content_struct['mt_excerpt']; 598 $post_more = $content_struct['mt_text_more']; 599 $post_status = $publish ? 'publish' : 'draft'; 600 601 if ($post_more) { 602 $post_content = $post_content . "\n<!--more-->\n" . $post_more; 603 } 604 605 $comment_status = (empty($content_struct['mt_allow_comments'])) ? 606 get_settings('default_comment_status') 607 : $content_struct['mt_allow_comments']; 608 609 $ping_status = (empty($content_struct['mt_allow_pings'])) ? 610 get_settings('default_ping_status') 611 : $content_struct['mt_allow_pings']; 612 613 // Do some timestamp voodoo 614 $dateCreated = $content_struct['dateCreated']; 615 $dateCreated = $dateCreated->getIso(); 616 if (!empty($dateCreated)) { 617 $post_date = get_date_from_gmt(iso8601_to_datetime($dateCreated)); 618 $post_date_gmt = iso8601_to_datetime($dateCreated, GMT); 619 } else { 620 $post_date = $postdata['post_date']; 621 $post_date_gmt = $postdata['post_date_gmt']; 622 } 623 624 // We've got all the data -- post it: 625 $newpost = compact('ID', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt', 'comment_status', 'ping_status', 'post_date', 'post_date_gmt'); 626 627 $post_ID = wp_update_post($newpost); 628 if (!$post_ID) { 629 return new IXR_Error(500, 'Sorry, your entry could not be edited. Something wrong happened.'); 630 } 631 632 logIO('O',"(MW) Edited ! ID: $post_ID"); 633 634 // FIXME: do we pingback always? pingback($content, $post_ID); 635 trackback_url_list($content_struct['mt_tb_ping_urls'], $post_ID); 636 637 return true; 638 } 639 640 641 /* metaweblog.getPost ...returns a post */ 642 function mw_getPost($args) { 643 644 global $wpdb; 645 646 $post_ID = $args[0]; 647 $user_login = $args[1]; 648 $user_pass = $args[2]; 649 650 if (!$this->login_pass_ok($user_login, $user_pass)) { 651 return $this->error; 652 } 653 654 $postdata = wp_get_single_post($post_ID, ARRAY_A); 655 656 if ($postdata['post_date'] != '') { 657 658 $post_date = mysql2date('Ymd\TH:i:s', $postdata['post_date']); 659 660 $categories = array(); 661 $catids = wp_get_post_cats('', $post_ID); 662 foreach($catids as $catid) { 663 $categories[] = get_cat_name($catid); 664 } 665 666 $post = get_extended($postdata['post_content']); 667 $link = post_permalink($postdata['ID']); 668 669 $allow_comments = ('open' == $postdata['comment_status']) ? 1 : 0; 670 $allow_pings = ('open' == $postdata['ping_status']) ? 1 : 0; 671 672 $resp = array( 673 'dateCreated' => new IXR_Date($post_date), 674 'userid' => $postdata['post_author'], 675 'postid' => $postdata['ID'], 676 'description' => $post['main'], 677 'title' => $postdata['post_title'], 678 'link' => $link, 679 'permaLink' => $link, 680 // commented out because no other tool seems to use this 681 // 'content' => $entry['post_content'], 682 'categories' => $categories, 683 'mt_excerpt' => $postdata['post_excerpt'], 684 'mt_text_more' => $post['extended'], 685 'mt_allow_comments' => $allow_comments, 686 'mt_allow_pings' => $allow_pings 687 ); 688 689 return $resp; 690 } else { 691 return new IXR_Error(404, 'Sorry, no such post.'); 692 } 693 } 694 695 696 /* metaweblog.getRecentPosts ...returns recent posts */ 697 function mw_getRecentPosts($args) { 698 699 $blog_ID = $args[0]; 700 $user_login = $args[1]; 701 $user_pass = $args[2]; 702 $num_posts = $args[3]; 703 704 if (!$this->login_pass_ok($user_login, $user_pass)) { 705 return $this->error; 706 } 707 708 $posts_list = wp_get_recent_posts($num_posts); 709 710 if (!$posts_list) { 711 $this->error = new IXR_Error(500, 'Either there are no posts, or something went wrong.'); 712 return $this->error; 713 } 714 715 foreach ($posts_list as $entry) { 716 717 $post_date = mysql2date('Ymd\TH:i:s', $entry['post_date']); 718 $categories = array(); 719 $catids = wp_get_post_cats('', $entry['ID']); 720 foreach($catids as $catid) { 721 $categories[] = get_cat_name($catid); 722 } 723 724 $post = get_extended($entry['post_content']); 725 $link = post_permalink($entry['ID']); 726 727 $allow_comments = ('open' == $entry['comment_status']) ? 1 : 0; 728 $allow_pings = ('open' == $entry['ping_status']) ? 1 : 0; 729 730 $struct[] = array( 731 'dateCreated' => new IXR_Date($post_date), 732 'userid' => $entry['post_author'], 733 'postid' => $entry['ID'], 734 'description' => $post['main'], 735 'title' => $entry['post_title'], 736 'link' => $link, 737 'permaLink' => $link, 738 // commented out because no other tool seems to use this 739 // 'content' => $entry['post_content'], 740 'categories' => $categories, 741 'mt_excerpt' => $entry['post_excerpt'], 742 'mt_text_more' => $post['extended'], 743 'mt_allow_comments' => $allow_comments, 744 'mt_allow_pings' => $allow_pings 745 ); 746 747 } 748 749 $recent_posts = array(); 750 for ($j=0; $j<count($struct); $j++) { 751 array_push($recent_posts, $struct[$j]); 752 } 753 754 return $recent_posts; 755 } 756 757 758 /* metaweblog.getCategories ...returns the list of categories on a given weblog */ 759 function mw_getCategories($args) { 760 761 global $wpdb; 762 763 $blog_ID = $args[0]; 764 $user_login = $args[1]; 765 $user_pass = $args[2]; 766 767 if (!$this->login_pass_ok($user_login, $user_pass)) { 768 return $this->error; 769 } 770 771 $categories_struct = array(); 772 773 // FIXME: can we avoid using direct SQL there? 774 if ($cats = $wpdb->get_results("SELECT cat_ID,cat_name FROM $wpdb->categories", ARRAY_A)) { 775 foreach ($cats as $cat) { 776 $struct['categoryId'] = $cat['cat_ID']; 777 $struct['description'] = $cat['cat_name']; 778 $struct['categoryName'] = $cat['cat_name']; 779 $struct['htmlUrl'] = htmlspecialchars(get_category_link(false, $cat['cat_ID'], $cat['cat_name'])); 780 $struct['rssUrl'] = htmlspecialchars(get_category_rss_link(false, $cat['cat_ID'], $cat['cat_name'])); 781 782 $categories_struct[] = $struct; 783 } 784 } 785 786 return $categories_struct; 787 } 788 789 790 /* metaweblog.newMediaObject uploads a file, following your settings */ 791 function mw_newMediaObject($args) { 792 // adapted from a patch by Johann Richard 793 // http://mycvs.org/archives/2004/06/30/file-upload-to-wordpress-in-ecto/ 794 795 $blog_ID = $args[0]; 796 $user_login = $args[1]; 797 $user_pass = $args[2]; 798 $data = $args[3]; 799 800 $name = $data['name']; 801 $type = $data['type']; 802 $bits = $data['bits']; 803 804 $file_realpath = get_settings('fileupload_realpath'); 805 $file_url = get_settings('fileupload_url'); 806 807 logIO('O', '(MW) Received '.strlen($bits).' bytes'); 808 809 if (!$this->login_pass_ok($user_login, $user_pass)) { 810 return $this->error; 811 } 812 813 $user_data = get_userdatabylogin($user_login); 814 815 if(!get_settings('use_fileupload')) { 816 // Uploads not allowed 817 logIO('O', '(MW) Uploads not allowed'); 818 $this->error = new IXR_Error(405, 'No uploads allowed for this site.'); 819 return $this->error; 820 } 821 822 if(get_settings('fileupload_minlevel') > $user_data->user_level) { 823 // User has not enough privileges 824 logIO('O', '(MW) Not enough privilege: user level too low'); 825 $this->error = new IXR_Error(401, 'You are not allowed to upload files to this site.'); 826 return $this->error; 827 } 828 829 if(trim($file_realpath) == '' || trim($file_url) == '' ) { 830 // WordPress is not correctly configured 831 logIO('O', '(MW) Bad configuration. Real/URL path not defined'); 832 $this->error = new IXR_Error(500, 'Please configure WordPress with valid paths for file upload.'); 833 return $this->error; 834 } 835 836 $prefix = '/'; 837 838 if(!empty($name)) { 839 // Create the path 840 $localpath = $file_realpath.$prefix.$name; 841 $url = $file_url.$prefix.$name; 842 843 if (mkdir_p(dirname($localpath))) { 844 845 /* encode & write data (binary) */ 846 $ifp = fopen($localpath, 'wb'); 847 $success = fwrite($ifp, $bits); 848 fclose($ifp); 849 @chmod($localpath, 0666); 850 851 if($success) { 852 $resp = array('url' => $url); 853 return $resp; 854 } else { 855 logIO('O', '(MW) Could not write file '.$name.' to '.$localpath); 856 return new IXR_Error(500, 'Could not write file '.$name); 857 } 858 859 } else { 860 return new IXR_Error(500, 'Could not create directories for '.$name); 861 } 862 } 863 } 864 865 866 867 /* MovableType API functions 868 * specs on http://www.movabletype.org/docs/mtmanual_programmatic.html 869 */ 870 871 /* mt.getRecentPostTitles ...returns recent posts' titles */ 872 function mt_getRecentPostTitles($args) { 873 874 $blog_ID = $args[0]; 875 $user_login = $args[1]; 876 $user_pass = $args[2]; 877 $num_posts = $args[3]; 878 879 if (!$this->login_pass_ok($user_login, $user_pass)) { 880 return $this->error; 881 } 882 883 $posts_list = wp_get_recent_posts($num_posts); 884 885 if (!$posts_list) { 886 $this->error = new IXR_Error(500, 'Either there are no posts, or something went wrong.'); 887 return $this->error; 888 } 889 890 foreach ($posts_list as $entry) { 891 892 $post_date = mysql2date('Ymd\TH:i:s', $entry['post_date']); 893 894 $struct[] = array( 895 'dateCreated' => new IXR_Date($post_date), 896 'userid' => $entry['post_author'], 897 'postid' => $entry['ID'], 898 'title' => $entry['post_title'], 899 ); 900 901 } 902 903 $recent_posts = array(); 904 for ($j=0; $j<count($struct); $j++) { 905 array_push($recent_posts, $struct[$j]); 906 } 907 908 return $recent_posts; 909 } 910 911 912 /* mt.getCategoryList ...returns the list of categories on a given weblog */ 913 function mt_getCategoryList($args) { 914 915 global $wpdb; 916 917 $blog_ID = $args[0]; 918 $user_login = $args[1]; 919 $user_pass = $args[2]; 920 921 if (!$this->login_pass_ok($user_login, $user_pass)) { 922 return $this->error; 923 } 924 925 $categories_struct = array(); 926 927 // FIXME: can we avoid using direct SQL there? 928 if ($cats = $wpdb->get_results("SELECT cat_ID, cat_name FROM $wpdb->categories", ARRAY_A)) { 929 foreach ($cats as $cat) { 930 $struct['categoryId'] = $cat['cat_ID']; 931 $struct['categoryName'] = $cat['cat_name']; 932 933 $categories_struct[] = $struct; 934 } 935 } 936 937 return $categories_struct; 938 } 939 940 941 /* mt.getPostCategories ...returns a post's categories */ 942 function mt_getPostCategories($args) { 943 944 $post_ID = $args[0]; 945 $user_login = $args[1]; 946 $user_pass = $args[2]; 947 948 if (!$this->login_pass_ok($user_login, $user_pass)) { 949 return $this->error; 950 } 951 952 $categories = array(); 953 $catids = wp_get_post_cats('', intval($post_ID)); 954 // first listed category will be the primary category 955 $isPrimary = true; 956 foreach($catids as $catid) { 957 $categories[] = array( 958 'categoryName' => get_cat_name($catid), 959 'categoryId' => $catid, 960 'isPrimary' => $isPrimary 961 ); 962 $isPrimary = false; 963 } 964 965 return $categories; 966 } 967 968 969 /* mt.setPostCategories ...sets a post's categories */ 970 function mt_setPostCategories($args) { 971 972 $post_ID = $args[0]; 973 $user_login = $args[1]; 974 $user_pass = $args[2]; 975 $categories = $args[3]; 976 977 if (!$this->login_pass_ok($user_login, $user_pass)) { 978 return $this->error; 979 } 980 981 $user_data = get_userdatabylogin($user_login); 982 if (!user_can_edit_post($user_data->ID, $post_ID)) { 983 return new IXR_Error(401, 'Sorry, you can not edit this post.'); 984 } 985 986 foreach($categories as $cat) { 987 $catids[] = $cat['categoryId']; 988 } 286 989 287 if (user_pass_ok($username,$password)) { 288 289 $userdata = get_userdatabylogin($username); 290 $post_author = $userdata->ID; 291 $user_level = $userdata->user_level; 292 if ($user_level < 1) { 293 return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1 294 "Sorry, level 0 users can not post"); 295 } 296 297 $post_title = addslashes(xmlrpc_getposttitle($content)); 298 $post_category = xmlrpc_getpostcategory($content); 299 300 $content = xmlrpc_removepostdata($content); 301 $post_content = format_to_post($content); 302 303 $post_date = current_time('mysql'); 304 $post_date_gmt = current_time('mysql', 1); 305 306 $postdata = compact('post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_title', 'post_category', 'post_status'); 307 308 $post_ID = wp_insert_post($postdata); 309 310 if (!$post_ID) 311 return new xmlrpcresp(0, $xmlrpcerruser+2, // user error 2 312 "For some strange yet very annoying reason, your entry couldn't be posted."); 313 314 if (!isset($blog_ID)) { $blog_ID = 1; } 315 316 if (isset($sleep_after_edit) && $sleep_after_edit > 0) { 317 sleep($sleep_after_edit); 318 } 319 320 321 pingback($content, $post_ID); 322 323 logIO("O","Posted ! ID: $post_ID"); 324 return new xmlrpcresp(new xmlrpcval("$post_ID")); 325 326 } else { 327 logIO("O","Wrong username/password combination <b>$username / $password</b>"); 328 return new xmlrpcresp(0, $xmlrpcerruser+3, // user error 3 329 'Wrong username/password combination '.$username.' / '.starify($password)); 330 } 331 } 332 333 334 335 ### blogger.editPost ### 336 337 $bloggereditpost_sig=array(array($xmlrpcBoolean, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcBoolean)); 338 339 $bloggereditpost_doc='Edits a post, blogger-api like'; 340 341 function bloggereditpost($m) { 342 global $wpdb; 343 344 global $xmlrpcerruser; // import user errcode value 345 global $blog_ID,$cache_userdata,$use_rss; 346 global $post_default_title,$post_default_category, $sleep_after_edit; 347 $err=""; 348 349 350 $post_ID=$m->getParam(1); 351 $username=$m->getParam(2); 352 $password=$m->getParam(3); 353 $newcontent=$m->getParam(4); 354 $publish=$m->getParam(5); 355 356 $ID = $post_ID->scalarval(); 357 $username = $username->scalarval(); 358 $password = $password->scalarval(); 359 $newcontent = $newcontent->scalarval(); 360 $post_status = $publish->scalarval()?'publish':'draft'; 361 362 $result = wp_get_single_post($ID,ARRAY_A); 363 364 if (!$result) 365 return new xmlrpcresp(0, $xmlrpcerruser+2, // user error 2 366 "No such post '$ID'."); 367 368 $userdata = get_userdatabylogin($username); 369 $user_ID = $userdata->ID; 370 $user_level = $userdata->user_level; 371 372 $postdata=get_postdata($ID); 373 $post_authordata=get_userdata($postdata["Author_ID"]); 374 $post_author_ID=$postdata["Author_ID"]; 375 376 if (($user_ID != $post_author_ID) && ($user_level <= $post_authordata->user_level)) { 377 return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1 378 "Sorry, you do not have the right to edit this post"); 379 } 380 381 if (user_pass_ok($username,$password)) { 382 383 if ($user_level < 1) { 384 return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1 385 "Sorry, level 0 users can not edit posts"); 386 } 387 388 extract($result); 389 390 $content = $newcontent; 391 392 $post_title = xmlrpc_getposttitle($content); 393 $post_category = xmlrpc_getpostcategory($content); 394 395 $content = xmlrpc_removepostdata($content); 396 $post_content = format_to_post($content); 397 398 $postdata = compact('ID','post_content','post_title','post_category','post_status','post_excerpt'); 399 400 $result = wp_update_post($postdata); 401 402 if (!$result) 403 return new xmlrpcresp(0, $xmlrpcerruser+2, // user error 2 404 "For some strange yet very annoying reason, the entry couldn't be edited."); 405 406 if (!isset($blog_ID)) { $blog_ID = 1; } 407 408 if (isset($sleep_after_edit) && $sleep_after_edit > 0) { 409 sleep($sleep_after_edit); 410 } 411 412 413 414 return new xmlrpcresp(new xmlrpcval(true, "boolean")); 415 416 } else { 417 return new xmlrpcresp(0, $xmlrpcerruser+3, // user error 3 418 'Wrong username/password combination '.$username.' / '.starify($password)); 419 } 420 } 421 422 423 424 ### blogger.deletePost ### 425 426 $bloggerdeletepost_sig=array(array($xmlrpcBoolean, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcBoolean)); 427 428 $bloggerdeletepost_doc='Deletes a post, blogger-api like'; 429 430 function bloggerdeletepost($m) { 431 global $wpdb; 432 433 global $xmlrpcerruser; // import user errcode value 434 global $blog_ID,$cache_userdata,$use_rss; 435 global $post_default_title,$post_default_category, $sleep_after_edit; 436 $err=""; 437 438 439 $post_ID=$m->getParam(1); 440 $username=$m->getParam(2); 441 $password=$m->getParam(3); 442 $newcontent=$m->getParam(4); 443 444 $post_ID = $post_ID->scalarval(); 445 $username = $username->scalarval(); 446 $password = $password->scalarval(); 447 $newcontent = $newcontent->scalarval(); 448 449 $sql = "SELECT * FROM $wpdb->posts WHERE ID = '$post_ID'"; 450 $result = $wpdb->get_results($sql); 451 if (!$result) 452 return new xmlrpcresp(0, $xmlrpcerruser+2, // user error 2 453 "No such post '$post_ID'."); 454 455 $userdata = get_userdatabylogin($username); 456 $user_ID = $userdata->ID; 457 $user_level = $userdata->user_level; 458 459 $postdata=get_postdata($post_ID); 460 $post_authordata=get_userdata($postdata["Author_ID"]); 461 $post_author_ID=$postdata["Author_ID"]; 462 463 if (($user_ID != $post_author_ID) && ($user_level <= $post_authordata->user_level)) { 464 return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1 465 "Sorry, you do not have the right to delete this post"); 466 } 467 468 if (user_pass_ok($username,$password)) { 469 470 if ($user_level < 1) { 471 return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1 472 "Sorry, level 0 users can not delete posts"); 473 } 474 475 $result = wp_delete_post($post_ID); 476 477 if (!$result) 478 return new xmlrpcresp(0, $xmlrpcerruser+2, // user error 2 479 "For some strange yet very annoying reason, the entry couldn't be deleted."); 480 481 if (!isset($blog_ID)) { $blog_ID = 1; } 482 483 if (isset($sleep_after_edit) && $sleep_after_edit > 0) { 484 sleep($sleep_after_edit); 485 } 486 487 488 489 return new xmlrpcresp(new xmlrpcval(true,'boolean')); 490 491 } else { 492 return new xmlrpcresp(0, $xmlrpcerruser+3, // user error 3 493 'Wrong username/password combination '.$username.' / '.starify($password)); 494 } 495 } 496 497 498 499 ### blogger.getUsersBlogs ### 500 501 $bloggergetusersblogs_sig=array(array($xmlrpcArray, $xmlrpcString, $xmlrpcString, $xmlrpcString)); 502 503 $bloggergetusersblogs_doc='returns the user\'s blogs - this is a dummy function, just so that BlogBuddy and other blogs-retrieving apps work'; 504 505 function bloggergetusersblogs($m) { 506 global $wpdb; 507 // this function will have a real purpose with CafeLog's multiple blogs capability 508 509 global $xmlrpcerruser; 510 511 $user_login = $m->getParam(1); 512 $user_login = $user_login->scalarval(); 513 514 515 $sql = "SELECT user_level FROM $wpdb->users WHERE user_login = '$user_login' AND user_level > 3"; 516 $result = $wpdb->get_results($sql); 517 518 519 $is_admin = $wpdb->num_rows; 520 521 $struct = new xmlrpcval(array("isAdmin" => new xmlrpcval($is_admin,"boolean"), 522 "url" => new xmlrpcval(get_settings('home') .'/'.get_settings('blogfilename')), 523 "blogid" => new xmlrpcval("1"), 524 "blogName" => new xmlrpcval(get_settings('blogname')) 525 ),"struct"); 526 $resp = new xmlrpcval(array($struct), "array"); 527 528 return new xmlrpcresp($resp); 529 } 530 531 532 533 ### blogger.getUserInfo ### 534 535 $bloggergetuserinfo_sig=array(array($xmlrpcStruct, $xmlrpcString, $xmlrpcString, $xmlrpcString)); 536 537 $bloggergetuserinfo_doc='gives the info about a user'; 538 539 function bloggergetuserinfo($m) { 540 global $xmlrpcerruser; 541 542 543 $username=$m->getParam(1); 544 $username = $username->scalarval(); 545 546 $password=$m->getParam(2); 547 $password = $password->scalarval(); 548 549 $userdata = get_userdatabylogin($username); 550 551 if (user_pass_ok($username,$password)) { 552 $struct = new xmlrpcval(array("nickname" => new xmlrpcval($userdata->user_nickname), 553 "userid" => new xmlrpcval($userdata->ID), 554 "url" => new xmlrpcval($userdata->user_url), 555 "email" => new xmlrpcval($userdata->user_email), 556 "lastname" => new xmlrpcval($userdata->user_lastname), 557 "firstname" => new xmlrpcval($userdata->user_firstname) 558 ),"struct"); 559 $resp = $struct; 560 return new xmlrpcresp($resp); 561 562 } else { 563 return new xmlrpcresp(0, $xmlrpcerruser+3, // user error 3 564 'Wrong username/password combination '.$username.' / '.starify($password)); 565 } 566 } 567 568 569 570 ### blogger.getPost ### 571 572 $bloggergetpost_sig=array(array($xmlrpcStruct, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString)); 573 574 $bloggergetpost_doc='fetches a post, blogger-api like'; 575 576 function bloggergetpost($m) { 577 global $xmlrpcerruser; 578 579 580 $post_ID=$m->getParam(1); 581 $post_ID = $post_ID->scalarval(); 582 583 $username=$m->getParam(2); 584 $username = $username->scalarval(); 585 586 $password=$m->getParam(3); 587 $password = $password->scalarval(); 588 589 if (user_pass_ok($username,$password)) { 590 $postdata = wp_get_single_post($post_ID); 591 592 if ($postdata['post_date'] != '') { 593 $post_date = mysql2date('Ymd\TH:i:s\Z', $postdata['post_date_gmt']); 594 595 $categories = implode(',', $postdata['post_category']); 596 597 $content = '<title>'.stripslashes($postdata['post_title']).'</title>'; 598 $content .= '<category>'.$categories.'</category>'; 599 $content .= stripslashes($postdata['post_content']); 600 601 $struct = new xmlrpcval(array('userid' => new xmlrpcval($postdata['post_author']), 602 "dateCreated" => new xmlrpcval($post_date,"dateTime.iso8601"), 603 "content" => new xmlrpcval($content), 604 "postid" => new xmlrpcval($postdata["ID"]) 605 ),"struct"); 606 607 $resp = $struct; 608 return new xmlrpcresp($resp); 609 } else { 610 return new xmlrpcresp(0, $xmlrpcerruser+3, // user error 4 611 "No such post #$post_ID"); 612 } 613 } else { 614 return new xmlrpcresp(0, $xmlrpcerruser+3, // user error 3 615 'Wrong username/password combination '.$username.' / '.starify($password)); 616 } 617 } 618 619 620 621 ### blogger.getRecentPosts ### 622 623 $bloggergetrecentposts_sig=array(array($xmlrpcArray, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcInt)); 624 625 $bloggergetrecentposts_doc='fetches X most recent posts, blogger-api like'; 626 627 function bloggergetrecentposts($m) { 628 global $wpdb; 629 global $xmlrpcerruser; 630 631 error_reporting(0); // there is a bug in phpxmlrpc that makes it say there are errors while the output is actually valid, so let's disable errors for that function 632 633 634 $blogid = 1; // we don't need that yet 635 636 $numposts=$m->getParam(4); 637 $numposts = $numposts->scalarval(); 638 639 if ($numposts > 0) { 640 $limit = " LIMIT $numposts"; 641 } else { 642 $limit = ""; 643 } 644 645 $username=$m->getParam(2); 646 $username = $username->scalarval(); 647 648 $password=$m->getParam(3); 649 $password = $password->scalarval(); 650 651 if (user_pass_ok($username,$password)) { 652 653 $sql = "SELECT * FROM $wpdb->posts ORDER BY post_date_gmt DESC".$limit; 654 $result = $wpdb->get_results($sql); 655 if (!$result) 656 return new xmlrpcresp(0, $xmlrpcerruser+2, // user error 2 657 "For some strange yet very annoying reason, the entries couldn't be fetched."); 658 659 $data = new xmlrpcval("","array"); 660 661 $i = 0; 662 foreach ($result as $row) { 663 $postdata = array( 664 "ID" => $row->ID, 665 "Author_ID" => $row->post_author, 666 "Date" => $row->post_date_gmt, 667 "Content" => $row->post_content, 668 "Title" => $row->post_title, 669 "Category" => $row->post_category 670 ); 671 672 $post_date = mysql2date('Ymd\TH:i:s\Z', $postdata['Date']); 673 674 $categories = implode(',', wp_get_post_cats(1, $postdata['ID'])); 675 676 $content = "<title>".stripslashes($postdata["Title"])."</title>"; 677 $content .= "<category>".$categories."</category>"; 678 $content .= stripslashes($postdata["Content"]); 679 680 // $content = convert_chars($content,"html"); 681 // $content = $postdata["Title"]; 682 683 $category = new xmlrpcval($postdata['Category']); 684 685 $authordata = get_userdata($postdata["Author_ID"]); 686 switch($authordata["user_idmode"]) { 687 case "nickname": 688 $authorname = $authordata["user_nickname"]; 689 690 case "login": 691 $authorname = $authordata["user_login"]; 692 break; 693 case "firstname": 694 $authorname = $authordata["user_firstname"]; 695 break; 696 case "lastname": 697 $authorname = $authordata["user_lastname"]; 698 break; 699 case "namefl": 700 $authorname = $authordata["user_firstname"]." ".$authordata["user_lastname"]; 701 break; 702 case "namelf": 703 $authorname = $authordata["user_lastname"]." ".$authordata["user_firstname"]; 704 break; 705 default: 706 $authorname = $authordata["user_nickname"]; 707 break; 708 } 709 710 $struct[$i] = new xmlrpcval(array("authorName" => new xmlrpcval($authorname), 711 "userid" => new xmlrpcval($postdata["Author_ID"]), 712 "dateCreated" => new xmlrpcval($post_date,"dateTime.iso8601"), 713 "content" => new xmlrpcval($content), 714 "postid" => new xmlrpcval($postdata["ID"]), 715 'category' => $category 716 ),"struct"); 717 $i = $i + 1; 718 } 719 720 $data = array($struct[0]); 721 for ($j=1; $j<$i; $j++) { 722 array_push($data, $struct[$j]); 723 } 724 725 $resp = new xmlrpcval($data, "array"); 726 727 return new xmlrpcresp($resp); 728 729 } else { 730 return new xmlrpcresp(0, $xmlrpcerruser+3, // user error 3 731 'Wrong username/password combination '.$username.' / '.starify($password)); 732 } 733 } 734 735 736 737 ### blogger.getTemplate ### 738 739 # note: on b2, it fetches your $blogfilename, or b2.php if you didn't specify the variable 740 741 $bloggergettemplate_sig=array(array($xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString)); 742 743 $bloggergettemplate_doc='returns the default template file\'s code'; 744 745 function bloggergettemplate($m) { 746 global $xmlrpcerruser; 747 748 error_reporting(0); // there is a bug in phpxmlrpc that makes it say there are errors while the output is actually valid, so let's disable errors for that function 749 750 751 $blogid = 1; // we do not need this yet 752 753 $templateType=$m->getParam(4); 754 $templateType = $templateType->scalarval(); 755 756 $username=$m->getParam(2); 757 $username = $username->scalarval(); 758 759 $password=$m->getParam(3); 760 $password = $password->scalarval(); 761 762 $userdata = get_userdatabylogin($username); 763 764 if ($userdata->user_level < 3) { 765 return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1 766 "Sorry, users whose level is less than 3, can not edit the template."); 767 } 768 769 if (user_pass_ok($username,$password)) { 770 771 if ($templateType == "main") { 772 if (get_settings('blogfilename') != '') { 773 $file = get_settings('blogfilename'); 774 } else { 775 $file = "wp.php"; 776 } 777 } elseif ($templateType == "archiveIndex") { 778 $file = "wp.php"; 779 } 780 781 $doc_root = preg_replace('#http://.+?/#', $_SERVER['DOCUMENT_ROOT'].'/', get_settings('home')); 782 $file = $doc_root.'/'.$file; 783 784 $f = fopen($file,"r"); 785 $content = fread($f,filesize($file)); 786 fclose($f); 787 788 $content = str_replace("\n","\r\n",$content); // so it is actually editable with a windows/mac client, instead of being returned as a looooooooooong line of code 789 790 return new xmlrpcresp(new xmlrpcval("$content")); 791 792 } else { 793 return new xmlrpcresp(0, $xmlrpcerruser+3, // user error 3 794 'Wrong username/password combination '.$username.' / '.starify($password)); 795 } 796 } 797 798 799 800 ### blogger.setTemplate ### 801 802 # note: on b2, it saves that in your $blogfilename, or b2.php if you didn't specify the variable 803 804 $bloggersettemplate_sig=array(array($xmlrpcBoolean, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString)); 805 806 $bloggersettemplate_doc='saves the default template file\'s code'; 807 808 function bloggersettemplate($m) { 809 global $xmlrpcerruser; 810 811 error_reporting(0); // there is a bug in phpxmlrpc that makes it say there are errors while the output is actually valid, so let's disable errors for that function 812 813 814 $blogid = 1; // we do not need this yet 815 816 $template=$m->getParam(4); 817 $template = $template->scalarval(); 818 819 $templateType=$m->getParam(5); 820 $templateType = $templateType->scalarval(); 821 822 $username=$m->getParam(2); 823 $username = $username->scalarval(); 824 825 $password=$m->getParam(3); 826 $password = $password->scalarval(); 827 828 $userdata = get_userdatabylogin($username); 829 830 if ($userdata->user_level < 3) { 831 return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1 832 "Sorry, users whose level is less than 3, can not edit the template."); 833 } 834 835 if (user_pass_ok($username,$password)) { 836 837 if ($templateType == 'main') { 838 if (get_settings('blogfilename') != '') { 839 $file = get_settings('blogfilename'); 840 } else { 841 $file = "wp.php"; 842 } 843 } elseif ($templateType == "archiveIndex") { 844 $file = "wp.php"; 845 } 846 847 $doc_root = preg_replace('#http://.+?/#', $_SERVER['DOCUMENT_ROOT'].'/', get_settings('home')); 848 $file = $doc_root.'/'.$file; 849 850 $f = fopen($file,"w+"); 851 fwrite($f, $template); 852 fclose($f); 853 854 return new xmlrpcresp(new xmlrpcval(true, "boolean")); 855 856 } else { 857 return new xmlrpcresp(0, $xmlrpcerruser+3, // user error 3 858 'Wrong username/password combination '.$username.' / '.starify($password)); 859 } 860 } 861 862 /**** /Blogger API ****/ 863 864 865 866 /**** metaWeblog API ****/ 867 868 /********************** 869 * 870 * metaWeblog API extensions 871 * added by 872 * Dougal Campbell <dougal@gunters.org> 873 * http://dougal.gunters.org/ 874 * 875 **********************/ 876 877 $mwnewpost_sig = array(array($xmlrpcString,$xmlrpcString,$xmlrpcString,$xmlrpcString,$xmlrpcStruct,$xmlrpcBoolean)); 878 $mwnewpost_doc = 'Add a post, MetaWeblog API-style'; 879 880 function mwnewpost($params) { 881 global $xmlrpcerruser; 882 global $blog_ID, $cache_userdata; 883 global $use_rss, $post_default_title; 884 global $post_default_category,$cafelogID,$sleep_after_edit; 885 886 $xblogid = $params->getParam(0); 887 $xuser = $params->getParam(1); 888 $xpass = $params->getParam(2); 889 $xcontent = $params->getParam(3); 890 $xpublish = $params->getParam(4); 891 892 $blogid = $xblogid->scalarval(); 893 $username = $xuser->scalarval(); 894 $password = $xpass->scalarval(); 895 $contentstruct = phpxmlrpc_decode($xcontent); 896 $post_status = $xpublish->scalarval()?'publish':'draft'; 897 898 // Check login 899 if (user_pass_ok($username,$password)) { 900 $userdata = get_userdatabylogin($username); 901 $post_author = $userdata->ID; 902 $user_level = $userdata->user_level; 903 if ($user_level < 1) { 904 return new xmlrpcresp(0, $xmlrpcerruser+1, 905 "Sorry, level 0 users cannot post"); 906 } 907 908 909 $post_title = $contentstruct['title']; 910 $post_content = format_to_post($contentstruct['description']); 911 912 $post_excerpt = $contentstruct['mt_excerpt']; 913 $post_more = $contentstruct['mt_text_more']; 914 915 $comment_status = $contentstruct['mt_allow_comments']?'open':'closed'; 916 $ping_status = $contentstruct['mt_allow_pings']?'open':'closed'; 917 918 if ($post_more) { 919 $post_content = $post_content . "\n<!--more-->\n" . $post_more; 920 } 921 922 // Do some timestamp voodoo 923 $dateCreated = $contentstruct['dateCreated']; 924 if (!empty($dateCreated)) { 925 $post_date = get_date_from_gmt(iso8601_to_datetime($dateCreated)); 926 $post_date_gmt = iso8601_to_datetime($dateCreated, GMT); 927 } else { 928 $post_date = current_time('mysql'); 929 $post_date_gmt = current_time('mysql', 1); 930 } 931 932 $catnames = $contentstruct['categories']; 933 // FIXME: commented until proper fix // logio("O","Post cats: " . print_r($catnames,true)); 934 $post_category = array(); 935 if ($catnames) { 936 foreach ($catnames as $cat) { 937 $post_category[] = get_cat_ID($cat); 938 } 939 } else { 940 $post_category[] = 1; 941 } 942 943 // We've got all the data -- post it: 944 $postarr = compact('post_author','post_date','post_date_gmt','post_content','post_title','post_category','post_status','post_excerpt','comment_status','ping_status'); 945 946 $post_ID = wp_insert_post($postarr); 947 948 if (!$post_ID) { 949 return new xmlrpcresp(0, $xmlrpcerruser+2, "For some strange yet very annoying reason, your entry could not be posted."); 950 } 951 952 if (!isset($blog_ID)) { $blog_ID = 1; } 953 954 if (isset($sleep_after_edit) && $sleep_after_edit > 0) { 955 sleep($sleep_after_edit); 956 } 957 958 pingback($content, $post_ID); 959 trackback_url_list($contentstruct['mt_tb_ping_urls'],$post_ID); 960 961 logIO("O","(MW) Posted ! ID: $post_ID"); 962 $myResp = new xmlrpcval($post_ID,"string"); 963 964 return new xmlrpcresp($myResp); 965 966 } else { 967 logIO("O","(MW) Wrong username/password combination <b>$username / $password</b>"); 968 return new xmlrpcresp(0, $xmlrpcerruser+3, // user error 3 969 'Wrong username/password combination '.$username.' / '.starify($password)); 970 } 971 } 972 973 $mweditpost_sig = array(array($xmlrpcBoolean,$xmlrpcString,$xmlrpcString,$xmlrpcString,$xmlrpcStruct,$xmlrpcBoolean)); 974 $mweditpost_doc = 'Edit a post, MetaWeblog API-style'; 975 976 function mweditpost ($params) { // ($postid, $user, $pass, $content, $publish) 977 global $xmlrpcerruser; 978 979 $xpostid = $params->getParam(0); 980 $xuser = $params->getParam(1); 981 $xpass = $params->getParam(2); 982 $xcontent = $params->getParam(3); 983 $xpublish = $params->getParam(4); 984 985 $ID = $xpostid->scalarval(); 986 $username = $xuser->scalarval(); 987 $password = $xpass->scalarval(); 988 $contentstruct = phpxmlrpc_decode($xcontent); 989 $postdata = wp_get_single_post($ID,ARRAY_A); 990 991 if (!$postdata) 992 return new xmlrpcresp(0, $xmlrpcerruser+2, // user error 2 993 "No such post $ID."); 994 995 $userdata = get_userdatabylogin($username); 996 $user_ID = $userdata->ID; 997 $user_level = $userdata->user_level; 998 $time_difference = get_settings('gmt_offset'); 999 1000 $post_author_ID = $postdata['post_author']; 1001 $post_authordata = get_userdata($post_author_ID); 1002 1003 if (($user_ID != $post_author_ID) && ($user_level <= $post_authordata->user_level)) { 1004 return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1 1005 "Sorry, you do not have the right to edit this post."); 1006 } 1007 1008 // Check login 1009 if (user_pass_ok($username,$password)) { 1010 if ($user_level < 1) { 1011 return new xmlrpcresp(0, $xmlrpcerruser+1, 1012 1013 "Sorry, level 0 users cannot edit posts"); 1014 } 1015 1016 extract($postdata); 1017 1018 $post_title = $contentstruct['title']; 1019 $post_content = format_to_post($contentstruct['description']); 1020 $catnames = $contentstruct['categories']; 1021 1022 if ($catnames) { 1023 foreach ($catnames as $cat) { 1024 $post_category[] = get_cat_ID($cat); 1025 } 1026 } 1027 1028 $post_excerpt = $contentstruct['mt_excerpt']; 1029 $post_more = $contentstruct['mt_text_more']; 1030 $post_status = $xpublish->scalarval()?'publish':'draft'; 1031 if ($post_more) { 1032 $post_content = $post_content . "\n<!--more-->\n" . $post_more; 1033 } 1034 $comment_status = (1 == $contentstruct['mt_allow_comments'])?'open':'closed'; 1035 $ping_status = $contentstruct['mt_allow_pings']?'open':'closed'; 1036 1037 // Do some timestamp voodoo 1038 $dateCreated = $contentstruct['dateCreated']; 1039 if (!empty($dateCreated)) { 1040 $post_date = get_date_from_gmt(iso8601_to_datetime($dateCreated)); 1041 $post_date_gmt = iso8601_to_datetime($dateCreated, GMT); 1042 } else { 1043 $post_date = $postdata['post_date']; 1044 $post_date_gmt = $postdata['post_date_gmt']; 1045 } 1046 1047 // We've got all the data -- post it: 1048 $newpost = compact('ID','post_content','post_title','post_category','post_status','post_excerpt','comment_status','ping_status','post_date','post_date_gmt'); 1049 1050 $post_ID = wp_update_post($newpost); 1051 1052 if (!$post_ID) { 1053 return new xmlrpcresp(0, $xmlrpcerruser+2, "For some strange yet very annoying reason, your entry could not be posted."); 1054 } 1055 1056 if (!isset($blog_ID)) { $blog_ID = 1; } 1057 1058 if (isset($sleep_after_edit) && $sleep_after_edit > 0) { 1059 sleep($sleep_after_edit); 1060 } 1061 1062 pingback($content, $post_ID); 1063 trackback_url_list($contentstruct['mt_tb_ping_urls'],$post_ID); 1064 1065 logIO("O","(MW) Edited ! ID: $post_ID"); 1066 $myResp = new xmlrpcval(true,"boolean"); 1067 1068 return new xmlrpcresp($myResp); 1069 1070 } else { 1071 logIO("O","(MW) Wrong username/password combination <b>$username / $password</b>"); 1072 return new xmlrpcresp(0, $xmlrpcerruser+3, // user error 3 1073 'Wrong username/password combination '.$username.' / '.starify($password)); 1074 } 1075 } 1076 1077 $mwgetpost_sig = array(array($xmlrpcStruct,$xmlrpcString,$xmlrpcString,$xmlrpcString)); 1078 $mwegetpost_doc = 'Get a post, MetaWeblog API-style'; 1079 1080 function mwgetpost ($params) { // ($postid, $user, $pass) 1081 global $xmlrpcerruser; 1082 1083 $xpostid = $params->getParam(0); 1084 $xuser = $params->getParam(1); 1085 $xpass = $params->getParam(2); 1086 1087 $post_ID = $xpostid->scalarval(); 1088 $username = $xuser->scalarval(); 1089 $password = $xpass->scalarval(); 1090 1091 // Check login 1092 if (user_pass_ok($username,$password)) { 1093 $postdata = wp_get_single_post($post_ID, ARRAY_A); 1094 1095 if ($postdata['post_date'] != '') { 1096 1097 $post_date = mysql2date('Ymd\TH:i:s\Z', $postdata['post_date_gmt']); 1098 1099 $catids = wp_get_post_cats('', $post_ID); 1100 foreach($catids as $catid) { 1101 $catname = get_cat_name($catid); 1102 $catnameenc = new xmlrpcval($catname); 1103 $catlist[] = $catnameenc; 1104 } 1105 $post = get_extended($postdata['post_content']); 1106 $allow_comments = ('open' == $postdata['comment_status'])?1:0; 1107 $allow_pings = ('open' == $postdata['ping_status'])?1:0; 1108 1109 $resp = array( 1110 'link' => new xmlrpcval(post_permalink($post_ID)), 1111 'title' => new xmlrpcval($postdata['post_title']), 1112 'description' => new xmlrpcval($post['main']), 1113 'dateCreated' => new xmlrpcval($post_date,'dateTime.iso8601'), 1114 'userid' => new xmlrpcval($postdata['post_author']), 1115 'postid' => new xmlrpcval($postdata['ID']), 1116 'content' => new xmlrpcval($postdata['post_content']), 1117 'permalink' => new xmlrpcval(post_permalink($post_ID)), 1118 'categories' => new xmlrpcval($catlist,'array'), 1119 'mt_excerpt' => new xmlrpcval($postdata['post_excerpt']), 1120 'mt_allow_comments' => new xmlrpcval($allow_comments,'int'), 1121 'mt_allow_pings' => new xmlrpcval($allow_pings,'int'), 1122 'mt_text_more' => new xmlrpcval($post['extended']) 1123 ); 1124 1125 $resp = new xmlrpcval($resp,'struct'); 1126 1127 return new xmlrpcresp($resp); 1128 } else { 1129 return new xmlrpcresp(0, $xmlrpcerruser+3, // user error 4 1130 "No such post #$post_ID"); 1131 } 1132 } else { 1133 return new xmlrpcresp(0, $xmlrpcerruser+3, // user error 3 1134 'Wrong username/password combination '.$username.' / '.starify($password)); 1135 } 1136 1137 } 1138 1139 $mwrecentposts_sig = array(array($xmlrpcArray,$xmlrpcString,$xmlrpcString,$xmlrpcString,$xmlrpcInt)); 1140 $mwerecentposts_doc = 'Get recent posts, MetaWeblog API-style'; 1141 1142 function mwrecentposts ($params) { // ($blogid, $user, $pass, $num) 1143 global $xmlrpcerruser; 1144 1145 $xblogid = $params->getParam(0); 1146 $xuser = $params->getParam(1); 1147 $xpass = $params->getParam(2); 1148 $xnum = $params->getParam(3); 1149 1150 $blogid = $xblogid->scalarval(); 1151 $username = $xuser->scalarval(); 1152 $password = $xpass->scalarval(); 1153 $num = $xnum->scalarval(); 1154 1155 // Check login 1156 if (user_pass_ok($username,$password)) { 1157 1158 $postlist = wp_get_recent_posts($num); 1159 1160 // Build response packet. We can't just use xmlrpc_encode, 1161 // because of the dateCreated field, which must be a date type. 1162 1163 // Encode each entry of the array. 1164 foreach($postlist as $entry) { 1165 1166 $isoString = mysql2date('Ymd\TH:i:s\Z', $entry['post_date_gmt']); 1167 $date = new xmlrpcval($isoString,"dateTime.iso8601"); 1168 $userid = new xmlrpcval($entry['post_author']); 1169 $content = new xmlrpcval($entry['post_content']); 1170 $excerpt = new xmlrpcval($entry['post_excerpt']); 1171 1172 // $pcat = stripslashes(get_cat_name($entry['post_category'])); 1173 1174 $catlist = array(); 1175 $catids = wp_get_post_cats('', $entry['ID']); 1176 foreach($catids as $catid) { 1177 $catname = get_cat_name($catid); 1178 $catnameenc = new xmlrpcval($catname); 1179 $catlist[] = $catnameenc; 1180 } 1181 1182 // For multiple cats, we might do something like 1183 // this in the future: 1184 //$catstruct['description'] = $pcat; 1185 //$catstruct['categoryId'] = $entry['post_category']; 1186 //$catstruct['categoryName'] = $pcat; 1187 //$catstruct['isPrimary'] = TRUE; 1188 1189 //$catstruct2 = phpxmlrpc_encode($catstruct); 1190 1191 // $categories = new xmlrpcval(array(new xmlrpcval($pcat)),'array'); 1192 $categories = new xmlrpcval($catlist, 'array'); 1193 1194 $post = get_extended($entry['post_content']); 1195 1196 $postid = new xmlrpcval($entry['ID']); 1197 $title = new xmlrpcval(stripslashes($entry['post_title'])); 1198 $description = new xmlrpcval(stripslashes($post['main'])); 1199 $link = new xmlrpcval(post_permalink($entry['ID'])); 1200 $permalink = $link; 1201 1202 $extended = new xmlrpcval(stripslashes($post['extended'])); 1203 1204 $allow_comments = new xmlrpcval((('open' == $entry['comment_status'])?1:0),'int'); 1205 $allow_pings = new xmlrpcval((('open' == $entry['ping_status'])?1:0),'int'); 1206 1207 $encode_arr = array( 1208 'dateCreated' => $date, 1209 'userid' => $userid, 1210 'postid' => $postid, 1211 'categories' => $categories, 1212 'title' => $title, 1213 'description' => $description, 1214 'link' => $link, 1215 'permalink' => $permalink, 1216 'mt_excerpt' => $excerpt, 1217 'mt_allow_comments' => $allow_comments, 1218 'mt_allow_pings' => $allow_pings, 1219 'mt_text_more' => $extended 1220 ); 1221 1222 $xmlrpcpostarr[] = new xmlrpcval($encode_arr,"struct"); 1223 } 1224 1225 // Now convert that to an xmlrpc array type 1226 $myResp = new xmlrpcval($xmlrpcpostarr,"array"); 1227 1228 return new xmlrpcresp($myResp); 1229 } else { 1230 return new xmlrpcresp(0, $xmlrpcerruser+3, // user error 3 1231 'Wrong username/password combination '.$username.' / '.starify($password)); 1232 } 1233 } 1234 1235 1236 $mwgetcats_sig = array(array($xmlrpcArray,$xmlrpcString,$xmlrpcString,$xmlrpcString)); 1237 $mwgetcats_doc = 'Get a post, MetaWeblog API-style'; 1238 1239 function mwgetcats ($params) { // ($blogid, $user, $pass) 1240 global $xmlrpcerruser,$wpdb; 1241 global $querystring_start, $querystring_equal, $querystring_separator; 1242 1243 $blog_URL = get_settings('home') . '/' . get_settings('blogfilename'); 1244 1245 $arr = array(); 1246 1247 if ($cats = $wpdb->get_results("SELECT cat_ID,cat_name FROM $wpdb->categories",ARRAY_A)) { 1248 foreach ($cats as $cat) { 1249 $struct['categoryId'] = $cat['cat_ID']; 1250 $struct['description'] = $cat['cat_name']; 1251 $struct['categoryName'] = $cat['cat_name']; 1252 $struct['htmlUrl'] = htmlspecialchars($blog_URL . $querystring_start . 'cat' . $querystring_equal . $cat['cat_ID']); 1253 $struct['rssUrl'] = ''; // will probably hack alexking's stuff in here 1254 1255 $arr[] = phpxmlrpc_encode($struct); 1256 } 1257 } 1258 1259 $resp = new xmlrpcval($arr,'array'); 1260 1261 return new xmlrpcresp($resp); 1262 } 1263 1264 1265 $mwnewmedia_sig = array(array($xmlrpcStruct,$xmlrpcString,$xmlrpcString,$xmlrpcString,$xmlrpcStruct)); 1266 $mwnewmedia_doc = 'Upload image or other binary data, MetaWeblog API-style (unimplemented)'; 1267 1268 function mwnewmedia($params) { // ($blogid, $user, $pass, $struct) 1269 global $xmlrpcerruser; 1270 1271 return new xmlrpcresp(0, $xmlrpcerruser+10, // user error 10 1272 'metaWeblog.newMediaObject not implemented (yet)'); 1273 } 1274 1275 1276 /**** /MetaWeblog API ****/ 1277 1278 1279 /**** MovableType API ****/ 1280 1281 /********************** 1282 * 1283 * MovableType API extensions 1284 * added by 1285 * Dougal Campbell <dougal@gunters.org> 1286 * http://dougal.gunters.org/ 1287 * 1288 * DONE: 1289 * mt.getCategoryList 1290 * mt.setPostCategories 1291 * mt.supportedMethods 1292 * mt.getPostCategories 1293 * mt.publishPost 1294 * mt.getRecentPostTitles 1295 * extend metaWeblog.newPost 1296 * extend metaWeblog.editPost 1297 * extend metaWeblog.getPost 1298 * extend metaWeblog.getRecentPosts 1299 * 1300 * PARTIALLY DONE: 1301 * mt.supportedTextFilters // empty stub, because WP doesn't support per-post text filters at this time 1302 * mt.getTrackbackPings // another stub. 1303 * metaWeblog.newMediaObject // ditto. For now. 1304 * 1305 **********************/ 1306 1307 $mt_supportedMethods_sig = array(array($xmlrpcArray)); 1308 $mt_supportedMethods_doc = 'Retrieve information about the XML-RPC methods supported by the server.'; 1309 1310 // ripped out of system.listMethods 1311 function mt_supportedMethods($params) { 1312 global $dispatch_map, $xmlrpcerr, $xmlrpcstr, $_xmlrpcs_dmap; 1313 $v=new xmlrpcval(); 1314 $dmap=$dispatch_map; 1315 $outAr=array(); 1316 for(reset($dmap); list($key, $val)=each($dmap); ) { 1317 $outAr[]=new xmlrpcval($key, "string"); 1318 } 1319 $dmap=$_xmlrpcs_dmap; 1320 for(reset($dmap); list($key, $val)=each($dmap); ) { 1321 $outAr[]=new xmlrpcval($key, "string"); 1322 } 1323 $v->addArray($outAr); 1324 return new xmlrpcresp($v); 1325 1326 } 1327 1328 $mt_getPostCategories_sig = array(array($xmlrpcArray, $xmlrpcString, $xmlrpcString, $xmlrpcString)); 1329 $mt_getPostCategories_doc = "Returns a list of all categories to which the post is assigned."; 1330 1331 function mt_getPostCategories($params) { 1332 global $xmlrpcusererr; 1333 1334 $xpostid = $params->getParam(0); 1335 $xuser = $params->getParam(1); 1336 $xpass = $params->getParam(2); 1337 1338 $post_ID = $xpostid->scalarval(); 1339 $username = $xuser->scalarval(); 1340 $password = $xpass->scalarval(); 1341 1342 if (user_pass_ok($username,$password)) { 1343 $catids = wp_get_post_cats('1', $post_ID); 1344 1345 // The first category listed will be set as primary 1346 $struct['isPrimary'] = true; 1347 foreach($catids as $catid) { 1348 $struct['categoryId'] = $catid; 1349 $struct['categoryName'] = get_cat_name($catid); 1350 1351 $resp_struct[] = phpxmlrpc_encode($struct); 1352 $struct['isPrimary'] = false; 1353 } 1354 1355 // Return an array of structs 1356 $resp_array = new xmlrpcval($resp_struct,'array'); 1357 1358 return new xmlrpcresp($resp_array); 1359 1360 } else { 1361 return new xmlrpcresp(0, $xmlrpcerruser+3, // user error 3 1362 'Wrong username/password combination '.$username.' / '.starify($password)); 1363 } 1364 } 1365 1366 $mt_setPostCategories_sig = array(array($xmlrpcBoolean, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcArray)); 1367 $mt_setPostCategories_doc = "Sets the categories for a post"; 1368 1369 function mt_setPostCategories($params) { 1370 global $xmlrpcusererr; 1371 1372 $xpostid = $params->getParam(0); 1373 $xuser = $params->getParam(1); 1374 $xpass = $params->getParam(2); 1375 $xcats = $params->getParam(3); 1376 1377 $post_ID = $xpostid->scalarval(); 1378 $username = $xuser->scalarval(); 1379 $password = $xpass->scalarval(); 1380 $cats = phpxmlrpc_decode($xcats); 1381 1382 foreach($cats as $cat) { 1383 $catids[] = $cat['categoryId']; 1384 } 1385 1386 if (user_pass_ok($username,$password)) { 1387 wp_set_post_cats('', $post_ID, $catids); 1388 1389 return new xmlrpcresp(new xmlrpcval(true,'boolean')); 1390 } else { 1391 return new xmlrpcresp(0, $xmlrpcerruser+3, // user error 3 1392 'Wrong username/password combination '.$username.' / '.starify($password)); 1393 } 1394 } 1395 1396 $mt_publishPost_sig = array(array($xmlrpcBoolean, $xmlrpcString, $xmlrpcString, $xmlrpcString)); 1397 $mt_publishPost_doc = "Publish (rebuild) all of the static files related to an entry. Equivalent to saving an entry in the system (but without the ping)."; 1398 1399 function mt_publishPost($params) { 1400 global $xmlrpcusererr; 1401 1402 $xpostid = $params->getParam(0); 1403 $xuser = $params->getParam(1); 1404 $xpass = $params->getParam(2); 1405 1406 $post_ID = $xpostid->scalarval(); 1407 $username = $xuser->scalarval(); 1408 $password = $xpass->scalarval(); 1409 1410 if (user_pass_ok($username,$password)) { 1411 $postdata = wp_get_single_post($post_ID,ARRAY_A); 1412 1413 $postdata['post_status'] = 'publish'; 1414 1415 // retain old cats 1416 $cats = wp_get_post_cats('',$post_ID); 1417 $postdata['post_category'] = $cats; 1418 1419 $result = wp_update_post($postdata); 1420 1421 return new xmlrpcresp(new xmlrpcval($result,'boolean')); 1422 } else { 1423 return new xmlrpcresp(0, $xmlrpcerruser+3, // user error 3 1424 'Wrong username/password combination '.$username.' / '.starify($password)); 1425 } 1426 } 1427 1428 $mt_getRecentPostTitles_sig = array(array($xmlrpcArray,$xmlrpcString,$xmlrpcString,$xmlrpcString,$xmlrpcInt)); 1429 $mt_getRecentPostTitles_doc = "Returns a bandwidth-friendly list of the most recent posts in the system."; 1430 1431 function mt_getRecentPostTitles($params) { 1432 global $xmlrpcusererr, $wpdb; 1433 1434 $xblogid = $params->getParam(0); 1435 $xuser = $params->getParam(1); 1436 $xpass = $params->getParam(2); 1437 $xnumposts = $params->getParam(3); 1438 1439 $blogid = $xblogid->scalarval(); 1440 $username = $xuser->scalarval(); 1441 $password = $xpass->scalarval(); 1442 $numposts = intval($xnumposts->scalarval()); 1443 1444 if (user_pass_ok($username,$password)) { 1445 $sql = "SELECT post_date, post_date_gmt, post_author, ID, post_title FROM $wpdb->posts ORDER BY post_date_gmt DESC LIMIT $numposts"; 1446 $posts = $wpdb->get_results($sql,ARRAY_A); 1447 1448 foreach($posts as $post) { 1449 1450 $post_date = mysql2date('Ymd\TH:i:s\Z', $post['post_date_gmt']); 1451 1452 $struct['dateCreated'] = new xmlrpcval($post_date, 'dateTime.iso8601'); 1453 $struct['userid'] = new xmlrpcval($post['post_author'], 'string'); 1454 $struct['postid'] = new xmlrpcval($post['ID'], 'string'); 1455 $struct['title'] = new xmlrpcval($post['post_title'], 'string'); 1456 1457 $result[] = $struct; 1458 } 1459 1460 return new xmlrpcresp(new xmlrpcval($results,'array')); 1461 1462 } else { 1463 return new xmlrpcresp(0, $xmlrpcerruser+3, // user error 3 1464 'Wrong username/password combination '.$username.' / '.starify($password)); 1465 } 1466 } 1467 1468 1469 $mt_supportedTextFilters_sig = array(array($xmlrpcArray)); 1470 $mt_supportedTextFilters_doc = "Retrieve information about the text formatting plugins supported by the server. (not implemented)"; 1471 1472 function mt_supportedTextFilters($params) { 1473 // This should probably check the status of the 'use_bbcode' 1474 // and 'use_gmcode' config options. 1475 1476 return new xmlrpcresp(new xmlrpcval(array(),'array')); 1477 } 1478 1479 1480 1481 $mt_getTrackbackPings_sig = array(array($xmlrpcArray,$xmlrpcString)); 1482 $mt_getTrackbackPings_doc = "Retrieve the list of Trackback pings posted to a particular entry. (not implemented)"; 1483 1484 function mt_getTrackbackPings($params) { 1485 $struct['pingTitle'] = ''; 1486 $struct['pingURL'] = ''; 1487 $struct['pingIP'] = ''; 1488 1489 $xmlstruct = phpxmlrpc_encode($struct); 1490 1491 return new xmlrpcresp(new xmlrpcval(array($xmlstruct),'array')); 1492 } 1493 1494 1495 1496 /**** /MovableType API ****/ 1497 1498 1499 /**** PingBack functions ****/ 1500 1501 $pingback_ping_sig = array(array($xmlrpcString, $xmlrpcString, $xmlrpcString)); 1502 1503 $pingback_ping_doc = 'Gets a pingback and registers it as a comment prefixed by <pingback />'; 1504 1505 function pingback_ping($m) { // original code by Mort 1506 // (http://mort.mine.nu:8080) 1507 global $wpdb, $wp_version; 1508 1509 //$log = debug_fopen('./xmlrpc.log', 'w'); 1510 1511 $title=''; 1512 1513 $pagelinkedfrom = $m->getParam(0); 1514 $pagelinkedfrom = $pagelinkedfrom->scalarval(); 1515 1516 $pagelinkedto = $m->getParam(1); 1517 $pagelinkedto = $pagelinkedto->scalarval(); 1518 1519 $pagelinkedfrom = str_replace('&', '&', $pagelinkedfrom); 1520 $pagelinkedto = preg_replace('#&([^amp\;])#is', '&$1', $pagelinkedto); 1521 1522 //debug_fwrite($log, 'BEGIN '.time().' - '.date('Y-m-d H:i:s')."\n\n"); 1523 //debug_fwrite($log, 'Page linked from: '.$pagelinkedfrom."\n"); 1524 //debug_fwrite($log, 'Page linked to: '.$pagelinkedto."\n"); 1525 1526 $messages = array( 1527 htmlentities("Pingback from ".$pagelinkedfrom." to " 1528 . $pagelinkedto . " registered. Keep the web talking! :-)"), 1529 htmlentities("We can't find the URL to the post you are trying to " 1530 . "link to in your entry. Please check how you wrote the post's permalink in your entry."), 1531 htmlentities("We can't find the post you are trying to link to." 1532 . " Please check the post's permalink.") 1533 ); 1534 1535 $message = $messages[0]; 1536 1537 // Check if the page linked to is in our site 1538 $pos1 = strpos($pagelinkedto, str_replace('http://', '', str_replace('www.', '', get_settings('home')))); 1539 if($pos1) { 990 wp_set_post_cats('', $post_ID, $catids); 991 992 return true; 993 } 994 995 996 /* mt.supportedMethods ...returns an array of methods supported by this server */ 997 function mt_supportedMethods($args) { 998 999 $supported_methods = array(); 1000 foreach($this->methods as $key=>$value) { 1001 $supported_methods[] = $key; 1002 } 1003 1004 return $supported_methods; 1005 } 1006 1007 1008 /* mt.supportedTextFilters ...returns an empty array because we don't 1009 support per-post text filters yet */ 1010 function mt_supportedTextFilters($args) { 1011 return array(); 1012 } 1013 1014 1015 /* mt.getTrackbackPings ...returns trackbacks sent to a given post */ 1016 function mt_getTrackbackPings($args) { 1017 1018 global $wpdb; 1019 1020 $post_ID = intval($args); 1021 1022 $actual_post = wp_get_single_post($post_ID, ARRAY_A); 1023 1024 if (!$actual_post) { 1025 return new IXR_Error(404, 'Sorry, no such post.'); 1026 } 1027 1028 $comments = $wpdb->get_results("SELECT comment_author_url, comment_content, comment_author_IP, comment_type FROM $wpdb->comments WHERE comment_post_ID = $post_ID"); 1029 1030 if (!$comments) { 1031 return array(); 1032 } 1033 1034 $trackback_pings = array(); 1035 foreach($comments as $comment) { 1036 if ((strpos($comment->comment_content, '<trackback />') === 0) 1037 || ('trackback' == $comment->comment_type)) { 1038 // FIXME: would be nicer to have a comment_title field? 1039 // FIXME: assumption: here we make the assumption that trackback 1040 // titles are stored as <strong>title</strong> 1041 $content = str_replace('<trackback />', '', $comment->comment_content); 1042 $title = substr($content, 8, (strpos($content, '</strong>') - 8)); 1043 $trackback_pings[] = array( 1044 'pingTitle' => $title, 1045 'pingURL' => $comment->comment_author_url, 1046 'pingIP' => $comment->comment_author_IP 1047 ); 1048 } 1049 } 1050 1051 return $trackback_pings; 1052 } 1053 1054 1055 /* mt.publishPost ...sets a post's publish status to 'publish' */ 1056 function mt_publishPost($args) { 1057 1058 $post_ID = $args[0]; 1059 $user_login = $args[1]; 1060 $user_pass = $args[2]; 1061 1062 if (!$this->login_pass_ok($user_login, $user_pass)) { 1063 return $this->error; 1064 } 1065 1066 $user_data = get_userdatabylogin($user_login); 1067 if (!user_can_edit_post($user_data->ID, $post_ID)) { 1068 return new IXR_Error(401, 'Sorry, you can not edit this post.'); 1069 } 1070 1071 $postdata = wp_get_single_post($post_ID,ARRAY_A); 1072 1073 $postdata['post_status'] = 'publish'; 1074 1075 // retain old cats 1076 $cats = wp_get_post_cats('',$post_ID); 1077 $postdata['post_category'] = $cats; 1078 1079 $result = wp_update_post($postdata); 1080 1081 return $result; 1082 } 1083 1084 1085 1086 /* PingBack functions 1087 * specs on www.hixie.ch/specs/pingback/pingback 1088 */ 1089 1090 /* pingback.ping gets a pingback and registers it */ 1091 function pingback_ping($args) { 1092 // original code by Mort (http://mort.mine.nu:8080 -- site seems dead) 1093 // refactored to return error codes and avoid deep ifififif headaches 1094 global $wpdb, $wp_version; 1095 1096 $pagelinkedfrom = $args[0]; 1097 $pagelinkedto = $args[1]; 1098 1099 $title = ''; 1100 1101 $pagelinkedfrom = str_replace('&', '&', $pagelinkedfrom); 1102 $pagelinkedto = preg_replace('#&([^amp\;])#is', '&$1', $pagelinkedto); 1103 1104 $error_code = -1; 1105 1106 // Check if the page linked to is in our site 1107 $pos1 = strpos($pagelinkedto, str_replace('http://', '', str_replace('www.', '', get_settings('home')))); 1108 if(!$pos1) { 1109 return new IXR_Error(0, ''); 1110 } 1111 1540 1112 1541 1113 // let's find which post is linked to 1114 // FIXME: does url_to_postid() cover all these cases already? 1115 // if so, then let's use it and drop the old code. 1542 1116 $urltest = parse_url($pagelinkedto); 1543 1117 if ($post_ID = url_to_postid($pagelinkedto)) { 1544 1118 $way = 'url_to_postid()'; 1545 } 1546 elseif (preg_match('#p/[0-9]{1,}#', $urltest['path'], $match)) { 1119 } elseif (preg_match('#p/[0-9]{1,}#', $urltest['path'], $match)) { 1547 1120 // the path defines the post_ID (archives/p/XXXX) 1548 1121 $blah = explode('/', $match[0]); … … 1568 1141 $title = preg_replace('/[^a-zA-Z0-9]/', '.', $urltest['fragment']); 1569 1142 $sql = "SELECT ID FROM $wpdb->posts WHERE post_title RLIKE '$title'"; 1570 $post_ID = $wpdb->get_var($sql) or die("Query: $sql\n\nError: "); 1143 if (! ($post_ID = $wpdb->get_var($sql)) ) { 1144 // returning unknown error '0' is better than die()ing 1145 return new IXR_Error(0, ''); 1146 } 1571 1147 $way = 'from the fragment (title)'; 1572 1148 } 1573 1149 } else { 1574 1150 // TODO: Attempt to extract a post ID from the given URL 1575 $post_ID = -1;1576 $way = 'no match';1577 } 1151 return new IXR_Error(33, 'The specified target URI cannot be used as a target. It either doesn\'t exist, or it is not a pingback-enabled resource.'); 1152 } 1153 1578 1154 1579 1155 logIO("O","(PB) URI='$pagelinkedto' ID='$post_ID' Found='$way'"); 1580 1581 //debug_fwrite($log, "Found post ID $way: $post_ID\n");1582 1156 1583 1157 $sql = 'SELECT post_author FROM '.$wpdb->posts.' WHERE ID = '.$post_ID; 1584 1158 $result = $wpdb->get_results($sql); 1585 1159 1160 if (!$wpdb->num_rows) { 1161 // Post_ID not found 1162 return new IXR_Error(33, 'The specified target URI cannot be used as a target. It either doesn\'t exist, or it is not a pingback-enabled resource.'); 1163 } 1164 1165 1166 // Let's check that the remote site didn't already pingback this entry 1167 $sql = 'SELECT * FROM '.$wpdb->comments.' 1168 WHERE comment_post_ID = '.$post_ID.' 1169 AND comment_author_url = \''.$pagelinkedfrom.'\' 1170 AND comment_type = \'pingback\''; 1171 $result = $wpdb->get_results($sql); 1172 //return($sql); 1173 1586 1174 if ($wpdb->num_rows) { 1587 1588 //debug_fwrite($log, 'Post exists'."\n"); 1589 1590 // Let's check that the remote site didn't already pingback this entry 1591 $sql = 'SELECT * FROM '.$wpdb->comments.' 1592 WHERE comment_post_ID = '.$post_ID.' 1593 AND comment_author_url = \''.$pagelinkedfrom.'\' 1594 AND comment_content LIKE \'%<pingback />%\''; 1595 $result = $wpdb->get_results($sql); 1596 1597 if ($wpdb->num_rows || (1==1)) { 1598 1599 // very stupid, but gives time to the 'from' server to publish ! 1600 sleep(1); 1601 1602 // Let's check the remote site 1603 $fp = @fopen($pagelinkedfrom, 'r'); 1604 1605 $puntero = 4096; 1606 while($remote_read = fread($fp, $puntero)) { 1607 $linea .= $remote_read; 1608 } 1609 // Work around bug in strip_tags(): 1610 $linea = str_replace('<!DOCTYPE','<DOCTYPE',$linea); 1611 $linea = strip_tags($linea, '<title><a>'); 1612 $linea = strip_all_but_one_link($linea, $pagelinkedto); 1613 // I don't think we need this? -- emc3 1614 //$linea = preg_replace('#&([^amp\;])#is', '&$1', $linea); 1615 if (empty($matchtitle)) { 1616 preg_match('|<title>([^<]*?)</title>|is', $linea, $matchtitle); 1617 } 1618 $pos2 = strpos($linea, $pagelinkedto); 1619 $pos3 = strpos($linea, str_replace('http://www.', 'http://', $pagelinkedto)); 1620 if (is_integer($pos2) || is_integer($pos3)) { 1621 //debug_fwrite($log, 'The page really links to us :)'."\n"); 1622 $pos4 = (is_integer($pos2)) ? $pos2 : $pos3; 1623 $start = $pos4-100; 1624 $context = substr($linea, $start, 250); 1625 $context = str_replace("\n", ' ', $context); 1626 $context = str_replace('&', '&', $context); 1627 } else { 1628 //debug_fwrite($log, 'The page doesn\'t link to us, here\'s an excerpt :'."\n\n".$linea."\n\n"); 1629 } 1630 //} 1631 //debug_fwrite($log, '*****'."\n\n"); 1632 fclose($fp); 1633 1634 if (!empty($context)) { 1635 // Check if pings are on, inelegant exit 1636 $pingstatus = $wpdb->get_var("SELECT ping_status FROM $wpdb->posts WHERE ID = $post_ID"); 1637 if ('closed' == $pingstatus) die('Sorry, pings are turned off for this post.'); 1638 1639 $pagelinkedfrom = preg_replace('#&([^amp\;])#is', '&$1', $pagelinkedfrom); 1640 $title = (!strlen($matchtitle[1])) ? $pagelinkedfrom : $matchtitle[1]; 1641 $original_context = strip_tags($context); 1642 $context = '<pingback />[...] '; 1643 $context = htmlspecialchars($original_context); 1644 $context .= ' [...]'; 1645 $original_pagelinkedfrom = $pagelinkedfrom; 1646 $pagelinkedfrom = addslashes($pagelinkedfrom); 1647 $original_title = $title; 1648 $title = addslashes(strip_tags(trim($title))); 1649 $user_ip = $_SERVER['REMOTE_ADDR']; 1650 $user_agent = addslashes($_SERVER['HTTP_USER_AGENT']); 1651 $now = current_time('mysql'); 1652 $now_gmt = current_time('mysql', 1); 1653 if( check_comment($title, '', $pagelinkedfrom, $context, $user_ip, $user_agent) ) { 1654 $approved = 1; 1655 } else { 1656 $approved = 0; 1657 } 1658 $consulta = $wpdb->query("INSERT INTO $wpdb->comments 1659 (comment_post_ID, comment_author, comment_author_url, comment_author_IP, comment_date, comment_date_gmt, comment_content, comment_approved, comment_agent) 1660 VALUES 1661 ($post_ID, '$title', '$pagelinkedfrom', '$user_ip', $now', '$now_gmt', '$context', '$approved', '$user_agent') 1662 "); 1663 1664 $comment_ID = $wpdb->get_var('SELECT last_insert_id()'); 1665 if (get_settings('comments_notify')) 1666 wp_notify_postauthor($comment_ID, 'pingback'); 1667 do_action('pingback_post', $comment_ID); 1668 } else { 1669 // URL pattern not found 1670 $message = "Page linked to: $pagelinkedto\nPage linked from:" 1671 . " $pagelinkedfrom\nTitle: $title\nContext: $context\n\n".$messages[1]; 1672 } 1673 } else { 1674 // We already have a Pingback from this URL 1675 $message = "Sorry, you already did a pingback to $pagelinkedto" 1676 . " from $pagelinkedfrom."; 1175 // We already have a Pingback from this URL 1176 return new IXR_Error(48, 'The pingback has already been registered.'); 1177 } 1178 1179 1180 // very stupid, but gives time to the 'from' server to publish ! 1181 sleep(1); 1182 1183 // Let's check the remote site 1184 $fp = @fopen($pagelinkedfrom, 'r'); 1185 if (!$fp) { 1186 // The source URI does not exist 1187 return new IXR_Error(16, 'The source URI does not exist.'); 1188 } 1189 1190 $puntero = 4096; 1191 while($remote_read = fread($fp, $puntero)) { 1192 $linea .= $remote_read; 1193 } 1194 1195 // Work around bug in strip_tags(): 1196 $linea = str_replace('<!DOCTYPE','<DOCTYPE',$linea); 1197 $linea = strip_tags($linea, '<title><a>'); 1198 $linea = strip_all_but_one_link($linea, $pagelinkedto); 1199 // I don't think we need this? -- emc3 1200 //$linea = preg_replace('#&([^amp\;])#is', '&$1', $linea); 1201 if (empty($matchtitle)) { 1202 preg_match('|<title>([^<]*?)</title>|is', $linea, $matchtitle); 1203 } 1204 $pos2 = strpos($linea, $pagelinkedto); 1205 $pos3 = strpos($linea, str_replace('http://www.', 'http://', $pagelinkedto)); 1206 if (is_integer($pos2) || is_integer($pos3)) { 1207 // The page really links to us :) 1208 $pos4 = (is_integer($pos2)) ? $pos2 : $pos3; 1209 $start = $pos4-100; 1210 $context = substr($linea, $start, 250); 1211 $context = str_replace("\n", ' ', $context); 1212 $context = str_replace('&', '&', $context); 1213 } 1214 1215 fclose($fp); 1216 1217 if (empty($context)) { 1218 // URL pattern not found 1219 return new IXR_Error(17, 'The source URI does not contain a link to the target URI, and so cannot be used as a source.'); 1220 } 1221 1222 1223 // Check if pings are on, inelegant exit 1224 $pingstatus = $wpdb->get_var("SELECT ping_status FROM $wpdb->posts WHERE ID = $post_ID"); 1225 if ('closed' == $pingstatus) { 1226 return new IXR_Error(33, 'The specified target URI cannot be used as a target. It either doesn\'t exist, or it is not a pingback-enabled resource.'); 1227 } 1228 1229 1230 $pagelinkedfrom = preg_replace('#&([^amp\;])#is', '&$1', $pagelinkedfrom); 1231 $title = (!strlen($matchtitle[1])) ? $pagelinkedfrom : $matchtitle[1]; 1232 $original_context = strip_tags($context); 1233 $context = '[...] '; 1234 $context = htmlspecialchars($original_context); 1235 $context .= ' [...]'; 1236 $original_pagelinkedfrom = $pagelinkedfrom; 1237 $pagelinkedfrom = addslashes($pagelinkedfrom); 1238 $original_title = $title; 1239 $title = addslashes(strip_tags(trim($title))); 1240 $user_ip = $_SERVER['REMOTE_ADDR']; 1241 $user_agent = addslashes($_SERVER['HTTP_USER_AGENT']); 1242 $now = current_time('mysql'); 1243 $now_gmt = current_time('mysql', 1); 1244 1245 // Check if the entry allows pings 1246 if( !check_comment($title, '', $pagelinkedfrom, $context, $user_ip, $user_agent) ) { 1247 return new IXR_Error(49, 'Pingbacks not allowed on this entry.'); 1248 } 1249 1250 1251 $consulta = $wpdb->query("INSERT INTO $wpdb->comments 1252 (comment_post_ID, comment_author, comment_author_url, comment_author_IP, comment_date, comment_date_gmt, comment_content, comment_approved, comment_agent, comment_type) 1253 VALUES 1254 ($post_ID, '$title', '$pagelinkedfrom', '$user_ip', '$now', '$now_gmt', '$context', '1', '$user_agent', 'pingback') 1255 "); 1256 1257 $comment_ID = $wpdb->get_var('SELECT last_insert_id()'); 1258 1259 if (get_settings('comments_notify')) { 1260 wp_notify_postauthor($comment_ID, 'pingback'); 1261 } 1262 1263 do_action('pingback_post', $comment_ID); 1264 1265 return "Pingback from $pagelinkedfrom to $pagelinkedto registered. Keep the web talking! :-)"; 1266 } 1267 1268 1269 /* pingback.extensions.getPingbacks returns an array of URLs 1270 that pingbacked the given URL 1271 specs on http://www.aquarionics.com/misc/archives/blogite/0198.html */ 1272 function pingback_extensions_getPingbacks($args) { 1273 1274 global $wpdb; 1275 1276 $url = $args; 1277 1278 $post_ID = url_to_postid($url); 1279 if (!$post_ID) { 1280 // We aren't sure that the resource is available and/or pingback enabled 1281 return new IXR_Error(33, 'The specified target URI cannot be used as a target. It either doesn\'t exist, or it is not a pingback-enabled resource.'); 1282 } 1283 1284 $actual_post = wp_get_single_post($post_ID, ARRAY_A); 1285 1286 if (!$actual_post) { 1287 // No such post = resource not found 1288 return new IXR_Error(32, 'The specified target URI does not exist.'); 1289 } 1290 1291 $comments = $wpdb->get_results("SELECT comment_author_url, comment_content, comment_author_IP, comment_type FROM $wpdb->comments WHERE comment_post_ID = $post_ID"); 1292 1293 if (!$comments) { 1294 return array(); 1295 } 1296 1297 $pingbacks = array(); 1298 foreach($comments as $comment) { 1299 if ((strpos($comment->comment_content, '<pingback />') === 0) 1300 || ('pingback' == $comment->comment_type)) { 1301 $pingbacks[] = $comment->comment_author_url; 1677 1302 } 1678 } else { 1679 // Post_ID not found 1680 $message = $messages[2]; 1681 //debug_fwrite($log, 'Post doesn\'t exist'."\n"); 1682 } 1683 } 1684 return new xmlrpcresp(new xmlrpcval($message)); 1303 } 1304 1305 return $pingbacks; 1306 } 1685 1307 } 1686 1308 1687 /**** /PingBack functions ****/ 1688 1689 /**** SERVER FUNCTIONS ARRAY ****/ 1690 1691 $dispatch_map = 1692 array( "blogger.newPost" => 1693 array("function" => "bloggernewpost", 1694 "signature" => $bloggernewpost_sig, 1695 "docstring" => $bloggernewpost_doc), 1696 1697 1698 "blogger.editPost" => 1699 array("function" => "bloggereditpost", 1700 "signature" => $bloggereditpost_sig, 1701 "docstring" => $bloggereditpost_doc), 1702 1703 1704 "blogger.deletePost" => 1705 array("function" => "bloggerdeletepost", 1706 "signature" => $bloggerdeletepost_sig, 1707 "docstring" => $bloggerdeletepost_doc), 1708 1709 1710 "blogger.getUsersBlogs" => 1711 array("function" => "bloggergetusersblogs", 1712 "signature" => $bloggergetusersblogs_sig, 1713 "docstring" => $bloggergetusersblogs_doc), 1714 1715 "blogger.getUserInfo" => 1716 array("function" => "bloggergetuserinfo", 1717 "signature" => $bloggergetuserinfo_sig, 1718 "docstring" => $bloggergetuserinfo_doc), 1719 1720 "blogger.getPost" => 1721 array("function" => "bloggergetpost", 1722 "signature" => $bloggergetpost_sig, 1723 "docstring" => $bloggergetpost_doc), 1724 1725 "blogger.getRecentPosts" => 1726 array("function" => "bloggergetrecentposts", 1727 "signature" => $bloggergetrecentposts_sig, 1728 "docstring" => $bloggergetrecentposts_doc), 1729 1730 "blogger.getTemplate" => 1731 array("function" => "bloggergettemplate", 1732 "signature" => $bloggergettemplate_sig, 1733 "docstring" => $bloggergettemplate_doc), 1734 1735 "blogger.setTemplate" => 1736 array("function" => "bloggersettemplate", 1737 "signature" => $bloggersettemplate_sig, 1738 "docstring" => $bloggersettemplate_doc), 1739 1740 "metaWeblog.newPost" => 1741 array("function" => "mwnewpost", 1742 "signature" => $mwnewpost_sig, 1743 "docstring" => $mwnewpost_doc), 1744 1745 "metaWeblog.editPost" => 1746 array("function" => "mweditpost", 1747 "signature" => $mweditpost_sig, 1748 "docstring" => $mweditpost_doc), 1749 1750 "metaWeblog.getPost" => 1751 array("function" => "mwgetpost", 1752 "signature" => $mwgetpost_sig, 1753 "docstring" => $mwgetpost_doc), 1754 1755 "metaWeblog.getRecentPosts" => 1756 array("function" => "mwrecentposts", 1757 "signature" => $mwrecentposts_sig, 1758 "docstring" => $mwrecentposts_doc), 1759 1760 "metaWeblog.getCategories" => 1761 array("function" => "mwgetcats", 1762 "signature" => $mwgetcats_sig, 1763 "docstring" => $mwgetcats_doc), 1764 1765 "metaWeblog.newMediaObject" => 1766 array("function" => "mwnewmedia", 1767 "signature" => $mwnewmedia_sig, 1768 "docstring" => $mwnewmedia_doc), 1769 1770 "mt.getCategoryList" => 1771 array("function" => "mwgetcats", 1772 "signature" => $mwgetcats_sig, 1773 "docstring" => $mwgetcats_doc), 1774 1775 "mt.getPostCategories" => 1776 array("function" => "mt_getPostCategories", 1777 "signature" => $mt_getPostCategories_sig, 1778 "docstring" => $mt_getPostCategories_doc), 1779 1780 "mt.setPostCategories" => 1781 array("function" => "mt_setPostCategories", 1782 "signature" => $mt_setPostCategories_sig, 1783 "docstring" => $mt_setPostCategories_doc), 1784 1785 "mt.publishPost" => 1786 array("function" => "mt_publishPost", 1787 "signature" => $mt_publishPost_sig, 1788 "docstring" => $mt_publishPost_doc), 1789 1790 "mt.supportedMethods" => 1791 array("function" => "mt_supportedMethods", 1792 "signature" => $mt_supportedMethods_sig, 1793 "docstring" => $mt_supportedMethods_doc), 1794 1795 "mt.supportedTextFilters" => 1796 array("function" => "mt_supportedTextFilters", 1797 "signature" => $mt_supportedTextFilters_sig, 1798 "docstring" => $mt_supportedTextFilters_doc), 1799 1800 "mt.getRecentPostTitles" => 1801 array("function" => "mt_getRecentPostTitles", 1802 "signature" => $mt_getRecentPostTitles_sig, 1803 "docstring" => $mt_getRecentPostTitles_doc), 1804 1805 "mt.getTrackbackPings" => 1806 array("function" => "mt_getTrackbackPings", 1807 "signature" => $mt_getTrackbackPings_sig, 1808 "docstring" => $mt_getTrackbackPings_doc), 1809 1810 "b2.newPost" => 1811 array("function" => "b2newpost", 1812 "signature" => $wpnewpost_sig, 1813 "docstring" => $wpnewpost_doc), 1814 "b2.getCategories" => 1815 array("function" => "b2getcategories", 1816 "signature" => $wpgetcategories_sig, 1817 "docstring" => $wpgetcategories_doc), 1818 1819 "b2.ping" => 1820 array("function" => "b2ping", 1821 "signature" => $wpping_sig, 1822 "docstring" => $wpping_doc), 1823 1824 "pingback.ping" => 1825 array("function" => "pingback_ping", 1826 "signature" => $pingback_ping_sig, 1827 "docstring" => $pingback_ping_doc), 1828 1829 "b2.getPostURL" => 1830 array("function" => "pingback_getPostURL", 1831 "signature" => $wp_getPostURL_sig, 1832 "docstring" => $wp_getPostURL_doc), 1833 ); 1834 1835 $s = new xmlrpc_server($dispatch_map); 1309 1310 $wp_xmlrpc_server = new wp_xmlrpc_server(); 1836 1311 1837 1312 ?>
Note: See TracChangeset
for help on using the changeset viewer.