-
+ 4F496F538195A62E0F48C2D27DD787923795583C1AE1419C1135D132CA848EFE79B148F31DE66D9414829B034981427920B317952BE6FE23A097447815B14000
mp-wp/xmlrpc.php
(0 . 0)(1 . 3393)
161310 <?php^M
161311 /**^M
161312 * XML-RPC protocol support for WordPress^M
161313 *^M
161314 * @license GPL v2 <./license.txt>^M
161315 * @package WordPress^M
161316 */^M
161317 ^M
161318 /**^M
161319 * Whether this is a XMLRPC Request^M
161320 *^M
161321 * @var bool^M
161322 */^M
161323 define('XMLRPC_REQUEST', true);^M
161324 ^M
161325 // Some browser-embedded clients send cookies. We don't want them.^M
161326 $_COOKIE = array();^M
161327 ^M
161328 // A bug in PHP < 5.2.2 makes $HTTP_RAW_POST_DATA not set by default,^M
161329 // but we can do it ourself.^M
161330 if ( !isset( $HTTP_RAW_POST_DATA ) ) {^M
161331 $HTTP_RAW_POST_DATA = file_get_contents( 'php://input' );^M
161332 }^M
161333 ^M
161334 // fix for mozBlog and other cases where '<?xml' isn't on the very first line^M
161335 if ( isset($HTTP_RAW_POST_DATA) )^M
161336 $HTTP_RAW_POST_DATA = trim($HTTP_RAW_POST_DATA);^M
161337 ^M
161338 /** Include the bootstrap for setting up WordPress environment */^M
161339 include('./wp-load.php');^M
161340 ^M
161341 if ( isset( $_GET['rsd'] ) ) { // http://archipelago.phrasewise.com/rsd^M
161342 header('Content-Type: text/xml; charset=' . get_option('blog_charset'), true);^M
161343 ?>^M
161344 <?php echo '<?xml version="1.0" encoding="'.get_option('blog_charset').'"?'.'>'; ?>^M
161345 <rsd version="1.0" xmlns="http://archipelago.phrasewise.com/rsd">^M
161346 <service>^M
161347 <engineName>WordPress</engineName>^M
161348 <engineLink>http://wordpress.org/</engineLink>^M
161349 <homePageLink><?php bloginfo_rss('url') ?></homePageLink>^M
161350 <apis>^M
161351 <api name="WordPress" blogID="1" preferred="true" apiLink="<?php echo site_url('xmlrpc.php') ?>" />^M
161352 <api name="Movable Type" blogID="1" preferred="false" apiLink="<?php echo site_url('xmlrpc.php') ?>" />^M
161353 <api name="MetaWeblog" blogID="1" preferred="false" apiLink="<?php echo site_url('xmlrpc.php') ?>" />^M
161354 <api name="Blogger" blogID="1" preferred="false" apiLink="<?php echo site_url('xmlrpc.php') ?>" />^M
161355 <api name="Atom" blogID="" preferred="false" apiLink="<?php echo apply_filters('atom_service_url', site_url('wp-app.php/service') ) ?>" />^M
161356 </apis>^M
161357 </service>^M
161358 </rsd>^M
161359 <?php^M
161360 exit;^M
161361 }^M
161362 ^M
161363 include_once(ABSPATH . 'wp-admin/includes/admin.php');^M
161364 include_once(ABSPATH . WPINC . '/class-IXR.php');^M
161365 ^M
161366 // Turn off all warnings and errors.^M
161367 // error_reporting(0);^M
161368 ^M
161369 /**^M
161370 * Posts submitted via the xmlrpc interface get that title^M
161371 * @name post_default_title^M
161372 * @var string^M
161373 */^M
161374 $post_default_title = "";^M
161375 ^M
161376 /**^M
161377 * Whether to enable XMLRPC Logging.^M
161378 *^M
161379 * @name xmlrpc_logging^M
161380 * @var int|bool^M
161381 */^M
161382 $xmlrpc_logging = 0;^M
161383 ^M
161384 /**^M
161385 * logIO() - Writes logging info to a file.^M
161386 *^M
161387 * @uses $xmlrpc_logging^M
161388 * @package WordPress^M
161389 * @subpackage Logging^M
161390 *^M
161391 * @param string $io Whether input or output^M
161392 * @param string $msg Information describing logging reason.^M
161393 * @return bool Always return true^M
161394 */^M
161395 function logIO($io,$msg) {^M
161396 global $xmlrpc_logging;^M
161397 if ($xmlrpc_logging) {^M
161398 $fp = fopen("../xmlrpc.log","a+");^M
161399 $date = gmdate("Y-m-d H:i:s ");^M
161400 $iot = ($io == "I") ? " Input: " : " Output: ";^M
161401 fwrite($fp, "\n\n".$date.$iot.$msg);^M
161402 fclose($fp);^M
161403 }^M
161404 return true;^M
161405 }^M
161406 ^M
161407 if ( isset($HTTP_RAW_POST_DATA) )^M
161408 logIO("I", $HTTP_RAW_POST_DATA);^M
161409 ^M
161410 /**^M
161411 * WordPress XMLRPC server implementation.^M
161412 *^M
161413 * Implements compatability for Blogger API, MetaWeblog API, MovableType, and^M
161414 * pingback. Additional WordPress API for managing comments, pages, posts,^M
161415 * options, etc.^M
161416 *^M
161417 * Since WordPress 2.6.0, WordPress XMLRPC server can be disabled in the^M
161418 * administration panels.^M
161419 *^M
161420 * @package WordPress^M
161421 * @subpackage Publishing^M
161422 * @since 1.5.0^M
161423 */^M
161424 class wp_xmlrpc_server extends IXR_Server {^M
161425 ^M
161426 /**^M
161427 * Register all of the XMLRPC methods that XMLRPC server understands.^M
161428 *^M
161429 * PHP4 constructor and sets up server and method property. Passes XMLRPC^M
161430 * methods through the 'xmlrpc_methods' filter to allow plugins to extend^M
161431 * or replace XMLRPC methods.^M
161432 *^M
161433 * @since 1.5.0^M
161434 *^M
161435 * @return wp_xmlrpc_server^M
161436 */^M
161437 function wp_xmlrpc_server() {^M
161438 $this->methods = array(^M
161439 // Close all but pingback!^M
161440 /*^M
161441 // WordPress API^M
161442 'wp.getUsersBlogs' => 'this:wp_getUsersBlogs',^M
161443 'wp.getPage' => 'this:wp_getPage',^M
161444 'wp.getPages' => 'this:wp_getPages',^M
161445 'wp.newPage' => 'this:wp_newPage',^M
161446 'wp.deletePage' => 'this:wp_deletePage',^M
161447 'wp.editPage' => 'this:wp_editPage',^M
161448 'wp.getPageList' => 'this:wp_getPageList',^M
161449 'wp.getAuthors' => 'this:wp_getAuthors',^M
161450 'wp.getCategories' => 'this:mw_getCategories', // Alias^M
161451 'wp.getTags' => 'this:wp_getTags',^M
161452 'wp.newCategory' => 'this:wp_newCategory',^M
161453 'wp.deleteCategory' => 'this:wp_deleteCategory',^M
161454 'wp.suggestCategories' => 'this:wp_suggestCategories',^M
161455 'wp.uploadFile' => 'this:mw_newMediaObject', // Alias^M
161456 'wp.getCommentCount' => 'this:wp_getCommentCount',^M
161457 'wp.getPostStatusList' => 'this:wp_getPostStatusList',^M
161458 'wp.getPageStatusList' => 'this:wp_getPageStatusList',^M
161459 'wp.getPageTemplates' => 'this:wp_getPageTemplates',^M
161460 'wp.getOptions' => 'this:wp_getOptions',^M
161461 'wp.setOptions' => 'this:wp_setOptions',^M
161462 'wp.getComment' => 'this:wp_getComment',^M
161463 'wp.getComments' => 'this:wp_getComments',^M
161464 'wp.deleteComment' => 'this:wp_deleteComment',^M
161465 'wp.editComment' => 'this:wp_editComment',^M
161466 'wp.newComment' => 'this:wp_newComment',^M
161467 'wp.getCommentStatusList' => 'this:wp_getCommentStatusList',^M
161468 ^M
161469 // Blogger API^M
161470 'blogger.getUsersBlogs' => 'this:blogger_getUsersBlogs',^M
161471 'blogger.getUserInfo' => 'this:blogger_getUserInfo',^M
161472 'blogger.getPost' => 'this:blogger_getPost',^M
161473 'blogger.getRecentPosts' => 'this:blogger_getRecentPosts',^M
161474 'blogger.getTemplate' => 'this:blogger_getTemplate',^M
161475 'blogger.setTemplate' => 'this:blogger_setTemplate',^M
161476 'blogger.newPost' => 'this:blogger_newPost',^M
161477 'blogger.editPost' => 'this:blogger_editPost',^M
161478 'blogger.deletePost' => 'this:blogger_deletePost',^M
161479 ^M
161480 // MetaWeblog API (with MT extensions to structs)^M
161481 'metaWeblog.newPost' => 'this:mw_newPost',^M
161482 'metaWeblog.editPost' => 'this:mw_editPost',^M
161483 'metaWeblog.getPost' => 'this:mw_getPost',^M
161484 'metaWeblog.getRecentPosts' => 'this:mw_getRecentPosts',^M
161485 'metaWeblog.getCategories' => 'this:mw_getCategories',^M
161486 'metaWeblog.newMediaObject' => 'this:mw_newMediaObject',^M
161487 ^M
161488 // MetaWeblog API aliases for Blogger API^M
161489 // see http://www.xmlrpc.com/stories/storyReader$2460^M
161490 'metaWeblog.deletePost' => 'this:blogger_deletePost',^M
161491 'metaWeblog.getTemplate' => 'this:blogger_getTemplate',^M
161492 'metaWeblog.setTemplate' => 'this:blogger_setTemplate',^M
161493 'metaWeblog.getUsersBlogs' => 'this:blogger_getUsersBlogs',^M
161494 ^M
161495 // MovableType API^M
161496 'mt.getCategoryList' => 'this:mt_getCategoryList',^M
161497 'mt.getRecentPostTitles' => 'this:mt_getRecentPostTitles',^M
161498 'mt.getPostCategories' => 'this:mt_getPostCategories',^M
161499 'mt.setPostCategories' => 'this:mt_setPostCategories',^M
161500 'mt.supportedMethods' => 'this:mt_supportedMethods',^M
161501 'mt.supportedTextFilters' => 'this:mt_supportedTextFilters',^M
161502 'mt.getTrackbackPings' => 'this:mt_getTrackbackPings',^M
161503 'mt.publishPost' => 'this:mt_publishPost',^M
161504 ^M
161505 ^M
161506 'demo.sayHello' => 'this:sayHello',^M
161507 'demo.addTwoNumbers' => 'this:addTwoNumbers'^M
161508 */^M
161509 ^M
161510 // PingBack^M
161511 'pingback.ping' => 'this:pingback_ping',^M
161512 'pingback.extensions.getPingbacks' => 'this:pingback_extensions_getPingbacks',^M
161513 ^M
161514 );^M
161515 ^M
161516 $this->initialise_blog_option_info( );^M
161517 $this->methods = apply_filters('xmlrpc_methods', $this->methods);^M
161518 $this->IXR_Server($this->methods);^M
161519 }^M
161520 ^M
161521 /**^M
161522 * Test XMLRPC API by saying, "Hello!" to client.^M
161523 *^M
161524 * @since 1.5.0^M
161525 *^M
161526 * @param array $args Method Parameters.^M
161527 * @return string^M
161528 */^M
161529 function sayHello($args) {^M
161530 return 'Hello!';^M
161531 }^M
161532 ^M
161533 /**^M
161534 * Test XMLRPC API by adding two numbers for client.^M
161535 *^M
161536 * @since 1.5.0^M
161537 *^M
161538 * @param array $args Method Parameters.^M
161539 * @return int^M
161540 */^M
161541 function addTwoNumbers($args) {^M
161542 $number1 = $args[0];^M
161543 $number2 = $args[1];^M
161544 return $number1 + $number2;^M
161545 }^M
161546 ^M
161547 /**^M
161548 * Check user's credentials.^M
161549 *^M
161550 * @since 1.5.0^M
161551 *^M
161552 * @param string $user_login User's username.^M
161553 * @param string $user_pass User's password.^M
161554 * @return bool Whether authentication passed.^M
161555 */^M
161556 function login_pass_ok($user_login, $user_pass) {^M
161557 if ( !get_option( 'enable_xmlrpc' ) ) {^M
161558 $this->error = new IXR_Error( 405, sprintf( __( 'XML-RPC services are disabled on this blog. An admin user can enable them at %s'), admin_url('options-writing.php') ) );^M
161559 return false;^M
161560 }^M
161561 ^M
161562 if (!user_pass_ok($user_login, $user_pass)) {^M
161563 $this->error = new IXR_Error(403, __('Bad login/pass combination.'));^M
161564 return false;^M
161565 }^M
161566 return true;^M
161567 }^M
161568 ^M
161569 /**^M
161570 * Sanitize string or array of strings for database.^M
161571 *^M
161572 * @since 1.5.2^M
161573 *^M
161574 * @param string|array $array Sanitize single string or array of strings.^M
161575 * @return string|array Type matches $array and sanitized for the database.^M
161576 */^M
161577 function escape(&$array) {^M
161578 global $wpdb;^M
161579 ^M
161580 if(!is_array($array)) {^M
161581 return($wpdb->escape($array));^M
161582 }^M
161583 else {^M
161584 foreach ( (array) $array as $k => $v ) {^M
161585 if (is_array($v)) {^M
161586 $this->escape($array[$k]);^M
161587 } else if (is_object($v)) {^M
161588 //skip^M
161589 } else {^M
161590 $array[$k] = $wpdb->escape($v);^M
161591 }^M
161592 }^M
161593 }^M
161594 }^M
161595 ^M
161596 /**^M
161597 * Retrieve custom fields for post.^M
161598 *^M
161599 * @since 2.5.0^M
161600 *^M
161601 * @param int $post_id Post ID.^M
161602 * @return array Custom fields, if exist.^M
161603 */^M
161604 function get_custom_fields($post_id) {^M
161605 $post_id = (int) $post_id;^M
161606 ^M
161607 $custom_fields = array();^M
161608 ^M
161609 foreach ( (array) has_meta($post_id) as $meta ) {^M
161610 // Don't expose protected fields.^M
161611 if ( strpos($meta['meta_key'], '_wp_') === 0 ) {^M
161612 continue;^M
161613 }^M
161614 ^M
161615 $custom_fields[] = array(^M
161616 "id" => $meta['meta_id'],^M
161617 "key" => $meta['meta_key'],^M
161618 "value" => $meta['meta_value']^M
161619 );^M
161620 }^M
161621 ^M
161622 return $custom_fields;^M
161623 }^M
161624 ^M
161625 /**^M
161626 * Set custom fields for post.^M
161627 *^M
161628 * @since 2.5.0^M
161629 *^M
161630 * @param int $post_id Post ID.^M
161631 * @param array $fields Custom fields.^M
161632 */^M
161633 function set_custom_fields($post_id, $fields) {^M
161634 $post_id = (int) $post_id;^M
161635 ^M
161636 foreach ( (array) $fields as $meta ) {^M
161637 if ( isset($meta['id']) ) {^M
161638 $meta['id'] = (int) $meta['id'];^M
161639 ^M
161640 if ( isset($meta['key']) ) {^M
161641 update_meta($meta['id'], $meta['key'], $meta['value']);^M
161642 }^M
161643 else {^M
161644 delete_meta($meta['id']);^M
161645 }^M
161646 }^M
161647 else {^M
161648 $_POST['metakeyinput'] = $meta['key'];^M
161649 $_POST['metavalue'] = $meta['value'];^M
161650 add_meta($post_id);^M
161651 }^M
161652 }^M
161653 }^M
161654 ^M
161655 /**^M
161656 * Setup blog options property.^M
161657 *^M
161658 * Passes property through 'xmlrpc_blog_options' filter.^M
161659 *^M
161660 * @since 2.6.0^M
161661 */^M
161662 function initialise_blog_option_info( ) {^M
161663 global $wp_version;^M
161664 ^M
161665 $this->blog_options = array(^M
161666 // Read only options^M
161667 'software_name' => array(^M
161668 'desc' => __( 'Software Name' ),^M
161669 'readonly' => true,^M
161670 'value' => 'WordPress'^M
161671 ),^M
161672 'software_version' => array(^M
161673 'desc' => __( 'Software Version' ),^M
161674 'readonly' => true,^M
161675 'value' => $wp_version^M
161676 ),^M
161677 'blog_url' => array(^M
161678 'desc' => __( 'Blog URL' ),^M
161679 'readonly' => true,^M
161680 'option' => 'siteurl'^M
161681 ),^M
161682 ^M
161683 // Updatable options^M
161684 'time_zone' => array(^M
161685 'desc' => __( 'Time Zone' ),^M
161686 'readonly' => false,^M
161687 'option' => 'gmt_offset'^M
161688 ),^M
161689 'blog_title' => array(^M
161690 'desc' => __( 'Blog Title' ),^M
161691 'readonly' => false,^M
161692 'option' => 'blogname'^M
161693 ),^M
161694 'blog_tagline' => array(^M
161695 'desc' => __( 'Blog Tagline' ),^M
161696 'readonly' => false,^M
161697 'option' => 'blogdescription'^M
161698 ),^M
161699 'date_format' => array(^M
161700 'desc' => __( 'Date Format' ),^M
161701 'readonly' => false,^M
161702 'option' => 'date_format'^M
161703 ),^M
161704 'time_format' => array(^M
161705 'desc' => __( 'Time Format' ),^M
161706 'readonly' => false,^M
161707 'option' => 'time_format'^M
161708 )^M
161709 );^M
161710 ^M
161711 $this->blog_options = apply_filters( 'xmlrpc_blog_options', $this->blog_options );^M
161712 }^M
161713 ^M
161714 /**^M
161715 * Retrieve the blogs of the user.^M
161716 *^M
161717 * @since 2.6.0^M
161718 *^M
161719 * @param array $args Method parameters.^M
161720 * @return array^M
161721 */^M
161722 function wp_getUsersBlogs( $args ) {^M
161723 // If this isn't on WPMU then just use blogger_getUsersBlogs^M
161724 if( !function_exists( 'is_site_admin' ) ) {^M
161725 array_unshift( $args, 1 );^M
161726 return $this->blogger_getUsersBlogs( $args );^M
161727 }^M
161728 ^M
161729 $this->escape( $args );^M
161730 ^M
161731 $username = $args[0];^M
161732 $password = $args[1];^M
161733 ^M
161734 if( !$this->login_pass_ok( $username, $password ) )^M
161735 return $this->error;^M
161736 ^M
161737 do_action( 'xmlrpc_call', 'wp.getUsersBlogs' );^M
161738 ^M
161739 $user = set_current_user( 0, $username );^M
161740 ^M
161741 $blogs = (array) get_blogs_of_user( $user->ID );^M
161742 $struct = array( );^M
161743 ^M
161744 foreach( $blogs as $blog ) {^M
161745 // Don't include blogs that aren't hosted at this site^M
161746 if( $blog->site_id != $current_site->id )^M
161747 continue;^M
161748 ^M
161749 $blog_id = $blog->userblog_id;^M
161750 switch_to_blog($blog_id);^M
161751 $is_admin = current_user_can('level_8');^M
161752 ^M
161753 $struct[] = array(^M
161754 'isAdmin' => $is_admin,^M
161755 'url' => get_option( 'home' ) . '/',^M
161756 'blogid' => $blog_id,^M
161757 'blogName' => get_option( 'blogname' ),^M
161758 'xmlrpc' => get_option( 'home' ) . '/xmlrpc.php'^M
161759 );^M
161760 ^M
161761 restore_current_blog( );^M
161762 }^M
161763 ^M
161764 return $struct;^M
161765 }^M
161766 ^M
161767 /**^M
161768 * Retrieve page.^M
161769 *^M
161770 * @since 2.2.0^M
161771 *^M
161772 * @param array $args Method parameters.^M
161773 * @return array^M
161774 */^M
161775 function wp_getPage($args) {^M
161776 $this->escape($args);^M
161777 ^M
161778 $blog_id = (int) $args[0];^M
161779 $page_id = (int) $args[1];^M
161780 $username = $args[2];^M
161781 $password = $args[3];^M
161782 ^M
161783 if(!$this->login_pass_ok($username, $password)) {^M
161784 return($this->error);^M
161785 }^M
161786 ^M
161787 set_current_user( 0, $username );^M
161788 if( !current_user_can( 'edit_page', $page_id ) )^M
161789 return new IXR_Error( 401, __( 'Sorry, you can not edit this page.' ) );^M
161790 ^M
161791 do_action('xmlrpc_call', 'wp.getPage');^M
161792 ^M
161793 // Lookup page info.^M
161794 $page = get_page($page_id);^M
161795 ^M
161796 // If we found the page then format the data.^M
161797 if($page->ID && ($page->post_type == "page")) {^M
161798 // Get all of the page content and link.^M
161799 $full_page = get_extended($page->post_content);^M
161800 $link = post_permalink($page->ID);^M
161801 ^M
161802 // Get info the page parent if there is one.^M
161803 $parent_title = "";^M
161804 if(!empty($page->post_parent)) {^M
161805 $parent = get_page($page->post_parent);^M
161806 $parent_title = $parent->post_title;^M
161807 }^M
161808 ^M
161809 // Determine comment and ping settings.^M
161810 $allow_comments = ("open" == $page->comment_status) ? 1 : 0;^M
161811 $allow_pings = ("open" == $page->ping_status) ? 1 : 0;^M
161812 ^M
161813 // Format page date.^M
161814 $page_date = mysql2date("Ymd\TH:i:s", $page->post_date);^M
161815 $page_date_gmt = mysql2date("Ymd\TH:i:s", $page->post_date_gmt);^M
161816 ^M
161817 // Pull the categories info together.^M
161818 $categories = array();^M
161819 foreach(wp_get_post_categories($page->ID) as $cat_id) {^M
161820 $categories[] = get_cat_name($cat_id);^M
161821 }^M
161822 ^M
161823 // Get the author info.^M
161824 $author = get_userdata($page->post_author);^M
161825 ^M
161826 $page_template = get_post_meta( $page->ID, '_wp_page_template', true );^M
161827 if( empty( $page_template ) )^M
161828 $page_template = 'default';^M
161829 ^M
161830 $page_struct = array(^M
161831 "dateCreated" => new IXR_Date($page_date),^M
161832 "userid" => $page->post_author,^M
161833 "page_id" => $page->ID,^M
161834 "page_status" => $page->post_status,^M
161835 "description" => $full_page["main"],^M
161836 "title" => $page->post_title,^M
161837 "link" => $link,^M
161838 "permaLink" => $link,^M
161839 "categories" => $categories,^M
161840 "excerpt" => $page->post_excerpt,^M
161841 "text_more" => $full_page["extended"],^M
161842 "mt_allow_comments" => $allow_comments,^M
161843 "mt_allow_pings" => $allow_pings,^M
161844 "wp_slug" => $page->post_name,^M
161845 "wp_password" => $page->post_password,^M
161846 "wp_author" => $author->display_name,^M
161847 "wp_page_parent_id" => $page->post_parent,^M
161848 "wp_page_parent_title" => $parent_title,^M
161849 "wp_page_order" => $page->menu_order,^M
161850 "wp_author_id" => $author->ID,^M
161851 "wp_author_display_name" => $author->display_name,^M
161852 "date_created_gmt" => new IXR_Date($page_date_gmt),^M
161853 "custom_fields" => $this->get_custom_fields($page_id),^M
161854 "wp_page_template" => $page_template^M
161855 );^M
161856 ^M
161857 return($page_struct);^M
161858 }^M
161859 // If the page doesn't exist indicate that.^M
161860 else {^M
161861 return(new IXR_Error(404, __("Sorry, no such page.")));^M
161862 }^M
161863 }^M
161864 ^M
161865 /**^M
161866 * Retrieve Pages.^M
161867 *^M
161868 * @since 2.2.0^M
161869 *^M
161870 * @param array $args Method parameters.^M
161871 * @return array^M
161872 */^M
161873 function wp_getPages($args) {^M
161874 $this->escape($args);^M
161875 ^M
161876 $blog_id = (int) $args[0];^M
161877 $username = $args[1];^M
161878 $password = $args[2];^M
161879 $num_pages = (int) $args[3];^M
161880 ^M
161881 if(!$this->login_pass_ok($username, $password)) {^M
161882 return($this->error);^M
161883 }^M
161884 ^M
161885 set_current_user( 0, $username );^M
161886 if( !current_user_can( 'edit_pages' ) )^M
161887 return new IXR_Error( 401, __( 'Sorry, you can not edit pages.' ) );^M
161888 ^M
161889 do_action('xmlrpc_call', 'wp.getPages');^M
161890 ^M
161891 $page_limit = 10;^M
161892 if( isset( $num_pages ) ) {^M
161893 $page_limit = $num_pages;^M
161894 }^M
161895 ^M
161896 $pages = get_posts( "post_type=page&post_status=all&numberposts={$page_limit}" );^M
161897 $num_pages = count($pages);^M
161898 ^M
161899 // If we have pages, put together their info.^M
161900 if($num_pages >= 1) {^M
161901 $pages_struct = array();^M
161902 ^M
161903 for($i = 0; $i < $num_pages; $i++) {^M
161904 $page = wp_xmlrpc_server::wp_getPage(array(^M
161905 $blog_id, $pages[$i]->ID, $username, $password^M
161906 ));^M
161907 $pages_struct[] = $page;^M
161908 }^M
161909 ^M
161910 return($pages_struct);^M
161911 }^M
161912 // If no pages were found return an error.^M
161913 else {^M
161914 return(array());^M
161915 }^M
161916 }^M
161917 ^M
161918 /**^M
161919 * Create new page.^M
161920 *^M
161921 * @since 2.2.0^M
161922 *^M
161923 * @param array $args Method parameters.^M
161924 * @return unknown^M
161925 */^M
161926 function wp_newPage($args) {^M
161927 // Items not escaped here will be escaped in newPost.^M
161928 $username = $this->escape($args[1]);^M
161929 $password = $this->escape($args[2]);^M
161930 $page = $args[3];^M
161931 $publish = $args[4];^M
161932 ^M
161933 if(!$this->login_pass_ok($username, $password)) {^M
161934 return($this->error);^M
161935 }^M
161936 ^M
161937 do_action('xmlrpc_call', 'wp.newPage');^M
161938 ^M
161939 // Set the user context and check if they are allowed^M
161940 // to add new pages.^M
161941 $user = set_current_user(0, $username);^M
161942 if(!current_user_can("publish_pages")) {^M
161943 return(new IXR_Error(401, __("Sorry, you can not add new pages.")));^M
161944 }^M
161945 ^M
161946 // Mark this as content for a page.^M
161947 $args[3]["post_type"] = "page";^M
161948 ^M
161949 // Let mw_newPost do all of the heavy lifting.^M
161950 return($this->mw_newPost($args));^M
161951 }^M
161952 ^M
161953 /**^M
161954 * Delete page.^M
161955 *^M
161956 * @since 2.2.0^M
161957 *^M
161958 * @param array $args Method parameters.^M
161959 * @return bool True, if success.^M
161960 */^M
161961 function wp_deletePage($args) {^M
161962 $this->escape($args);^M
161963 ^M
161964 $blog_id = (int) $args[0];^M
161965 $username = $args[1];^M
161966 $password = $args[2];^M
161967 $page_id = (int) $args[3];^M
161968 ^M
161969 if(!$this->login_pass_ok($username, $password)) {^M
161970 return($this->error);^M
161971 }^M
161972 ^M
161973 do_action('xmlrpc_call', 'wp.deletePage');^M
161974 ^M
161975 // Get the current page based on the page_id and^M
161976 // make sure it is a page and not a post.^M
161977 $actual_page = wp_get_single_post($page_id, ARRAY_A);^M
161978 if(^M
161979 !$actual_page^M
161980 || ($actual_page["post_type"] != "page")^M
161981 ) {^M
161982 return(new IXR_Error(404, __("Sorry, no such page.")));^M
161983 }^M
161984 ^M
161985 // Set the user context and make sure they can delete pages.^M
161986 set_current_user(0, $username);^M
161987 if(!current_user_can("delete_page", $page_id)) {^M
161988 return(new IXR_Error(401, __("Sorry, you do not have the right to delete this page.")));^M
161989 }^M
161990 ^M
161991 // Attempt to delete the page.^M
161992 $result = wp_delete_post($page_id);^M
161993 if(!$result) {^M
161994 return(new IXR_Error(500, __("Failed to delete the page.")));^M
161995 }^M
161996 ^M
161997 return(true);^M
161998 }^M
161999 ^M
162000 /**^M
162001 * Edit page.^M
162002 *^M
162003 * @since 2.2.0^M
162004 *^M
162005 * @param array $args Method parameters.^M
162006 * @return unknown^M
162007 */^M
162008 function wp_editPage($args) {^M
162009 // Items not escaped here will be escaped in editPost.^M
162010 $blog_id = (int) $args[0];^M
162011 $page_id = (int) $this->escape($args[1]);^M
162012 $username = $this->escape($args[2]);^M
162013 $password = $this->escape($args[3]);^M
162014 $content = $args[4];^M
162015 $publish = $args[5];^M
162016 ^M
162017 if(!$this->login_pass_ok($username, $password)) {^M
162018 return($this->error);^M
162019 }^M
162020 ^M
162021 do_action('xmlrpc_call', 'wp.editPage');^M
162022 ^M
162023 // Get the page data and make sure it is a page.^M
162024 $actual_page = wp_get_single_post($page_id, ARRAY_A);^M
162025 if(^M
162026 !$actual_page^M
162027 || ($actual_page["post_type"] != "page")^M
162028 ) {^M
162029 return(new IXR_Error(404, __("Sorry, no such page.")));^M
162030 }^M
162031 ^M
162032 // Set the user context and make sure they are allowed to edit pages.^M
162033 set_current_user(0, $username);^M
162034 if(!current_user_can("edit_page", $page_id)) {^M
162035 return(new IXR_Error(401, __("Sorry, you do not have the right to edit this page.")));^M
162036 }^M
162037 ^M
162038 // Mark this as content for a page.^M
162039 $content["post_type"] = "page";^M
162040 ^M
162041 // Arrange args in the way mw_editPost understands.^M
162042 $args = array(^M
162043 $page_id,^M
162044 $username,^M
162045 $password,^M
162046 $content,^M
162047 $publish^M
162048 );^M
162049 ^M
162050 // Let mw_editPost do all of the heavy lifting.^M
162051 return($this->mw_editPost($args));^M
162052 }^M
162053 ^M
162054 /**^M
162055 * Retrieve page list.^M
162056 *^M
162057 * @since 2.2.0^M
162058 *^M
162059 * @param array $args Method parameters.^M
162060 * @return unknown^M
162061 */^M
162062 function wp_getPageList($args) {^M
162063 global $wpdb;^M
162064 ^M
162065 $this->escape($args);^M
162066 ^M
162067 $blog_id = (int) $args[0];^M
162068 $username = $args[1];^M
162069 $password = $args[2];^M
162070 ^M
162071 if(!$this->login_pass_ok($username, $password)) {^M
162072 return($this->error);^M
162073 }^M
162074 ^M
162075 set_current_user( 0, $username );^M
162076 if( !current_user_can( 'edit_pages' ) )^M
162077 return new IXR_Error( 401, __( 'Sorry, you can not edit pages.' ) );^M
162078 ^M
162079 do_action('xmlrpc_call', 'wp.getPageList');^M
162080 ^M
162081 // Get list of pages ids and titles^M
162082 $page_list = $wpdb->get_results("^M
162083 SELECT ID page_id,^M
162084 post_title page_title,^M
162085 post_parent page_parent_id,^M
162086 post_date_gmt,^M
162087 post_date^M
162088 FROM {$wpdb->posts}^M
162089 WHERE post_type = 'page'^M
162090 ORDER BY ID^M
162091 ");^M
162092 ^M
162093 // The date needs to be formated properly.^M
162094 $num_pages = count($page_list);^M
162095 for($i = 0; $i < $num_pages; $i++) {^M
162096 $post_date = mysql2date("Ymd\TH:i:s", $page_list[$i]->post_date);^M
162097 $post_date_gmt = mysql2date("Ymd\TH:i:s", $page_list[$i]->post_date_gmt);^M
162098 ^M
162099 $page_list[$i]->dateCreated = new IXR_Date($post_date);^M
162100 $page_list[$i]->date_created_gmt = new IXR_Date($post_date_gmt);^M
162101 ^M
162102 unset($page_list[$i]->post_date_gmt);^M
162103 unset($page_list[$i]->post_date);^M
162104 }^M
162105 ^M
162106 return($page_list);^M
162107 }^M
162108 ^M
162109 /**^M
162110 * Retrieve authors list.^M
162111 *^M
162112 * @since 2.2.0^M
162113 *^M
162114 * @param array $args Method parameters.^M
162115 * @return array^M
162116 */^M
162117 function wp_getAuthors($args) {^M
162118 ^M
162119 $this->escape($args);^M
162120 ^M
162121 $blog_id = (int) $args[0];^M
162122 $username = $args[1];^M
162123 $password = $args[2];^M
162124 ^M
162125 if(!$this->login_pass_ok($username, $password)) {^M
162126 return($this->error);^M
162127 }^M
162128 ^M
162129 set_current_user(0, $username);^M
162130 if(!current_user_can("edit_posts")) {^M
162131 return(new IXR_Error(401, __("Sorry, you can not edit posts on this blog.")));^M
162132 }^M
162133 ^M
162134 do_action('xmlrpc_call', 'wp.getAuthors');^M
162135 ^M
162136 $authors = array();^M
162137 foreach( (array) get_users_of_blog() as $row ) {^M
162138 $authors[] = array(^M
162139 "user_id" => $row->user_id,^M
162140 "user_login" => $row->user_login,^M
162141 "display_name" => $row->display_name^M
162142 );^M
162143 }^M
162144 ^M
162145 return($authors);^M
162146 }^M
162147 ^M
162148 /**^M
162149 * Get list of all tags^M
162150 *^M
162151 * @since 2.7^M
162152 *^M
162153 * @param array $args Method parameters.^M
162154 * @return array^M
162155 */^M
162156 function wp_getTags( $args ) {^M
162157 $this->escape( $args );^M
162158 ^M
162159 $blog_id = (int) $args[0];^M
162160 $username = $args[1];^M
162161 $password = $args[2];^M
162162 ^M
162163 if( !$this->login_pass_ok( $username, $password ) ) {^M
162164 return $this->error;^M
162165 }^M
162166 ^M
162167 set_current_user( 0, $username );^M
162168 if( !current_user_can( 'edit_posts' ) ) {^M
162169 return new IXR_Error( 401, __( 'Sorry, you must be able to edit posts on this blog in order to view tags.' ) );^M
162170 }^M
162171 ^M
162172 do_action( 'xmlrpc_call', 'wp.getKeywords' );^M
162173 ^M
162174 $tags = array( );^M
162175 ^M
162176 if( $all_tags = get_tags( ) ) {^M
162177 foreach( (array) $all_tags as $tag ) {^M
162178 $struct['tag_id'] = $tag->term_id;^M
162179 $struct['name'] = $tag->name;^M
162180 $struct['count'] = $tag->count;^M
162181 $struct['slug'] = $tag->slug;^M
162182 $struct['html_url'] = wp_specialchars( get_tag_link( $tag->term_id ) );^M
162183 $struct['rss_url'] = wp_specialchars( get_tag_feed_link( $tag->term_id ) );^M
162184 ^M
162185 $tags[] = $struct;^M
162186 }^M
162187 }^M
162188 ^M
162189 return $tags;^M
162190 }^M
162191 ^M
162192 /**^M
162193 * Create new category.^M
162194 *^M
162195 * @since 2.2.0^M
162196 *^M
162197 * @param array $args Method parameters.^M
162198 * @return int Category ID.^M
162199 */^M
162200 function wp_newCategory($args) {^M
162201 $this->escape($args);^M
162202 ^M
162203 $blog_id = (int) $args[0];^M
162204 $username = $args[1];^M
162205 $password = $args[2];^M
162206 $category = $args[3];^M
162207 ^M
162208 if(!$this->login_pass_ok($username, $password)) {^M
162209 return($this->error);^M
162210 }^M
162211 ^M
162212 do_action('xmlrpc_call', 'wp.newCategory');^M
162213 ^M
162214 // Set the user context and make sure they are^M
162215 // allowed to add a category.^M
162216 set_current_user(0, $username);^M
162217 if(!current_user_can("manage_categories")) {^M
162218 return(new IXR_Error(401, __("Sorry, you do not have the right to add a category.")));^M
162219 }^M
162220 ^M
162221 // If no slug was provided make it empty so that^M
162222 // WordPress will generate one.^M
162223 if(empty($category["slug"])) {^M
162224 $category["slug"] = "";^M
162225 }^M
162226 ^M
162227 // If no parent_id was provided make it empty^M
162228 // so that it will be a top level page (no parent).^M
162229 if ( !isset($category["parent_id"]) )^M
162230 $category["parent_id"] = "";^M
162231 ^M
162232 // If no description was provided make it empty.^M
162233 if(empty($category["description"])) {^M
162234 $category["description"] = "";^M
162235 }^M
162236 ^M
162237 $new_category = array(^M
162238 "cat_name" => $category["name"],^M
162239 "category_nicename" => $category["slug"],^M
162240 "category_parent" => $category["parent_id"],^M
162241 "category_description" => $category["description"]^M
162242 );^M
162243 ^M
162244 $cat_id = wp_insert_category($new_category);^M
162245 if(!$cat_id) {^M
162246 return(new IXR_Error(500, __("Sorry, the new category failed.")));^M
162247 }^M
162248 ^M
162249 return($cat_id);^M
162250 }^M
162251 ^M
162252 /**^M
162253 * Remove category.^M
162254 *^M
162255 * @since 2.5.0^M
162256 *^M
162257 * @param array $args Method parameters.^M
162258 * @return mixed See {@link wp_delete_category()} for return info.^M
162259 */^M
162260 function wp_deleteCategory($args) {^M
162261 $this->escape($args);^M
162262 ^M
162263 $blog_id = (int) $args[0];^M
162264 $username = $args[1];^M
162265 $password = $args[2];^M
162266 $category_id = (int) $args[3];^M
162267 ^M
162268 if( !$this->login_pass_ok( $username, $password ) ) {^M
162269 return $this->error;^M
162270 }^M
162271 ^M
162272 do_action('xmlrpc_call', 'wp.deleteCategory');^M
162273 ^M
162274 set_current_user(0, $username);^M
162275 if( !current_user_can("manage_categories") ) {^M
162276 return new IXR_Error( 401, __( "Sorry, you do not have the right to delete a category." ) );^M
162277 }^M
162278 ^M
162279 return wp_delete_category( $category_id );^M
162280 }^M
162281 ^M
162282 /**^M
162283 * Retrieve category list.^M
162284 *^M
162285 * @since 2.2.0^M
162286 *^M
162287 * @param array $args Method parameters.^M
162288 * @return array^M
162289 */^M
162290 function wp_suggestCategories($args) {^M
162291 $this->escape($args);^M
162292 ^M
162293 $blog_id = (int) $args[0];^M
162294 $username = $args[1];^M
162295 $password = $args[2];^M
162296 $category = $args[3];^M
162297 $max_results = (int) $args[4];^M
162298 ^M
162299 if(!$this->login_pass_ok($username, $password)) {^M
162300 return($this->error);^M
162301 }^M
162302 ^M
162303 set_current_user(0, $username);^M
162304 if( !current_user_can( 'edit_posts' ) )^M
162305 return new IXR_Error( 401, __( 'Sorry, you must be able to edit posts to this blog in order to view categories.' ) );^M
162306 ^M
162307 do_action('xmlrpc_call', 'wp.suggestCategories');^M
162308 ^M
162309 $category_suggestions = array();^M
162310 $args = array('get' => 'all', 'number' => $max_results, 'name__like' => $category);^M
162311 foreach ( (array) get_categories($args) as $cat ) {^M
162312 $category_suggestions[] = array(^M
162313 "category_id" => $cat->cat_ID,^M
162314 "category_name" => $cat->cat_name^M
162315 );^M
162316 }^M
162317 ^M
162318 return($category_suggestions);^M
162319 }^M
162320 ^M
162321 /**^M
162322 * Retrieve comment.^M
162323 *^M
162324 * @since 2.7.0^M
162325 *^M
162326 * @param array $args Method parameters.^M
162327 * @return array^M
162328 */^M
162329 function wp_getComment($args) {^M
162330 $this->escape($args);^M
162331 ^M
162332 $blog_id = (int) $args[0];^M
162333 $username = $args[1];^M
162334 $password = $args[2];^M
162335 $comment_id = (int) $args[3];^M
162336 ^M
162337 if ( !$this->login_pass_ok( $username, $password ) )^M
162338 return $this->error;^M
162339 ^M
162340 set_current_user( 0, $username );^M
162341 if ( !current_user_can( 'moderate_comments' ) )^M
162342 return new IXR_Error( 403, __( 'You are not allowed to moderate comments on this blog.' ) );^M
162343 ^M
162344 do_action('xmlrpc_call', 'wp.getComment');^M
162345 ^M
162346 if ( ! $comment = get_comment($comment_id) )^M
162347 return new IXR_Error( 404, __( 'Invalid comment ID.' ) );^M
162348 ^M
162349 // Format page date.^M
162350 $comment_date = mysql2date("Ymd\TH:i:s", $comment->comment_date);^M
162351 $comment_date_gmt = mysql2date("Ymd\TH:i:s", $comment->comment_date_gmt);^M
162352 ^M
162353 if ( 0 == $comment->comment_approved )^M
162354 $comment_status = 'hold';^M
162355 else if ( 'spam' == $comment->comment_approved )^M
162356 $comment_status = 'spam';^M
162357 else if ( 1 == $comment->comment_approved )^M
162358 $comment_status = 'approve';^M
162359 else^M
162360 $comment_status = $comment->comment_approved;^M
162361 ^M
162362 $link = get_comment_link($comment);^M
162363 ^M
162364 $comment_struct = array(^M
162365 "date_created_gmt" => new IXR_Date($comment_date_gmt),^M
162366 "user_id" => $comment->user_id,^M
162367 "comment_id" => $comment->comment_ID,^M
162368 "parent" => $comment->comment_parent,^M
162369 "status" => $comment_status,^M
162370 "content" => $comment->comment_content,^M
162371 "link" => $link,^M
162372 "post_id" => $comment->comment_post_ID,^M
162373 "post_title" => get_the_title($comment->comment_post_ID),^M
162374 "author" => $comment->comment_author,^M
162375 "author_url" => $comment->comment_author_url,^M
162376 "author_email" => $comment->comment_author_email,^M
162377 "author_ip" => $comment->comment_author_IP,^M
162378 "type" => $comment->comment_type,^M
162379 );^M
162380 ^M
162381 return $comment_struct;^M
162382 }^M
162383 ^M
162384 /**^M
162385 * Retrieve comments.^M
162386 *^M
162387 * @since 2.7.0^M
162388 *^M
162389 * @param array $args Method parameters.^M
162390 * @return array^M
162391 */^M
162392 function wp_getComments($args) {^M
162393 $this->escape($args);^M
162394 ^M
162395 $blog_id = (int) $args[0];^M
162396 $username = $args[1];^M
162397 $password = $args[2];^M
162398 $struct = $args[3];^M
162399 ^M
162400 if ( !$this->login_pass_ok($username, $password) )^M
162401 return($this->error);^M
162402 ^M
162403 set_current_user( 0, $username );^M
162404 if ( !current_user_can( 'moderate_comments' ) )^M
162405 return new IXR_Error( 401, __( 'Sorry, you can not edit comments.' ) );^M
162406 ^M
162407 do_action('xmlrpc_call', 'wp.getComments');^M
162408 ^M
162409 if ( isset($struct['status']) )^M
162410 $status = $struct['status'];^M
162411 else^M
162412 $status = '';^M
162413 ^M
162414 $post_id = '';^M
162415 if ( isset($struct['post_id']) )^M
162416 $post_id = absint($struct['post_id']);^M
162417 ^M
162418 $offset = 0;^M
162419 if ( isset($struct['offset']) )^M
162420 $offset = absint($struct['offset']);^M
162421 ^M
162422 $number = 10;^M
162423 if ( isset($struct['number']) )^M
162424 $number = absint($struct['number']);^M
162425 ^M
162426 $comments = get_comments( array('status' => $status, 'post_id' => $post_id, 'offset' => $offset, 'number' => $number ) );^M
162427 $num_comments = count($comments);^M
162428 ^M
162429 if ( ! $num_comments )^M
162430 return array();^M
162431 ^M
162432 $comments_struct = array();^M
162433 ^M
162434 for ( $i = 0; $i < $num_comments; $i++ ) {^M
162435 $comment = wp_xmlrpc_server::wp_getComment(array(^M
162436 $blog_id, $username, $password, $comments[$i]->comment_ID,^M
162437 ));^M
162438 $comments_struct[] = $comment;^M
162439 }^M
162440 ^M
162441 return $comments_struct;^M
162442 }^M
162443 ^M
162444 /**^M
162445 * Remove comment.^M
162446 *^M
162447 * @since 2.7.0^M
162448 *^M
162449 * @param array $args Method parameters.^M
162450 * @return mixed {@link wp_delete_comment()}^M
162451 */^M
162452 function wp_deleteComment($args) {^M
162453 $this->escape($args);^M
162454 ^M
162455 $blog_id = (int) $args[0];^M
162456 $username = $args[1];^M
162457 $password = $args[2];^M
162458 $comment_ID = (int) $args[3];^M
162459 ^M
162460 if ( !$this->login_pass_ok( $username, $password ) )^M
162461 return $this->error;^M
162462 ^M
162463 set_current_user( 0, $username );^M
162464 if ( !current_user_can( 'moderate_comments' ) )^M
162465 return new IXR_Error( 403, __( 'You are not allowed to moderate comments on this blog.' ) );^M
162466 ^M
162467 do_action('xmlrpc_call', 'wp.deleteComment');^M
162468 ^M
162469 if ( ! get_comment($comment_ID) )^M
162470 return new IXR_Error( 404, __( 'Invalid comment ID.' ) );^M
162471 ^M
162472 return wp_delete_comment($comment_ID);^M
162473 }^M
162474 ^M
162475 /**^M
162476 * Edit comment.^M
162477 *^M
162478 * @since 2.7.0^M
162479 *^M
162480 * @param array $args Method parameters.^M
162481 * @return bool True, on success.^M
162482 */^M
162483 function wp_editComment($args) {^M
162484 $this->escape($args);^M
162485 ^M
162486 $blog_id = (int) $args[0];^M
162487 $username = $args[1];^M
162488 $password = $args[2];^M
162489 $comment_ID = (int) $args[3];^M
162490 $content_struct = $args[4];^M
162491 ^M
162492 if ( !$this->login_pass_ok( $username, $password ) )^M
162493 return $this->error;^M
162494 ^M
162495 set_current_user( 0, $username );^M
162496 if ( !current_user_can( 'moderate_comments' ) )^M
162497 return new IXR_Error( 403, __( 'You are not allowed to moderate comments on this blog.' ) );^M
162498 ^M
162499 do_action('xmlrpc_call', 'wp.editComment');^M
162500 ^M
162501 if ( ! get_comment($comment_ID) )^M
162502 return new IXR_Error( 404, __( 'Invalid comment ID.' ) );^M
162503 ^M
162504 if ( isset($content_struct['status']) ) {^M
162505 $statuses = get_comment_statuses();^M
162506 $statuses = array_keys($statuses);^M
162507 ^M
162508 if ( ! in_array($content_struct['status'], $statuses) )^M
162509 return new IXR_Error( 401, __( 'Invalid comment status.' ) );^M
162510 $comment_approved = $content_struct['status'];^M
162511 }^M
162512 ^M
162513 // Do some timestamp voodoo^M
162514 if ( !empty( $content_struct['date_created_gmt'] ) ) {^M
162515 $dateCreated = str_replace( 'Z', '', $content_struct['date_created_gmt']->getIso() ) . 'Z'; // We know this is supposed to be GMT, so we're going to slap that Z on there by force^M
162516 $comment_date = get_date_from_gmt(iso8601_to_datetime($dateCreated));^M
162517 $comment_date_gmt = iso8601_to_datetime($dateCreated, GMT);^M
162518 }^M
162519 ^M
162520 if ( isset($content_struct['content']) )^M
162521 $comment_content = $content_struct['content'];^M
162522 ^M
162523 if ( isset($content_struct['author']) )^M
162524 $comment_author = $content_struct['author'];^M
162525 ^M
162526 if ( isset($content_struct['author_url']) )^M
162527 $comment_author_url = $content_struct['author_url'];^M
162528 ^M
162529 if ( isset($content_struct['author_email']) )^M
162530 $comment_author_email = $content_struct['author_email'];^M
162531 ^M
162532 // We've got all the data -- post it:^M
162533 $comment = compact('comment_ID', 'comment_content', 'comment_approved', 'comment_date', 'comment_date_gmt', 'comment_author', 'comment_author_email', 'comment_author_url');^M
162534 ^M
162535 $result = wp_update_comment($comment);^M
162536 if ( is_wp_error( $result ) )^M
162537 return new IXR_Error(500, $result->get_error_message());^M
162538 ^M
162539 if ( !$result )^M
162540 return new IXR_Error(500, __('Sorry, the comment could not be edited. Something wrong happened.'));^M
162541 ^M
162542 return true;^M
162543 }^M
162544 ^M
162545 /**^M
162546 * Create new comment.^M
162547 *^M
162548 * @since 2.7.0^M
162549 *^M
162550 * @param array $args Method parameters.^M
162551 * @return mixed {@link wp_new_comment()}^M
162552 */^M
162553 function wp_newComment($args) {^M
162554 global $wpdb;^M
162555 ^M
162556 $this->escape($args);^M
162557 ^M
162558 $blog_id = (int) $args[0];^M
162559 $username = $args[1];^M
162560 $password = $args[2];^M
162561 $post = $args[3];^M
162562 $content_struct = $args[4];^M
162563 ^M
162564 $allow_anon = apply_filters('xmlrpc_allow_anonymous_comments', false);^M
162565 ^M
162566 if ( !$this->login_pass_ok( $username, $password ) ) {^M
162567 $logged_in = false;^M
162568 if ( $allow_anon && get_option('comment_registration') )^M
162569 return new IXR_Error( 403, __( 'You must be registered to comment' ) );^M
162570 else if ( !$allow_anon )^M
162571 return $this->error;^M
162572 } else {^M
162573 $logged_in = true;^M
162574 set_current_user( 0, $username );^M
162575 if ( !current_user_can( 'moderate_comments' ) )^M
162576 return new IXR_Error( 403, __( 'You are not allowed to moderate comments on this blog.' ) );^M
162577 }^M
162578 ^M
162579 if ( is_numeric($post) )^M
162580 $post_id = absint($post);^M
162581 else^M
162582 $post_id = url_to_postid($post);^M
162583 ^M
162584 if ( ! $post_id )^M
162585 return new IXR_Error( 404, __( 'Invalid post ID.' ) );^M
162586 ^M
162587 if ( ! get_post($post_id) )^M
162588 return new IXR_Error( 404, __( 'Invalid post ID.' ) );^M
162589 ^M
162590 $comment['comment_post_ID'] = $post_id;^M
162591 ^M
162592 if ( $logged_in ) {^M
162593 $user = wp_get_current_user();^M
162594 $comment['comment_author'] = $wpdb->escape( $user->display_name );^M
162595 $comment['comment_author_email'] = $wpdb->escape( $user->user_email );^M
162596 $comment['comment_author_url'] = $wpdb->escape( $user->user_url );^M
162597 $comment['user_ID'] = $user->ID;^M
162598 } else {^M
162599 $comment['comment_author'] = '';^M
162600 if ( isset($content_struct['author']) )^M
162601 $comment['comment_author'] = $content_struct['author'];^M
162602 $comment['comment_author_email'] = '';^M
162603 if ( isset($content_struct['author']) )^M
162604 $comment['comment_author_email'] = $content_struct['author_email'];^M
162605 $comment['comment_author_url'] = '';^M
162606 if ( isset($content_struct['author']) )^M
162607 $comment['comment_author_url'] = $content_struct['author_url'];^M
162608 $comment['user_ID'] = 0;^M
162609 ^M
162610 if ( get_option('require_name_email') ) {^M
162611 if ( 6 > strlen($comment['comment_author_email']) || '' == $comment['comment_author'] )^M
162612 return new IXR_Error( 403, __( 'Comment author name and email are required' ) );^M
162613 elseif ( !is_email($comment['comment_author_email']) )^M
162614 return new IXR_Error( 403, __( 'A valid email address is required' ) );^M
162615 }^M
162616 }^M
162617 ^M
162618 $comment['comment_parent'] = isset($content_struct['comment_parent']) ? absint($content_struct['comment_parent']) : 0;^M
162619 ^M
162620 $comment['comment_content'] = $content_struct['content'];^M
162621 ^M
162622 do_action('xmlrpc_call', 'wp.newComment');^M
162623 ^M
162624 return wp_new_comment($comment);^M
162625 }^M
162626 ^M
162627 /**^M
162628 * Retrieve all of the comment status.^M
162629 *^M
162630 * @since 2.7.0^M
162631 *^M
162632 * @param array $args Method parameters.^M
162633 * @return array^M
162634 */^M
162635 function wp_getCommentStatusList($args) {^M
162636 $this->escape( $args );^M
162637 ^M
162638 $blog_id = (int) $args[0];^M
162639 $username = $args[1];^M
162640 $password = $args[2];^M
162641 ^M
162642 if ( !$this->login_pass_ok( $username, $password ) )^M
162643 return $this->error;^M
162644 ^M
162645 set_current_user( 0, $username );^M
162646 if ( !current_user_can( 'moderate_comments' ) )^M
162647 return new IXR_Error( 403, __( 'You are not allowed access to details about this blog.' ) );^M
162648 ^M
162649 do_action('xmlrpc_call', 'wp.getCommentStatusList');^M
162650 ^M
162651 return get_comment_statuses( );^M
162652 }^M
162653 ^M
162654 /**^M
162655 * Retrieve comment count.^M
162656 *^M
162657 * @since 2.5.0^M
162658 *^M
162659 * @param array $args Method parameters.^M
162660 * @return array^M
162661 */^M
162662 function wp_getCommentCount( $args ) {^M
162663 $this->escape($args);^M
162664 ^M
162665 $blog_id = (int) $args[0];^M
162666 $username = $args[1];^M
162667 $password = $args[2];^M
162668 $post_id = (int) $args[3];^M
162669 ^M
162670 if( !$this->login_pass_ok( $username, $password ) ) {^M
162671 return $this->error;^M
162672 }^M
162673 ^M
162674 set_current_user( 0, $username );^M
162675 if( !current_user_can( 'edit_posts' ) ) {^M
162676 return new IXR_Error( 403, __( 'You are not allowed access to details about comments.' ) );^M
162677 }^M
162678 ^M
162679 do_action('xmlrpc_call', 'wp.getCommentCount');^M
162680 ^M
162681 $count = wp_count_comments( $post_id );^M
162682 return array(^M
162683 "approved" => $count->approved,^M
162684 "awaiting_moderation" => $count->moderated,^M
162685 "spam" => $count->spam,^M
162686 "total_comments" => $count->total_comments^M
162687 );^M
162688 }^M
162689 ^M
162690 /**^M
162691 * Retrieve post statuses.^M
162692 *^M
162693 * @since 2.5.0^M
162694 *^M
162695 * @param array $args Method parameters.^M
162696 * @return array^M
162697 */^M
162698 function wp_getPostStatusList( $args ) {^M
162699 $this->escape( $args );^M
162700 ^M
162701 $blog_id = (int) $args[0];^M
162702 $username = $args[1];^M
162703 $password = $args[2];^M
162704 ^M
162705 if( !$this->login_pass_ok( $username, $password ) ) {^M
162706 return $this->error;^M
162707 }^M
162708 ^M
162709 set_current_user( 0, $username );^M
162710 if( !current_user_can( 'edit_posts' ) ) {^M
162711 return new IXR_Error( 403, __( 'You are not allowed access to details about this blog.' ) );^M
162712 }^M
162713 ^M
162714 do_action('xmlrpc_call', 'wp.getPostStatusList');^M
162715 ^M
162716 return get_post_statuses( );^M
162717 }^M
162718 ^M
162719 /**^M
162720 * Retrieve page statuses.^M
162721 *^M
162722 * @since 2.5.0^M
162723 *^M
162724 * @param array $args Method parameters.^M
162725 * @return array^M
162726 */^M
162727 function wp_getPageStatusList( $args ) {^M
162728 $this->escape( $args );^M
162729 ^M
162730 $blog_id = (int) $args[0];^M
162731 $username = $args[1];^M
162732 $password = $args[2];^M
162733 ^M
162734 if( !$this->login_pass_ok( $username, $password ) ) {^M
162735 return $this->error;^M
162736 }^M
162737 ^M
162738 set_current_user( 0, $username );^M
162739 if( !current_user_can( 'edit_posts' ) ) {^M
162740 return new IXR_Error( 403, __( 'You are not allowed access to details about this blog.' ) );^M
162741 }^M
162742 ^M
162743 do_action('xmlrpc_call', 'wp.getPageStatusList');^M
162744 ^M
162745 return get_page_statuses( );^M
162746 }^M
162747 ^M
162748 /**^M
162749 * Retrieve page templates.^M
162750 *^M
162751 * @since 2.6.0^M
162752 *^M
162753 * @param array $args Method parameters.^M
162754 * @return array^M
162755 */^M
162756 function wp_getPageTemplates( $args ) {^M
162757 $this->escape( $args );^M
162758 ^M
162759 $blog_id = (int) $args[0];^M
162760 $username = $args[1];^M
162761 $password = $args[2];^M
162762 ^M
162763 if( !$this->login_pass_ok( $username, $password ) ) {^M
162764 return $this->error;^M
162765 }^M
162766 ^M
162767 set_current_user( 0, $username );^M
162768 if( !current_user_can( 'edit_pages' ) ) {^M
162769 return new IXR_Error( 403, __( 'You are not allowed access to details about this blog.' ) );^M
162770 }^M
162771 ^M
162772 $templates = get_page_templates( );^M
162773 $templates['Default'] = 'default';^M
162774 ^M
162775 return $templates;^M
162776 }^M
162777 ^M
162778 /**^M
162779 * Retrieve blog options.^M
162780 *^M
162781 * @since 2.6.0^M
162782 *^M
162783 * @param array $args Method parameters.^M
162784 * @return array^M
162785 */^M
162786 function wp_getOptions( $args ) {^M
162787 $this->escape( $args );^M
162788 ^M
162789 $blog_id = (int) $args[0];^M
162790 $username = $args[1];^M
162791 $password = $args[2];^M
162792 $options = (array) $args[3];^M
162793 ^M
162794 if( !$this->login_pass_ok( $username, $password ) )^M
162795 return $this->error;^M
162796 ^M
162797 $user = set_current_user( 0, $username );^M
162798 ^M
162799 // If no specific options where asked for, return all of them^M
162800 if (count( $options ) == 0 ) {^M
162801 $options = array_keys($this->blog_options);^M
162802 }^M
162803 ^M
162804 return $this->_getOptions($options);^M
162805 }^M
162806 ^M
162807 /**^M
162808 * Retrieve blog options value from list.^M
162809 *^M
162810 * @since 2.6.0^M
162811 *^M
162812 * @param array $options Options to retrieve.^M
162813 * @return array^M
162814 */^M
162815 function _getOptions($options)^M
162816 {^M
162817 $data = array( );^M
162818 foreach( $options as $option ) {^M
162819 if( array_key_exists( $option, $this->blog_options ) )^M
162820 {^M
162821 $data[$option] = $this->blog_options[$option];^M
162822 //Is the value static or dynamic?^M
162823 if( isset( $data[$option]['option'] ) ) {^M
162824 $data[$option]['value'] = get_option( $data[$option]['option'] );^M
162825 unset($data[$option]['option']);^M
162826 }^M
162827 }^M
162828 }^M
162829 ^M
162830 return $data;^M
162831 }^M
162832 ^M
162833 /**^M
162834 * Update blog options.^M
162835 *^M
162836 * @since 2.6.0^M
162837 *^M
162838 * @param array $args Method parameters.^M
162839 * @return unknown^M
162840 */^M
162841 function wp_setOptions( $args ) {^M
162842 $this->escape( $args );^M
162843 ^M
162844 $blog_id = (int) $args[0];^M
162845 $username = $args[1];^M
162846 $password = $args[2];^M
162847 $options = (array) $args[3];^M
162848 ^M
162849 if( !$this->login_pass_ok( $username, $password ) )^M
162850 return $this->error;^M
162851 ^M
162852 $user = set_current_user( 0, $username );^M
162853 if( !current_user_can( 'manage_options' ) )^M
162854 return new IXR_Error( 403, __( 'You are not allowed to update options.' ) );^M
162855 ^M
162856 foreach( $options as $o_name => $o_value ) {^M
162857 $option_names[] = $o_name;^M
162858 if( empty( $o_value ) )^M
162859 continue;^M
162860 ^M
162861 if( !array_key_exists( $o_name, $this->blog_options ) )^M
162862 continue;^M
162863 ^M
162864 if( $this->blog_options[$o_name]['readonly'] == true )^M
162865 continue;^M
162866 ^M
162867 update_option( $this->blog_options[$o_name]['option'], $o_value );^M
162868 }^M
162869 ^M
162870 //Now return the updated values^M
162871 return $this->_getOptions($option_names);^M
162872 }^M
162873 ^M
162874 /* Blogger API functions.^M
162875 * specs on http://plant.blogger.com/api and http://groups.yahoo.com/group/bloggerDev/^M
162876 */^M
162877 ^M
162878 /**^M
162879 * Retrieve blogs that user owns.^M
162880 *^M
162881 * Will make more sense once we support multiple blogs.^M
162882 *^M
162883 * @since 1.5.0^M
162884 *^M
162885 * @param array $args Method parameters.^M
162886 * @return array^M
162887 */^M
162888 function blogger_getUsersBlogs($args) {^M
162889 ^M
162890 $this->escape($args);^M
162891 ^M
162892 $user_login = $args[1];^M
162893 $user_pass = $args[2];^M
162894 ^M
162895 if (!$this->login_pass_ok($user_login, $user_pass)) {^M
162896 return $this->error;^M
162897 }^M
162898 ^M
162899 do_action('xmlrpc_call', 'blogger.getUsersBlogs');^M
162900 ^M
162901 set_current_user(0, $user_login);^M
162902 $is_admin = current_user_can('manage_options');^M
162903 ^M
162904 $struct = array(^M
162905 'isAdmin' => $is_admin,^M
162906 'url' => get_option('home') . '/',^M
162907 'blogid' => '1',^M
162908 'blogName' => get_option('blogname'),^M
162909 'xmlrpc' => get_option('home') . '/xmlrpc.php',^M
162910 );^M
162911 ^M
162912 return array($struct);^M
162913 }^M
162914 ^M
162915 /**^M
162916 * Retrieve user's data.^M
162917 *^M
162918 * Gives your client some info about you, so you don't have to.^M
162919 *^M
162920 * @since 1.5.0^M
162921 *^M
162922 * @param array $args Method parameters.^M
162923 * @return array^M
162924 */^M
162925 function blogger_getUserInfo($args) {^M
162926 ^M
162927 $this->escape($args);^M
162928 ^M
162929 $user_login = $args[1];^M
162930 $user_pass = $args[2];^M
162931 ^M
162932 if (!$this->login_pass_ok($user_login, $user_pass)) {^M
162933 return $this->error;^M
162934 }^M
162935 ^M
162936 set_current_user( 0, $user_login );^M
162937 if( !current_user_can( 'edit_posts' ) )^M
162938 return new IXR_Error( 401, __( 'Sorry, you do not have access to user data on this blog.' ) );^M
162939 ^M
162940 do_action('xmlrpc_call', 'blogger.getUserInfo');^M
162941 ^M
162942 $user_data = get_userdatabylogin($user_login);^M
162943 ^M
162944 $struct = array(^M
162945 'nickname' => $user_data->nickname,^M
162946 'userid' => $user_data->ID,^M
162947 'url' => $user_data->user_url,^M
162948 'lastname' => $user_data->last_name,^M
162949 'firstname' => $user_data->first_name^M
162950 );^M
162951 ^M
162952 return $struct;^M
162953 }^M
162954 ^M
162955 /**^M
162956 * Retrieve post.^M
162957 *^M
162958 * @since 1.5.0^M
162959 *^M
162960 * @param array $args Method parameters.^M
162961 * @return array^M
162962 */^M
162963 function blogger_getPost($args) {^M
162964 ^M
162965 $this->escape($args);^M
162966 ^M
162967 $post_ID = (int) $args[1];^M
162968 $user_login = $args[2];^M
162969 $user_pass = $args[3];^M
162970 ^M
162971 if (!$this->login_pass_ok($user_login, $user_pass)) {^M
162972 return $this->error;^M
162973 }^M
162974 ^M
162975 set_current_user( 0, $user_login );^M
162976 if( !current_user_can( 'edit_post', $post_ID ) )^M
162977 return new IXR_Error( 401, __( 'Sorry, you can not edit this post.' ) );^M
162978 ^M
162979 do_action('xmlrpc_call', 'blogger.getPost');^M
162980 ^M
162981 $post_data = wp_get_single_post($post_ID, ARRAY_A);^M
162982 ^M
162983 $categories = implode(',', wp_get_post_categories($post_ID));^M
162984 ^M
162985 $content = '<title>'.stripslashes($post_data['post_title']).'</title>';^M
162986 $content .= '<category>'.$categories.'</category>';^M
162987 $content .= stripslashes($post_data['post_content']);^M
162988 ^M
162989 $struct = array(^M
162990 'userid' => $post_data['post_author'],^M
162991 'dateCreated' => new IXR_Date(mysql2date('Ymd\TH:i:s', $post_data['post_date'])),^M
162992 'content' => $content,^M
162993 'postid' => $post_data['ID']^M
162994 );^M
162995 ^M
162996 return $struct;^M
162997 }^M
162998 ^M
162999 /**^M
163000 * Retrieve list of recent posts.^M
163001 *^M
163002 * @since 1.5.0^M
163003 *^M
163004 * @param array $args Method parameters.^M
163005 * @return array^M
163006 */^M
163007 function blogger_getRecentPosts($args) {^M
163008 ^M
163009 $this->escape($args);^M
163010 ^M
163011 $blog_ID = (int) $args[1]; /* though we don't use it yet */^M
163012 $user_login = $args[2];^M
163013 $user_pass = $args[3];^M
163014 $num_posts = $args[4];^M
163015 ^M
163016 if (!$this->login_pass_ok($user_login, $user_pass)) {^M
163017 return $this->error;^M
163018 }^M
163019 ^M
163020 do_action('xmlrpc_call', 'blogger.getRecentPosts');^M
163021 ^M
163022 $posts_list = wp_get_recent_posts($num_posts);^M
163023 ^M
163024 set_current_user( 0, $user_login );^M
163025 ^M
163026 if (!$posts_list) {^M
163027 $this->error = new IXR_Error(500, __('Either there are no posts, or something went wrong.'));^M
163028 return $this->error;^M
163029 }^M
163030 ^M
163031 foreach ($posts_list as $entry) {^M
163032 if( !current_user_can( 'edit_post', $entry['ID'] ) )^M
163033 continue;^M
163034 ^M
163035 $post_date = mysql2date('Ymd\TH:i:s', $entry['post_date']);^M
163036 $categories = implode(',', wp_get_post_categories($entry['ID']));^M
163037 ^M
163038 $content = '<title>'.stripslashes($entry['post_title']).'</title>';^M
163039 $content .= '<category>'.$categories.'</category>';^M
163040 $content .= stripslashes($entry['post_content']);^M
163041 ^M
163042 $struct[] = array(^M
163043 'userid' => $entry['post_author'],^M
163044 'dateCreated' => new IXR_Date($post_date),^M
163045 'content' => $content,^M
163046 'postid' => $entry['ID'],^M
163047 );^M
163048 ^M
163049 }^M
163050 ^M
163051 $recent_posts = array();^M
163052 for ($j=0; $j<count($struct); $j++) {^M
163053 array_push($recent_posts, $struct[$j]);^M
163054 }^M
163055 ^M
163056 return $recent_posts;^M
163057 }^M
163058 ^M
163059 /**^M
163060 * Retrieve blog_filename content.^M
163061 *^M
163062 * @since 1.5.0^M
163063 *^M
163064 * @param array $args Method parameters.^M
163065 * @return string^M
163066 */^M
163067 function blogger_getTemplate($args) {^M
163068 ^M
163069 $this->escape($args);^M
163070 ^M
163071 $blog_ID = (int) $args[1];^M
163072 $user_login = $args[2];^M
163073 $user_pass = $args[3];^M
163074 $template = $args[4]; /* could be 'main' or 'archiveIndex', but we don't use it */^M
163075 ^M
163076 if (!$this->login_pass_ok($user_login, $user_pass)) {^M
163077 return $this->error;^M
163078 }^M
163079 ^M
163080 do_action('xmlrpc_call', 'blogger.getTemplate');^M
163081 ^M
163082 set_current_user(0, $user_login);^M
163083 if ( !current_user_can('edit_themes') ) {^M
163084 return new IXR_Error(401, __('Sorry, this user can not edit the template.'));^M
163085 }^M
163086 ^M
163087 /* warning: here we make the assumption that the blog's URL is on the same server */^M
163088 $filename = get_option('home') . '/';^M
163089 $filename = preg_replace('#https?://.+?/#', $_SERVER['DOCUMENT_ROOT'].'/', $filename);^M
163090 ^M
163091 $f = fopen($filename, 'r');^M
163092 $content = fread($f, filesize($filename));^M
163093 fclose($f);^M
163094 ^M
163095 /* so it is actually editable with a windows/mac client */^M
163096 // 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);^M
163097 ^M
163098 return $content;^M
163099 }^M
163100 ^M
163101 /**^M
163102 * Updates the content of blog_filename.^M
163103 *^M
163104 * @since 1.5.0^M
163105 *^M
163106 * @param array $args Method parameters.^M
163107 * @return bool True when done.^M
163108 */^M
163109 function blogger_setTemplate($args) {^M
163110 ^M
163111 $this->escape($args);^M
163112 ^M
163113 $blog_ID = (int) $args[1];^M
163114 $user_login = $args[2];^M
163115 $user_pass = $args[3];^M
163116 $content = $args[4];^M
163117 $template = $args[5]; /* could be 'main' or 'archiveIndex', but we don't use it */^M
163118 ^M
163119 if (!$this->login_pass_ok($user_login, $user_pass)) {^M
163120 return $this->error;^M
163121 }^M
163122 ^M
163123 do_action('xmlrpc_call', 'blogger.setTemplate');^M
163124 ^M
163125 set_current_user(0, $user_login);^M
163126 if ( !current_user_can('edit_themes') ) {^M
163127 return new IXR_Error(401, __('Sorry, this user can not edit the template.'));^M
163128 }^M
163129 ^M
163130 /* warning: here we make the assumption that the blog's URL is on the same server */^M
163131 $filename = get_option('home') . '/';^M
163132 $filename = preg_replace('#https?://.+?/#', $_SERVER['DOCUMENT_ROOT'].'/', $filename);^M
163133 ^M
163134 if ($f = fopen($filename, 'w+')) {^M
163135 fwrite($f, $content);^M
163136 fclose($f);^M
163137 } else {^M
163138 return new IXR_Error(500, __('Either the file is not writable, or something wrong happened. The file has not been updated.'));^M
163139 }^M
163140 ^M
163141 return true;^M
163142 }^M
163143 ^M
163144 /**^M
163145 * Create new post.^M
163146 *^M
163147 * @since 1.5.0^M
163148 *^M
163149 * @param array $args Method parameters.^M
163150 * @return int^M
163151 */^M
163152 function blogger_newPost($args) {^M
163153 ^M
163154 $this->escape($args);^M
163155 ^M
163156 $blog_ID = (int) $args[1]; /* though we don't use it yet */^M
163157 $user_login = $args[2];^M
163158 $user_pass = $args[3];^M
163159 $content = $args[4];^M
163160 $publish = $args[5];^M
163161 ^M
163162 if (!$this->login_pass_ok($user_login, $user_pass)) {^M
163163 return $this->error;^M
163164 }^M
163165 ^M
163166 do_action('xmlrpc_call', 'blogger.newPost');^M
163167 ^M
163168 $cap = ($publish) ? 'publish_posts' : 'edit_posts';^M
163169 $user = set_current_user(0, $user_login);^M
163170 if ( !current_user_can($cap) )^M
163171 return new IXR_Error(401, __('Sorry, you are not allowed to post on this blog.'));^M
163172 ^M
163173 $post_status = ($publish) ? 'publish' : 'draft';^M
163174 ^M
163175 $post_author = $user->ID;^M
163176 ^M
163177 $post_title = xmlrpc_getposttitle($content);^M
163178 $post_category = xmlrpc_getpostcategory($content);^M
163179 $post_content = xmlrpc_removepostdata($content);^M
163180 ^M
163181 $post_date = current_time('mysql');^M
163182 $post_date_gmt = current_time('mysql', 1);^M
163183 ^M
163184 $post_data = compact('blog_ID', 'post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_title', 'post_category', 'post_status');^M
163185 ^M
163186 $post_ID = wp_insert_post($post_data);^M
163187 if ( is_wp_error( $post_ID ) )^M
163188 return new IXR_Error(500, $post_ID->get_error_message());^M
163189 ^M
163190 if (!$post_ID)^M
163191 return new IXR_Error(500, __('Sorry, your entry could not be posted. Something wrong happened.'));^M
163192 ^M
163193 $this->attach_uploads( $post_ID, $post_content );^M
163194 ^M
163195 logIO('O', "Posted ! ID: $post_ID");^M
163196 ^M
163197 return $post_ID;^M
163198 }^M
163199 ^M
163200 /**^M
163201 * Edit a post.^M
163202 *^M
163203 * @since 1.5.0^M
163204 *^M
163205 * @param array $args Method parameters.^M
163206 * @return bool true when done.^M
163207 */^M
163208 function blogger_editPost($args) {^M
163209 ^M
163210 $this->escape($args);^M
163211 ^M
163212 $post_ID = (int) $args[1];^M
163213 $user_login = $args[2];^M
163214 $user_pass = $args[3];^M
163215 $content = $args[4];^M
163216 $publish = $args[5];^M
163217 ^M
163218 if (!$this->login_pass_ok($user_login, $user_pass)) {^M
163219 return $this->error;^M
163220 }^M
163221 ^M
163222 do_action('xmlrpc_call', 'blogger.editPost');^M
163223 ^M
163224 $actual_post = wp_get_single_post($post_ID,ARRAY_A);^M
163225 ^M
163226 if (!$actual_post || $actual_post['post_type'] != 'post') {^M
163227 return new IXR_Error(404, __('Sorry, no such post.'));^M
163228 }^M
163229 ^M
163230 $this->escape($actual_post);^M
163231 ^M
163232 set_current_user(0, $user_login);^M
163233 if ( !current_user_can('edit_post', $post_ID) )^M
163234 return new IXR_Error(401, __('Sorry, you do not have the right to edit this post.'));^M
163235 ^M
163236 extract($actual_post, EXTR_SKIP);^M
163237 ^M
163238 if ( ('publish' == $post_status) && !current_user_can('publish_posts') )^M
163239 return new IXR_Error(401, __('Sorry, you do not have the right to publish this post.'));^M
163240 ^M
163241 $post_title = xmlrpc_getposttitle($content);^M
163242 $post_category = xmlrpc_getpostcategory($content);^M
163243 $post_content = xmlrpc_removepostdata($content);^M
163244 ^M
163245 $postdata = compact('ID', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt');^M
163246 ^M
163247 $result = wp_update_post($postdata);^M
163248 ^M
163249 if (!$result) {^M
163250 return new IXR_Error(500, __('For some strange yet very annoying reason, this post could not be edited.'));^M
163251 }^M
163252 $this->attach_uploads( $ID, $post_content );^M
163253 ^M
163254 return true;^M
163255 }^M
163256 ^M
163257 /**^M
163258 * Remove a post.^M
163259 *^M
163260 * @since 1.5.0^M
163261 *^M
163262 * @param array $args Method parameters.^M
163263 * @return bool True when post is deleted.^M
163264 */^M
163265 function blogger_deletePost($args) {^M
163266 $this->escape($args);^M
163267 ^M
163268 $post_ID = (int) $args[1];^M
163269 $user_login = $args[2];^M
163270 $user_pass = $args[3];^M
163271 $publish = $args[4];^M
163272 ^M
163273 if (!$this->login_pass_ok($user_login, $user_pass)) {^M
163274 return $this->error;^M
163275 }^M
163276 ^M
163277 do_action('xmlrpc_call', 'blogger.deletePost');^M
163278 ^M
163279 $actual_post = wp_get_single_post($post_ID,ARRAY_A);^M
163280 ^M
163281 if (!$actual_post || $actual_post['post_type'] != 'post') {^M
163282 return new IXR_Error(404, __('Sorry, no such post.'));^M
163283 }^M
163284 ^M
163285 set_current_user(0, $user_login);^M
163286 if ( !current_user_can('edit_post', $post_ID) )^M
163287 return new IXR_Error(401, __('Sorry, you do not have the right to delete this post.'));^M
163288 ^M
163289 $result = wp_delete_post($post_ID);^M
163290 ^M
163291 if (!$result) {^M
163292 return new IXR_Error(500, __('For some strange yet very annoying reason, this post could not be deleted.'));^M
163293 }^M
163294 ^M
163295 return true;^M
163296 }^M
163297 ^M
163298 /* MetaWeblog API functions^M
163299 * specs on wherever Dave Winer wants them to be^M
163300 */^M
163301 ^M
163302 /**^M
163303 * Create a new post.^M
163304 *^M
163305 * @since 1.5.0^M
163306 *^M
163307 * @param array $args Method parameters.^M
163308 * @return int^M
163309 */^M
163310 function mw_newPost($args) {^M
163311 $this->escape($args);^M
163312 ^M
163313 $blog_ID = (int) $args[0]; // we will support this in the near future^M
163314 $user_login = $args[1];^M
163315 $user_pass = $args[2];^M
163316 $content_struct = $args[3];^M
163317 $publish = $args[4];^M
163318 ^M
163319 if (!$this->login_pass_ok($user_login, $user_pass)) {^M
163320 return $this->error;^M
163321 }^M
163322 $user = set_current_user(0, $user_login);^M
163323 ^M
163324 do_action('xmlrpc_call', 'metaWeblog.newPost');^M
163325 ^M
163326 $cap = ( $publish ) ? 'publish_posts' : 'edit_posts';^M
163327 $error_message = __( 'Sorry, you are not allowed to publish posts on this blog.' );^M
163328 $post_type = 'post';^M
163329 $page_template = '';^M
163330 if( !empty( $content_struct['post_type'] ) ) {^M
163331 if( $content_struct['post_type'] == 'page' ) {^M
163332 $cap = ( $publish ) ? 'publish_pages' : 'edit_pages';^M
163333 $error_message = __( 'Sorry, you are not allowed to publish pages on this blog.' );^M
163334 $post_type = 'page';^M
163335 if( !empty( $content_struct['wp_page_template'] ) )^M
163336 $page_template = $content_struct['wp_page_template'];^M
163337 }^M
163338 elseif( $content_struct['post_type'] == 'post' ) {^M
163339 // This is the default, no changes needed^M
163340 }^M
163341 else {^M
163342 // No other post_type values are allowed here^M
163343 return new IXR_Error( 401, __( 'Invalid post type.' ) );^M
163344 }^M
163345 }^M
163346 ^M
163347 if( !current_user_can( $cap ) ) {^M
163348 return new IXR_Error( 401, $error_message );^M
163349 }^M
163350 ^M
163351 // Let WordPress generate the post_name (slug) unless^M
163352 // one has been provided.^M
163353 $post_name = "";^M
163354 if(isset($content_struct["wp_slug"])) {^M
163355 $post_name = $content_struct["wp_slug"];^M
163356 }^M
163357 ^M
163358 // Only use a password if one was given.^M
163359 if(isset($content_struct["wp_password"])) {^M
163360 $post_password = $content_struct["wp_password"];^M
163361 }^M
163362 ^M
163363 // Only set a post parent if one was provided.^M
163364 if(isset($content_struct["wp_page_parent_id"])) {^M
163365 $post_parent = $content_struct["wp_page_parent_id"];^M
163366 }^M
163367 ^M
163368 // Only set the menu_order if it was provided.^M
163369 if(isset($content_struct["wp_page_order"])) {^M
163370 $menu_order = $content_struct["wp_page_order"];^M
163371 }^M
163372 ^M
163373 $post_author = $user->ID;^M
163374 ^M
163375 // If an author id was provided then use it instead.^M
163376 if(^M
163377 isset($content_struct["wp_author_id"])^M
163378 && ($user->ID != $content_struct["wp_author_id"])^M
163379 ) {^M
163380 switch($post_type) {^M
163381 case "post":^M
163382 if(!current_user_can("edit_others_posts")) {^M
163383 return(new IXR_Error(401, __("You are not allowed to post as this user")));^M
163384 }^M
163385 break;^M
163386 case "page":^M
163387 if(!current_user_can("edit_others_pages")) {^M
163388 return(new IXR_Error(401, __("You are not allowed to create pages as this user")));^M
163389 }^M
163390 break;^M
163391 default:^M
163392 return(new IXR_Error(401, __("Invalid post type.")));^M
163393 break;^M
163394 }^M
163395 $post_author = $content_struct["wp_author_id"];^M
163396 }^M
163397 ^M
163398 $post_title = $content_struct['title'];^M
163399 $post_content = apply_filters( 'content_save_pre', $content_struct['description'] );^M
163400 ^M
163401 $post_status = $publish ? 'publish' : 'draft';^M
163402 ^M
163403 if( isset( $content_struct["{$post_type}_status"] ) ) {^M
163404 switch( $content_struct["{$post_type}_status"] ) {^M
163405 case 'draft':^M
163406 case 'private':^M
163407 case 'publish':^M
163408 $post_status = $content_struct["{$post_type}_status"];^M
163409 break;^M
163410 case 'pending':^M
163411 // Pending is only valid for posts, not pages.^M
163412 if( $post_type === 'post' ) {^M
163413 $post_status = $content_struct["{$post_type}_status"];^M
163414 }^M
163415 break;^M
163416 default:^M
163417 $post_status = $publish ? 'publish' : 'draft';^M
163418 break;^M
163419 }^M
163420 }^M
163421 ^M
163422 $post_excerpt = $content_struct['mt_excerpt'];^M
163423 $post_more = $content_struct['mt_text_more'];^M
163424 ^M
163425 $tags_input = $content_struct['mt_keywords'];^M
163426 ^M
163427 if(isset($content_struct["mt_allow_comments"])) {^M
163428 if(!is_numeric($content_struct["mt_allow_comments"])) {^M
163429 switch($content_struct["mt_allow_comments"]) {^M
163430 case "closed":^M
163431 $comment_status = "closed";^M
163432 break;^M
163433 case "open":^M
163434 $comment_status = "open";^M
163435 break;^M
163436 default:^M
163437 $comment_status = get_option("default_comment_status");^M
163438 break;^M
163439 }^M
163440 }^M
163441 else {^M
163442 switch((int) $content_struct["mt_allow_comments"]) {^M
163443 case 0:^M
163444 case 2:^M
163445 $comment_status = "closed";^M
163446 break;^M
163447 case 1:^M
163448 $comment_status = "open";^M
163449 break;^M
163450 default:^M
163451 $comment_status = get_option("default_comment_status");^M
163452 break;^M
163453 }^M
163454 }^M
163455 }^M
163456 else {^M
163457 $comment_status = get_option("default_comment_status");^M
163458 }^M
163459 ^M
163460 if(isset($content_struct["mt_allow_pings"])) {^M
163461 if(!is_numeric($content_struct["mt_allow_pings"])) {^M
163462 switch($content_struct['mt_allow_pings']) {^M
163463 case "closed":^M
163464 $ping_status = "closed";^M
163465 break;^M
163466 case "open":^M
163467 $ping_status = "open";^M
163468 break;^M
163469 default:^M
163470 $ping_status = get_option("default_ping_status");^M
163471 break;^M
163472 }^M
163473 }^M
163474 else {^M
163475 switch((int) $content_struct["mt_allow_pings"]) {^M
163476 case 0:^M
163477 $ping_status = "closed";^M
163478 break;^M
163479 case 1:^M
163480 $ping_status = "open";^M
163481 break;^M
163482 default:^M
163483 $ping_status = get_option("default_ping_status");^M
163484 break;^M
163485 }^M
163486 }^M
163487 }^M
163488 else {^M
163489 $ping_status = get_option("default_ping_status");^M
163490 }^M
163491 ^M
163492 if ($post_more) {^M
163493 $post_content = $post_content . "<!--more-->" . $post_more;^M
163494 }^M
163495 ^M
163496 $to_ping = $content_struct['mt_tb_ping_urls'];^M
163497 if ( is_array($to_ping) )^M
163498 $to_ping = implode(' ', $to_ping);^M
163499 ^M
163500 // Do some timestamp voodoo^M
163501 if ( !empty( $content_struct['date_created_gmt'] ) )^M
163502 $dateCreated = str_replace( 'Z', '', $content_struct['date_created_gmt']->getIso() ) . 'Z'; // We know this is supposed to be GMT, so we're going to slap that Z on there by force^M
163503 elseif ( !empty( $content_struct['dateCreated']) )^M
163504 $dateCreated = $content_struct['dateCreated']->getIso();^M
163505 ^M
163506 if ( !empty( $dateCreated ) ) {^M
163507 $post_date = get_date_from_gmt(iso8601_to_datetime($dateCreated));^M
163508 $post_date_gmt = iso8601_to_datetime($dateCreated, GMT);^M
163509 } else {^M
163510 $post_date = current_time('mysql');^M
163511 $post_date_gmt = current_time('mysql', 1);^M
163512 }^M
163513 ^M
163514 $catnames = $content_struct['categories'];^M
163515 logIO('O', 'Post cats: ' . var_export($catnames,true));^M
163516 $post_category = array();^M
163517 ^M
163518 if (is_array($catnames)) {^M
163519 foreach ($catnames as $cat) {^M
163520 $post_category[] = get_cat_ID($cat);^M
163521 }^M
163522 }^M
163523 ^M
163524 // We've got all the data -- post it:^M
163525 $postdata = compact('post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt', 'comment_status', 'ping_status', 'to_ping', 'post_type', 'post_name', 'post_password', 'post_parent', 'menu_order', 'tags_input', 'page_template');^M
163526 ^M
163527 $post_ID = wp_insert_post($postdata, true);^M
163528 if ( is_wp_error( $post_ID ) )^M
163529 return new IXR_Error(500, $post_ID->get_error_message());^M
163530 ^M
163531 if (!$post_ID) {^M
163532 return new IXR_Error(500, __('Sorry, your entry could not be posted. Something wrong happened.'));^M
163533 }^M
163534 ^M
163535 if ( isset($content_struct['custom_fields']) ) {^M
163536 $this->set_custom_fields($post_ID, $content_struct['custom_fields']);^M
163537 }^M
163538 ^M
163539 // Handle enclosures^M
163540 $enclosure = $content_struct['enclosure'];^M
163541 if( is_array( $enclosure ) && isset( $enclosure['url'] ) && isset( $enclosure['length'] ) && isset( $enclosure['type'] ) ) {^M
163542 add_post_meta( $post_ID, 'enclosure', $enclosure['url'] . "\n" . $enclosure['length'] . "\n" . $enclosure['type'] );^M
163543 }^M
163544 ^M
163545 $this->attach_uploads( $post_ID, $post_content );^M
163546 ^M
163547 logIO('O', "Posted ! ID: $post_ID");^M
163548 ^M
163549 return strval($post_ID);^M
163550 }^M
163551 ^M
163552 /**^M
163553 * Attach upload to a post.^M
163554 *^M
163555 * @since 2.1.0^M
163556 *^M
163557 * @param int $post_ID Post ID.^M
163558 * @param string $post_content Post Content for attachment.^M
163559 */^M
163560 function attach_uploads( $post_ID, $post_content ) {^M
163561 global $wpdb;^M
163562 ^M
163563 // find any unattached files^M
163564 $attachments = $wpdb->get_results( "SELECT ID, guid FROM {$wpdb->posts} WHERE post_parent = '-1' AND post_type = 'attachment'" );^M
163565 if( is_array( $attachments ) ) {^M
163566 foreach( $attachments as $file ) {^M
163567 if( strpos( $post_content, $file->guid ) !== false ) {^M
163568 $wpdb->query( $wpdb->prepare("UPDATE {$wpdb->posts} SET post_parent = %d WHERE ID = %d", $post_ID, $file->ID) );^M
163569 }^M
163570 }^M
163571 }^M
163572 }^M
163573 ^M
163574 /**^M
163575 * Edit a post.^M
163576 *^M
163577 * @since 1.5.0^M
163578 *^M
163579 * @param array $args Method parameters.^M
163580 * @return bool True on success.^M
163581 */^M
163582 function mw_editPost($args) {^M
163583 ^M
163584 $this->escape($args);^M
163585 ^M
163586 $post_ID = (int) $args[0];^M
163587 $user_login = $args[1];^M
163588 $user_pass = $args[2];^M
163589 $content_struct = $args[3];^M
163590 $publish = $args[4];^M
163591 ^M
163592 if (!$this->login_pass_ok($user_login, $user_pass)) {^M
163593 return $this->error;^M
163594 }^M
163595 $user = set_current_user(0, $user_login);^M
163596 ^M
163597 do_action('xmlrpc_call', 'metaWeblog.editPost');^M
163598 ^M
163599 $cap = ( $publish ) ? 'publish_posts' : 'edit_posts';^M
163600 $error_message = __( 'Sorry, you are not allowed to publish posts on this blog.' );^M
163601 $post_type = 'post';^M
163602 $page_template = '';^M
163603 if( !empty( $content_struct['post_type'] ) ) {^M
163604 if( $content_struct['post_type'] == 'page' ) {^M
163605 $cap = ( $publish ) ? 'publish_pages' : 'edit_pages';^M
163606 $error_message = __( 'Sorry, you are not allowed to publish pages on this blog.' );^M
163607 $post_type = 'page';^M
163608 if( !empty( $content_struct['wp_page_template'] ) )^M
163609 $page_template = $content_struct['wp_page_template'];^M
163610 }^M
163611 elseif( $content_struct['post_type'] == 'post' ) {^M
163612 // This is the default, no changes needed^M
163613 }^M
163614 else {^M
163615 // No other post_type values are allowed here^M
163616 return new IXR_Error( 401, __( 'Invalid post type.' ) );^M
163617 }^M
163618 }^M
163619 ^M
163620 if( !current_user_can( $cap ) ) {^M
163621 return new IXR_Error( 401, $error_message );^M
163622 }^M
163623 ^M
163624 $postdata = wp_get_single_post($post_ID, ARRAY_A);^M
163625 ^M
163626 // If there is no post data for the give post id, stop^M
163627 // now and return an error. Other wise a new post will be^M
163628 // created (which was the old behavior).^M
163629 if(empty($postdata["ID"])) {^M
163630 return(new IXR_Error(404, __("Invalid post id.")));^M
163631 }^M
163632 ^M
163633 $this->escape($postdata);^M
163634 extract($postdata, EXTR_SKIP);^M
163635 ^M
163636 // Let WordPress manage slug if none was provided.^M
163637 $post_name = "";^M
163638 if(isset($content_struct["wp_slug"])) {^M
163639 $post_name = $content_struct["wp_slug"];^M
163640 }^M
163641 ^M
163642 // Only use a password if one was given.^M
163643 if(isset($content_struct["wp_password"])) {^M
163644 $post_password = $content_struct["wp_password"];^M
163645 }^M
163646 ^M
163647 // Only set a post parent if one was given.^M
163648 if(isset($content_struct["wp_page_parent_id"])) {^M
163649 $post_parent = $content_struct["wp_page_parent_id"];^M
163650 }^M
163651 ^M
163652 // Only set the menu_order if it was given.^M
163653 if(isset($content_struct["wp_page_order"])) {^M
163654 $menu_order = $content_struct["wp_page_order"];^M
163655 }^M
163656 ^M
163657 $post_author = $postdata["post_author"];^M
163658 ^M
163659 // Only set the post_author if one is set.^M
163660 if(^M
163661 isset($content_struct["wp_author_id"])^M
163662 && ($user->ID != $content_struct["wp_author_id"])^M
163663 ) {^M
163664 switch($post_type) {^M
163665 case "post":^M
163666 if(!current_user_can("edit_others_posts")) {^M
163667 return(new IXR_Error(401, __("You are not allowed to change the post author as this user.")));^M
163668 }^M
163669 break;^M
163670 case "page":^M
163671 if(!current_user_can("edit_others_pages")) {^M
163672 return(new IXR_Error(401, __("You are not allowed to change the page author as this user.")));^M
163673 }^M
163674 break;^M
163675 default:^M
163676 return(new IXR_Error(401, __("Invalid post type.")));^M
163677 break;^M
163678 }^M
163679 $post_author = $content_struct["wp_author_id"];^M
163680 }^M
163681 ^M
163682 if(isset($content_struct["mt_allow_comments"])) {^M
163683 if(!is_numeric($content_struct["mt_allow_comments"])) {^M
163684 switch($content_struct["mt_allow_comments"]) {^M
163685 case "closed":^M
163686 $comment_status = "closed";^M
163687 break;^M
163688 case "open":^M
163689 $comment_status = "open";^M
163690 break;^M
163691 default:^M
163692 $comment_status = get_option("default_comment_status");^M
163693 break;^M
163694 }^M
163695 }^M
163696 else {^M
163697 switch((int) $content_struct["mt_allow_comments"]) {^M
163698 case 0:^M
163699 case 2:^M
163700 $comment_status = "closed";^M
163701 break;^M
163702 case 1:^M
163703 $comment_status = "open";^M
163704 break;^M
163705 default:^M
163706 $comment_status = get_option("default_comment_status");^M
163707 break;^M
163708 }^M
163709 }^M
163710 }^M
163711 ^M
163712 if(isset($content_struct["mt_allow_pings"])) {^M
163713 if(!is_numeric($content_struct["mt_allow_pings"])) {^M
163714 switch($content_struct["mt_allow_pings"]) {^M
163715 case "closed":^M
163716 $ping_status = "closed";^M
163717 break;^M
163718 case "open":^M
163719 $ping_status = "open";^M
163720 break;^M
163721 default:^M
163722 $ping_status = get_option("default_ping_status");^M
163723 break;^M
163724 }^M
163725 }^M
163726 else {^M
163727 switch((int) $content_struct["mt_allow_pings"]) {^M
163728 case 0:^M
163729 $ping_status = "closed";^M
163730 break;^M
163731 case 1:^M
163732 $ping_status = "open";^M
163733 break;^M
163734 default:^M
163735 $ping_status = get_option("default_ping_status");^M
163736 break;^M
163737 }^M
163738 }^M
163739 }^M
163740 ^M
163741 $post_title = $content_struct['title'];^M
163742 $post_content = apply_filters( 'content_save_pre', $content_struct['description'] );^M
163743 $catnames = $content_struct['categories'];^M
163744 ^M
163745 $post_category = array();^M
163746 ^M
163747 if (is_array($catnames)) {^M
163748 foreach ($catnames as $cat) {^M
163749 $post_category[] = get_cat_ID($cat);^M
163750 }^M
163751 }^M
163752 ^M
163753 $post_excerpt = $content_struct['mt_excerpt'];^M
163754 $post_more = $content_struct['mt_text_more'];^M
163755 ^M
163756 $post_status = $publish ? 'publish' : 'draft';^M
163757 if( isset( $content_struct["{$post_type}_status"] ) ) {^M
163758 switch( $content_struct["{$post_type}_status"] ) {^M
163759 case 'draft':^M
163760 case 'private':^M
163761 case 'publish':^M
163762 $post_status = $content_struct["{$post_type}_status"];^M
163763 break;^M
163764 case 'pending':^M
163765 // Pending is only valid for posts, not pages.^M
163766 if( $post_type === 'post' ) {^M
163767 $post_status = $content_struct["{$post_type}_status"];^M
163768 }^M
163769 break;^M
163770 default:^M
163771 $post_status = $publish ? 'publish' : 'draft';^M
163772 break;^M
163773 }^M
163774 }^M
163775 ^M
163776 $tags_input = $content_struct['mt_keywords'];^M
163777 ^M
163778 if ( ('publish' == $post_status) ) {^M
163779 if ( ( 'page' == $post_type ) && !current_user_can('publish_pages') )^M
163780 return new IXR_Error(401, __('Sorry, you do not have the right to publish this page.'));^M
163781 else if ( !current_user_can('publish_posts') )^M
163782 return new IXR_Error(401, __('Sorry, you do not have the right to publish this post.'));^M
163783 }^M
163784 ^M
163785 if ($post_more) {^M
163786 $post_content = $post_content . "<!--more-->" . $post_more;^M
163787 }^M
163788 ^M
163789 $to_ping = $content_struct['mt_tb_ping_urls'];^M
163790 if ( is_array($to_ping) )^M
163791 $to_ping = implode(' ', $to_ping);^M
163792 ^M
163793 // Do some timestamp voodoo^M
163794 if ( !empty( $content_struct['date_created_gmt'] ) )^M
163795 $dateCreated = str_replace( 'Z', '', $content_struct['date_created_gmt']->getIso() ) . 'Z'; // We know this is supposed to be GMT, so we're going to slap that Z on there by force^M
163796 elseif ( !empty( $content_struct['dateCreated']) )^M
163797 $dateCreated = $content_struct['dateCreated']->getIso();^M
163798 ^M
163799 if ( !empty( $dateCreated ) ) {^M
163800 $post_date = get_date_from_gmt(iso8601_to_datetime($dateCreated));^M
163801 $post_date_gmt = iso8601_to_datetime($dateCreated, GMT);^M
163802 } else {^M
163803 $post_date = $postdata['post_date'];^M
163804 $post_date_gmt = $postdata['post_date_gmt'];^M
163805 }^M
163806 ^M
163807 // We've got all the data -- post it:^M
163808 $newpost = compact('ID', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt', 'comment_status', 'ping_status', 'post_date', 'post_date_gmt', 'to_ping', 'post_name', 'post_password', 'post_parent', 'menu_order', 'post_author', 'tags_input', 'page_template');^M
163809 ^M
163810 $result = wp_update_post($newpost, true);^M
163811 if ( is_wp_error( $result ) )^M
163812 return new IXR_Error(500, $result->get_error_message());^M
163813 ^M
163814 if (!$result) {^M
163815 return new IXR_Error(500, __('Sorry, your entry could not be edited. Something wrong happened.'));^M
163816 }^M
163817 ^M
163818 if ( isset($content_struct['custom_fields']) ) {^M
163819 $this->set_custom_fields($post_ID, $content_struct['custom_fields']);^M
163820 }^M
163821 ^M
163822 // Handle enclosures^M
163823 $enclosure = $content_struct['enclosure'];^M
163824 if( is_array( $enclosure ) && isset( $enclosure['url'] ) && isset( $enclosure['length'] ) && isset( $enclosure['type'] ) ) {^M
163825 add_post_meta( $post_ID, 'enclosure', $enclosure['url'] . "\n" . $enclosure['length'] . "\n" . $enclosure['type'] );^M
163826 }^M
163827 ^M
163828 $this->attach_uploads( $ID, $post_content );^M
163829 ^M
163830 logIO('O',"(MW) Edited ! ID: $post_ID");^M
163831 ^M
163832 return true;^M
163833 }^M
163834 ^M
163835 /**^M
163836 * Retrieve post.^M
163837 *^M
163838 * @since 1.5.0^M
163839 *^M
163840 * @param array $args Method parameters.^M
163841 * @return array^M
163842 */^M
163843 function mw_getPost($args) {^M
163844 ^M
163845 $this->escape($args);^M
163846 ^M
163847 $post_ID = (int) $args[0];^M
163848 $user_login = $args[1];^M
163849 $user_pass = $args[2];^M
163850 ^M
163851 if (!$this->login_pass_ok($user_login, $user_pass)) {^M
163852 return $this->error;^M
163853 }^M
163854 ^M
163855 set_current_user( 0, $user_login );^M
163856 if( !current_user_can( 'edit_post', $post_ID ) )^M
163857 return new IXR_Error( 401, __( 'Sorry, you can not edit this post.' ) );^M
163858 ^M
163859 do_action('xmlrpc_call', 'metaWeblog.getPost');^M
163860 ^M
163861 $postdata = wp_get_single_post($post_ID, ARRAY_A);^M
163862 ^M
163863 if ($postdata['post_date'] != '') {^M
163864 $post_date = mysql2date('Ymd\TH:i:s', $postdata['post_date']);^M
163865 $post_date_gmt = mysql2date('Ymd\TH:i:s', $postdata['post_date_gmt']);^M
163866 ^M
163867 $categories = array();^M
163868 $catids = wp_get_post_categories($post_ID);^M
163869 foreach($catids as $catid)^M
163870 $categories[] = get_cat_name($catid);^M
163871 ^M
163872 $tagnames = array();^M
163873 $tags = wp_get_post_tags( $post_ID );^M
163874 if ( !empty( $tags ) ) {^M
163875 foreach ( $tags as $tag )^M
163876 $tagnames[] = $tag->name;^M
163877 $tagnames = implode( ', ', $tagnames );^M
163878 } else {^M
163879 $tagnames = '';^M
163880 }^M
163881 ^M
163882 $post = get_extended($postdata['post_content']);^M
163883 $link = post_permalink($postdata['ID']);^M
163884 ^M
163885 // Get the author info.^M
163886 $author = get_userdata($postdata['post_author']);^M
163887 ^M
163888 $allow_comments = ('open' == $postdata['comment_status']) ? 1 : 0;^M
163889 $allow_pings = ('open' == $postdata['ping_status']) ? 1 : 0;^M
163890 ^M
163891 // Consider future posts as published^M
163892 if( $postdata['post_status'] === 'future' ) {^M
163893 $postdata['post_status'] = 'publish';^M
163894 }^M
163895 ^M
163896 $enclosure = array();^M
163897 foreach ( (array) get_post_custom($post_ID) as $key => $val) {^M
163898 if ($key == 'enclosure') {^M
163899 foreach ( (array) $val as $enc ) {^M
163900 $encdata = split("\n", $enc);^M
163901 $enclosure['url'] = trim(htmlspecialchars($encdata[0]));^M
163902 $enclosure['length'] = trim($encdata[1]);^M
163903 $enclosure['type'] = trim($encdata[2]);^M
163904 break 2;^M
163905 }^M
163906 }^M
163907 }^M
163908 ^M
163909 $resp = array(^M
163910 'dateCreated' => new IXR_Date($post_date),^M
163911 'userid' => $postdata['post_author'],^M
163912 'postid' => $postdata['ID'],^M
163913 'description' => $post['main'],^M
163914 'title' => $postdata['post_title'],^M
163915 'link' => $link,^M
163916 'permaLink' => $link,^M
163917 // commented out because no other tool seems to use this^M
163918 // 'content' => $entry['post_content'],^M
163919 'categories' => $categories,^M
163920 'mt_excerpt' => $postdata['post_excerpt'],^M
163921 'mt_text_more' => $post['extended'],^M
163922 'mt_allow_comments' => $allow_comments,^M
163923 'mt_allow_pings' => $allow_pings,^M
163924 'mt_keywords' => $tagnames,^M
163925 'wp_slug' => $postdata['post_name'],^M
163926 'wp_password' => $postdata['post_password'],^M
163927 'wp_author_id' => $author->ID,^M
163928 'wp_author_display_name' => $author->display_name,^M
163929 'date_created_gmt' => new IXR_Date($post_date_gmt),^M
163930 'post_status' => $postdata['post_status'],^M
163931 'custom_fields' => $this->get_custom_fields($post_ID)^M
163932 );^M
163933 ^M
163934 if (!empty($enclosure)) $resp['enclosure'] = $enclosure;^M
163935 ^M
163936 return $resp;^M
163937 } else {^M
163938 return new IXR_Error(404, __('Sorry, no such post.'));^M
163939 }^M
163940 }^M
163941 ^M
163942 /**^M
163943 * Retrieve list of recent posts.^M
163944 *^M
163945 * @since 1.5.0^M
163946 *^M
163947 * @param array $args Method parameters.^M
163948 * @return array^M
163949 */^M
163950 function mw_getRecentPosts($args) {^M
163951 ^M
163952 $this->escape($args);^M
163953 ^M
163954 $blog_ID = (int) $args[0];^M
163955 $user_login = $args[1];^M
163956 $user_pass = $args[2];^M
163957 $num_posts = (int) $args[3];^M
163958 ^M
163959 if (!$this->login_pass_ok($user_login, $user_pass)) {^M
163960 return $this->error;^M
163961 }^M
163962 ^M
163963 do_action('xmlrpc_call', 'metaWeblog.getRecentPosts');^M
163964 ^M
163965 $posts_list = wp_get_recent_posts($num_posts);^M
163966 ^M
163967 if (!$posts_list) {^M
163968 return array( );^M
163969 }^M
163970 ^M
163971 set_current_user( 0, $user_login );^M
163972 ^M
163973 foreach ($posts_list as $entry) {^M
163974 if( !current_user_can( 'edit_post', $entry['ID'] ) )^M
163975 continue;^M
163976 ^M
163977 $post_date = mysql2date('Ymd\TH:i:s', $entry['post_date']);^M
163978 $post_date_gmt = mysql2date('Ymd\TH:i:s', $entry['post_date_gmt']);^M
163979 ^M
163980 $categories = array();^M
163981 $catids = wp_get_post_categories($entry['ID']);^M
163982 foreach($catids as $catid) {^M
163983 $categories[] = get_cat_name($catid);^M
163984 }^M
163985 ^M
163986 $tagnames = array();^M
163987 $tags = wp_get_post_tags( $entry['ID'] );^M
163988 if ( !empty( $tags ) ) {^M
163989 foreach ( $tags as $tag ) {^M
163990 $tagnames[] = $tag->name;^M
163991 }^M
163992 $tagnames = implode( ', ', $tagnames );^M
163993 } else {^M
163994 $tagnames = '';^M
163995 }^M
163996 ^M
163997 $post = get_extended($entry['post_content']);^M
163998 $link = post_permalink($entry['ID']);^M
163999 ^M
164000 // Get the post author info.^M
164001 $author = get_userdata($entry['post_author']);^M
164002 ^M
164003 $allow_comments = ('open' == $entry['comment_status']) ? 1 : 0;^M
164004 $allow_pings = ('open' == $entry['ping_status']) ? 1 : 0;^M
164005 ^M
164006 // Consider future posts as published^M
164007 if( $entry['post_status'] === 'future' ) {^M
164008 $entry['post_status'] = 'publish';^M
164009 }^M
164010 ^M
164011 $struct[] = array(^M
164012 'dateCreated' => new IXR_Date($post_date),^M
164013 'userid' => $entry['post_author'],^M
164014 'postid' => $entry['ID'],^M
164015 'description' => $post['main'],^M
164016 'title' => $entry['post_title'],^M
164017 'link' => $link,^M
164018 'permaLink' => $link,^M
164019 // commented out because no other tool seems to use this^M
164020 // 'content' => $entry['post_content'],^M
164021 'categories' => $categories,^M
164022 'mt_excerpt' => $entry['post_excerpt'],^M
164023 'mt_text_more' => $post['extended'],^M
164024 'mt_allow_comments' => $allow_comments,^M
164025 'mt_allow_pings' => $allow_pings,^M
164026 'mt_keywords' => $tagnames,^M
164027 'wp_slug' => $entry['post_name'],^M
164028 'wp_password' => $entry['post_password'],^M
164029 'wp_author_id' => $author->ID,^M
164030 'wp_author_display_name' => $author->display_name,^M
164031 'date_created_gmt' => new IXR_Date($post_date_gmt),^M
164032 'post_status' => $entry['post_status'],^M
164033 'custom_fields' => $this->get_custom_fields($entry['ID'])^M
164034 );^M
164035 ^M
164036 }^M
164037 ^M
164038 $recent_posts = array();^M
164039 for ($j=0; $j<count($struct); $j++) {^M
164040 array_push($recent_posts, $struct[$j]);^M
164041 }^M
164042 ^M
164043 return $recent_posts;^M
164044 }^M
164045 ^M
164046 /**^M
164047 * Retrieve the list of categories on a given blog.^M
164048 *^M
164049 * @since 1.5.0^M
164050 *^M
164051 * @param array $args Method parameters.^M
164052 * @return array^M
164053 */^M
164054 function mw_getCategories($args) {^M
164055 ^M
164056 $this->escape($args);^M
164057 ^M
164058 $blog_ID = (int) $args[0];^M
164059 $user_login = $args[1];^M
164060 $user_pass = $args[2];^M
164061 ^M
164062 if (!$this->login_pass_ok($user_login, $user_pass)) {^M
164063 return $this->error;^M
164064 }^M
164065 ^M
164066 set_current_user( 0, $user_login );^M
164067 if( !current_user_can( 'edit_posts' ) )^M
164068 return new IXR_Error( 401, __( 'Sorry, you must be able to edit posts on this blog in order to view categories.' ) );^M
164069 ^M
164070 do_action('xmlrpc_call', 'metaWeblog.getCategories');^M
164071 ^M
164072 $categories_struct = array();^M
164073 ^M
164074 if ( $cats = get_categories('get=all') ) {^M
164075 foreach ( $cats as $cat ) {^M
164076 $struct['categoryId'] = $cat->term_id;^M
164077 $struct['parentId'] = $cat->parent;^M
164078 $struct['description'] = $cat->description;^M
164079 $struct['categoryName'] = $cat->name;^M
164080 $struct['htmlUrl'] = wp_specialchars(get_category_link($cat->term_id));^M
164081 $struct['rssUrl'] = wp_specialchars(get_category_feed_link($cat->term_id, 'rss2'));^M
164082 ^M
164083 $categories_struct[] = $struct;^M
164084 }^M
164085 }^M
164086 ^M
164087 return $categories_struct;^M
164088 }^M
164089 ^M
164090 /**^M
164091 * Uploads a file, following your settings.^M
164092 *^M
164093 * Adapted from a patch by Johann Richard.^M
164094 *^M
164095 * @link http://mycvs.org/archives/2004/06/30/file-upload-to-wordpress-in-ecto/^M
164096 *^M
164097 * @since 1.5.0^M
164098 *^M
164099 * @param array $args Method parameters.^M
164100 * @return array^M
164101 */^M
164102 function mw_newMediaObject($args) {^M
164103 global $wpdb;^M
164104 ^M
164105 $blog_ID = (int) $args[0];^M
164106 $user_login = $wpdb->escape($args[1]);^M
164107 $user_pass = $wpdb->escape($args[2]);^M
164108 $data = $args[3];^M
164109 ^M
164110 $name = sanitize_file_name( $data['name'] );^M
164111 $type = $data['type'];^M
164112 $bits = $data['bits'];^M
164113 ^M
164114 logIO('O', '(MW) Received '.strlen($bits).' bytes');^M
164115 ^M
164116 if ( !$this->login_pass_ok($user_login, $user_pass) )^M
164117 return $this->error;^M
164118 ^M
164119 do_action('xmlrpc_call', 'metaWeblog.newMediaObject');^M
164120 ^M
164121 set_current_user(0, $user_login);^M
164122 if ( !current_user_can('upload_files') ) {^M
164123 logIO('O', '(MW) User does not have upload_files capability');^M
164124 $this->error = new IXR_Error(401, __('You are not allowed to upload files to this site.'));^M
164125 return $this->error;^M
164126 }^M
164127 ^M
164128 if ( $upload_err = apply_filters( "pre_upload_error", false ) )^M
164129 return new IXR_Error(500, $upload_err);^M
164130 ^M
164131 if(!empty($data["overwrite"]) && ($data["overwrite"] == true)) {^M
164132 // Get postmeta info on the object.^M
164133 $old_file = $wpdb->get_row("^M
164134 SELECT ID^M
164135 FROM {$wpdb->posts}^M
164136 WHERE post_title = '{$name}'^M
164137 AND post_type = 'attachment'^M
164138 ");^M
164139 ^M
164140 // Delete previous file.^M
164141 wp_delete_attachment($old_file->ID);^M
164142 ^M
164143 // Make sure the new name is different by pre-pending the^M
164144 // previous post id.^M
164145 $filename = preg_replace("/^wpid\d+-/", "", $name);^M
164146 $name = "wpid{$old_file->ID}-{$filename}";^M
164147 }^M
164148 ^M
164149 $upload = wp_upload_bits($name, $type, $bits);^M
164150 if ( ! empty($upload['error']) ) {^M
164151 $errorString = sprintf(__('Could not write file %1$s (%2$s)'), $name, $upload['error']);^M
164152 logIO('O', '(MW) ' . $errorString);^M
164153 return new IXR_Error(500, $errorString);^M
164154 }^M
164155 // Construct the attachment array^M
164156 // attach to post_id -1^M
164157 $post_id = -1;^M
164158 $attachment = array(^M
164159 'post_title' => $name,^M
164160 'post_content' => '',^M
164161 'post_type' => 'attachment',^M
164162 'post_parent' => $post_id,^M
164163 'post_mime_type' => $type,^M
164164 'guid' => $upload[ 'url' ]^M
164165 );^M
164166 ^M
164167 // Save the data^M
164168 $id = wp_insert_attachment( $attachment, $upload[ 'file' ], $post_id );^M
164169 wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $upload['file'] ) );^M
164170 ^M
164171 return apply_filters( 'wp_handle_upload', array( 'file' => $name, 'url' => $upload[ 'url' ], 'type' => $type ) );^M
164172 }^M
164173 ^M
164174 /* MovableType API functions^M
164175 * specs on http://www.movabletype.org/docs/mtmanual_programmatic.html^M
164176 */^M
164177 ^M
164178 /**^M
164179 * Retrieve the post titles of recent posts.^M
164180 *^M
164181 * @since 1.5.0^M
164182 *^M
164183 * @param array $args Method parameters.^M
164184 * @return array^M
164185 */^M
164186 function mt_getRecentPostTitles($args) {^M
164187 ^M
164188 $this->escape($args);^M
164189 ^M
164190 $blog_ID = (int) $args[0];^M
164191 $user_login = $args[1];^M
164192 $user_pass = $args[2];^M
164193 $num_posts = (int) $args[3];^M
164194 ^M
164195 if (!$this->login_pass_ok($user_login, $user_pass)) {^M
164196 return $this->error;^M
164197 }^M
164198 ^M
164199 do_action('xmlrpc_call', 'mt.getRecentPostTitles');^M
164200 ^M
164201 $posts_list = wp_get_recent_posts($num_posts);^M
164202 ^M
164203 if (!$posts_list) {^M
164204 $this->error = new IXR_Error(500, __('Either there are no posts, or something went wrong.'));^M
164205 return $this->error;^M
164206 }^M
164207 ^M
164208 set_current_user( 0, $user_login );^M
164209 ^M
164210 foreach ($posts_list as $entry) {^M
164211 if( !current_user_can( 'edit_post', $entry['ID'] ) )^M
164212 continue;^M
164213 ^M
164214 $post_date = mysql2date('Ymd\TH:i:s', $entry['post_date']);^M
164215 $post_date_gmt = mysql2date('Ymd\TH:i:s', $entry['post_date_gmt']);^M
164216 ^M
164217 $struct[] = array(^M
164218 'dateCreated' => new IXR_Date($post_date),^M
164219 'userid' => $entry['post_author'],^M
164220 'postid' => $entry['ID'],^M
164221 'title' => $entry['post_title'],^M
164222 'date_created_gmt' => new IXR_Date($post_date_gmt)^M
164223 );^M
164224 ^M
164225 }^M
164226 ^M
164227 $recent_posts = array();^M
164228 for ($j=0; $j<count($struct); $j++) {^M
164229 array_push($recent_posts, $struct[$j]);^M
164230 }^M
164231 ^M
164232 return $recent_posts;^M
164233 }^M
164234 ^M
164235 /**^M
164236 * Retrieve list of all categories on blog.^M
164237 *^M
164238 * @since 1.5.0^M
164239 *^M
164240 * @param array $args Method parameters.^M
164241 * @return array^M
164242 */^M
164243 function mt_getCategoryList($args) {^M
164244 ^M
164245 $this->escape($args);^M
164246 ^M
164247 $blog_ID = (int) $args[0];^M
164248 $user_login = $args[1];^M
164249 $user_pass = $args[2];^M
164250 ^M
164251 if (!$this->login_pass_ok($user_login, $user_pass)) {^M
164252 return $this->error;^M
164253 }^M
164254 ^M
164255 set_current_user( 0, $user_login );^M
164256 if( !current_user_can( 'edit_posts' ) )^M
164257 return new IXR_Error( 401, __( 'Sorry, you must be able to edit posts on this blog in order to view categories.' ) );^M
164258 ^M
164259 do_action('xmlrpc_call', 'mt.getCategoryList');^M
164260 ^M
164261 $categories_struct = array();^M
164262 ^M
164263 if ( $cats = get_categories('hide_empty=0&hierarchical=0') ) {^M
164264 foreach ($cats as $cat) {^M
164265 $struct['categoryId'] = $cat->term_id;^M
164266 $struct['categoryName'] = $cat->name;^M
164267 ^M
164268 $categories_struct[] = $struct;^M
164269 }^M
164270 }^M
164271 ^M
164272 return $categories_struct;^M
164273 }^M
164274 ^M
164275 /**^M
164276 * Retrieve post categories.^M
164277 *^M
164278 * @since 1.5.0^M
164279 *^M
164280 * @param array $args Method parameters.^M
164281 * @return array^M
164282 */^M
164283 function mt_getPostCategories($args) {^M
164284 ^M
164285 $this->escape($args);^M
164286 ^M
164287 $post_ID = (int) $args[0];^M
164288 $user_login = $args[1];^M
164289 $user_pass = $args[2];^M
164290 ^M
164291 if (!$this->login_pass_ok($user_login, $user_pass)) {^M
164292 return $this->error;^M
164293 }^M
164294 ^M
164295 set_current_user( 0, $user_login );^M
164296 if( !current_user_can( 'edit_post', $post_ID ) )^M
164297 return new IXR_Error( 401, __( 'Sorry, you can not edit this post.' ) );^M
164298 ^M
164299 do_action('xmlrpc_call', 'mt.getPostCategories');^M
164300 ^M
164301 $categories = array();^M
164302 $catids = wp_get_post_categories(intval($post_ID));^M
164303 // first listed category will be the primary category^M
164304 $isPrimary = true;^M
164305 foreach($catids as $catid) {^M
164306 $categories[] = array(^M
164307 'categoryName' => get_cat_name($catid),^M
164308 'categoryId' => (string) $catid,^M
164309 'isPrimary' => $isPrimary^M
164310 );^M
164311 $isPrimary = false;^M
164312 }^M
164313 ^M
164314 return $categories;^M
164315 }^M
164316 ^M
164317 /**^M
164318 * Sets categories for a post.^M
164319 *^M
164320 * @since 1.5.0^M
164321 *^M
164322 * @param array $args Method parameters.^M
164323 * @return bool True on success.^M
164324 */^M
164325 function mt_setPostCategories($args) {^M
164326 ^M
164327 $this->escape($args);^M
164328 ^M
164329 $post_ID = (int) $args[0];^M
164330 $user_login = $args[1];^M
164331 $user_pass = $args[2];^M
164332 $categories = $args[3];^M
164333 ^M
164334 if (!$this->login_pass_ok($user_login, $user_pass)) {^M
164335 return $this->error;^M
164336 }^M
164337 ^M
164338 do_action('xmlrpc_call', 'mt.setPostCategories');^M
164339 ^M
164340 set_current_user(0, $user_login);^M
164341 if ( !current_user_can('edit_post', $post_ID) )^M
164342 return new IXR_Error(401, __('Sorry, you can not edit this post.'));^M
164343 ^M
164344 foreach($categories as $cat) {^M
164345 $catids[] = $cat['categoryId'];^M
164346 }^M
164347 ^M
164348 wp_set_post_categories($post_ID, $catids);^M
164349 ^M
164350 return true;^M
164351 }^M
164352 ^M
164353 /**^M
164354 * Retrieve an array of methods supported by this server.^M
164355 *^M
164356 * @since 1.5.0^M
164357 *^M
164358 * @param array $args Method parameters.^M
164359 * @return array^M
164360 */^M
164361 function mt_supportedMethods($args) {^M
164362 ^M
164363 do_action('xmlrpc_call', 'mt.supportedMethods');^M
164364 ^M
164365 $supported_methods = array();^M
164366 foreach($this->methods as $key=>$value) {^M
164367 $supported_methods[] = $key;^M
164368 }^M
164369 ^M
164370 return $supported_methods;^M
164371 }^M
164372 ^M
164373 /**^M
164374 * Retrieve an empty array because we don't support per-post text filters.^M
164375 *^M
164376 * @since 1.5.0^M
164377 *^M
164378 * @param array $args Method parameters.^M
164379 */^M
164380 function mt_supportedTextFilters($args) {^M
164381 do_action('xmlrpc_call', 'mt.supportedTextFilters');^M
164382 return apply_filters('xmlrpc_text_filters', array());^M
164383 }^M
164384 ^M
164385 /**^M
164386 * Retrieve trackbacks sent to a given post.^M
164387 *^M
164388 * @since 1.5.0^M
164389 *^M
164390 * @param array $args Method parameters.^M
164391 * @return mixed^M
164392 */^M
164393 function mt_getTrackbackPings($args) {^M
164394 ^M
164395 global $wpdb;^M
164396 ^M
164397 $post_ID = intval($args);^M
164398 ^M
164399 do_action('xmlrpc_call', 'mt.getTrackbackPings');^M
164400 ^M
164401 $actual_post = wp_get_single_post($post_ID, ARRAY_A);^M
164402 ^M
164403 if (!$actual_post) {^M
164404 return new IXR_Error(404, __('Sorry, no such post.'));^M
164405 }^M
164406 ^M
164407 $comments = $wpdb->get_results( $wpdb->prepare("SELECT comment_author_url, comment_content, comment_author_IP, comment_type FROM $wpdb->comments WHERE comment_post_ID = %d", $post_ID) );^M
164408 ^M
164409 if (!$comments) {^M
164410 return array();^M
164411 }^M
164412 ^M
164413 $trackback_pings = array();^M
164414 foreach($comments as $comment) {^M
164415 if ( 'trackback' == $comment->comment_type ) {^M
164416 $content = $comment->comment_content;^M
164417 $title = substr($content, 8, (strpos($content, '</strong>') - 8));^M
164418 $trackback_pings[] = array(^M
164419 'pingTitle' => $title,^M
164420 'pingURL' => $comment->comment_author_url,^M
164421 'pingIP' => $comment->comment_author_IP^M
164422 );^M
164423 }^M
164424 }^M
164425 ^M
164426 return $trackback_pings;^M
164427 }^M
164428 ^M
164429 /**^M
164430 * Sets a post's publish status to 'publish'.^M
164431 *^M
164432 * @since 1.5.0^M
164433 *^M
164434 * @param array $args Method parameters.^M
164435 * @return int^M
164436 */^M
164437 function mt_publishPost($args) {^M
164438 ^M
164439 $this->escape($args);^M
164440 ^M
164441 $post_ID = (int) $args[0];^M
164442 $user_login = $args[1];^M
164443 $user_pass = $args[2];^M
164444 ^M
164445 if (!$this->login_pass_ok($user_login, $user_pass)) {^M
164446 return $this->error;^M
164447 }^M
164448 ^M
164449 do_action('xmlrpc_call', 'mt.publishPost');^M
164450 ^M
164451 set_current_user(0, $user_login);^M
164452 if ( !current_user_can('edit_post', $post_ID) )^M
164453 return new IXR_Error(401, __('Sorry, you can not edit this post.'));^M
164454 ^M
164455 $postdata = wp_get_single_post($post_ID,ARRAY_A);^M
164456 ^M
164457 $postdata['post_status'] = 'publish';^M
164458 ^M
164459 // retain old cats^M
164460 $cats = wp_get_post_categories($post_ID);^M
164461 $postdata['post_category'] = $cats;^M
164462 $this->escape($postdata);^M
164463 ^M
164464 $result = wp_update_post($postdata);^M
164465 ^M
164466 return $result;^M
164467 }^M
164468 ^M
164469 /* PingBack functions^M
164470 * specs on www.hixie.ch/specs/pingback/pingback^M
164471 */^M
164472 ^M
164473 /**^M
164474 * Retrieves a pingback and registers it.^M
164475 *^M
164476 * @since 1.5.0^M
164477 *^M
164478 * @param array $args Method parameters.^M
164479 * @return array^M
164480 */^M
164481 function pingback_ping($args) {^M
164482 global $wpdb;^M
164483 ^M
164484 do_action('xmlrpc_call', 'pingback.ping');^M
164485 ^M
164486 $this->escape($args);^M
164487 ^M
164488 $pagelinkedfrom = $args[0];^M
164489 $pagelinkedto = $args[1];^M
164490 ^M
164491 $title = '';^M
164492 ^M
164493 $pagelinkedfrom = str_replace('&', '&', $pagelinkedfrom);^M
164494 $pagelinkedto = str_replace('&', '&', $pagelinkedto);^M
164495 $pagelinkedto = str_replace('&', '&', $pagelinkedto);^M
164496 ^M
164497 // Check if the page linked to is in our site^M
164498 $pos1 = strpos($pagelinkedto, str_replace(array('http://www.','http://','https://www.','https://'), '', get_option('home')));^M
164499 if( !$pos1 )^M
164500 return new IXR_Error(0, __('Is there no link to us?'));^M
164501 ^M
164502 // let's find which post is linked to^M
164503 // FIXME: does url_to_postid() cover all these cases already?^M
164504 // if so, then let's use it and drop the old code.^M
164505 $urltest = parse_url($pagelinkedto);^M
164506 if ($post_ID = url_to_postid($pagelinkedto)) {^M
164507 $way = 'url_to_postid()';^M
164508 } elseif (preg_match('#p/[0-9]{1,}#', $urltest['path'], $match)) {^M
164509 // the path defines the post_ID (archives/p/XXXX)^M
164510 $blah = explode('/', $match[0]);^M
164511 $post_ID = (int) $blah[1];^M
164512 $way = 'from the path';^M
164513 } elseif (preg_match('#p=[0-9]{1,}#', $urltest['query'], $match)) {^M
164514 // the querystring defines the post_ID (?p=XXXX)^M
164515 $blah = explode('=', $match[0]);^M
164516 $post_ID = (int) $blah[1];^M
164517 $way = 'from the querystring';^M
164518 } elseif (isset($urltest['fragment'])) {^M
164519 // an #anchor is there, it's either...^M
164520 if (intval($urltest['fragment'])) {^M
164521 // ...an integer #XXXX (simpliest case)^M
164522 $post_ID = (int) $urltest['fragment'];^M
164523 $way = 'from the fragment (numeric)';^M
164524 } elseif (preg_match('/post-[0-9]+/',$urltest['fragment'])) {^M
164525 // ...a post id in the form 'post-###'^M
164526 $post_ID = preg_replace('/[^0-9]+/', '', $urltest['fragment']);^M
164527 $way = 'from the fragment (post-###)';^M
164528 } elseif (is_string($urltest['fragment'])) {^M
164529 // ...or a string #title, a little more complicated^M
164530 $title = preg_replace('/[^a-z0-9]/i', '.', $urltest['fragment']);^M
164531 $sql = $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE post_title RLIKE %s", $title);^M
164532 if (! ($post_ID = $wpdb->get_var($sql)) ) {^M
164533 // returning unknown error '0' is better than die()ing^M
164534 return new IXR_Error(0, '');^M
164535 }^M
164536 $way = 'from the fragment (title)';^M
164537 }^M
164538 } else {^M
164539 // TODO: Attempt to extract a post ID from the given URL^M
164540 return new IXR_Error(33, __('The specified target URL cannot be used as a target. It either doesn\'t exist, or it is not a pingback-enabled resource.'));^M
164541 }^M
164542 $post_ID = (int) $post_ID;^M
164543 ^M
164544 ^M
164545 logIO("O","(PB) URL='$pagelinkedto' ID='$post_ID' Found='$way'");^M
164546 ^M
164547 $post = get_post($post_ID);^M
164548 ^M
164549 if ( !$post ) // Post_ID not found^M
164550 return new IXR_Error(33, __('The specified target URL cannot be used as a target. It either doesn\'t exist, or it is not a pingback-enabled resource.'));^M
164551 ^M
164552 if ( $post_ID == url_to_postid($pagelinkedfrom) )^M
164553 return new IXR_Error(0, __('The source URL and the target URL cannot both point to the same resource.'));^M
164554 ^M
164555 // Check if pings are on^M
164556 if ( !pings_open($post) )^M
164557 return new IXR_Error(33, __('The specified target URL cannot be used as a target. It either doesn\'t exist, or it is not a pingback-enabled resource.'));^M
164558 ^M
164559 // Let's check that the remote site didn't already pingback this entry^M
164560 $wpdb->get_results( $wpdb->prepare("SELECT * FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_author_url = %s", $post_ID, $pagelinkedfrom) );^M
164561 ^M
164562 if ( $wpdb->num_rows ) // We already have a Pingback from this URL^M
164563 return new IXR_Error(48, __('The pingback has already been registered.'));^M
164564 ^M
164565 // very stupid, but gives time to the 'from' server to publish !^M
164566 sleep(1);^M
164567 ^M
164568 // Let's check the remote site^M
164569 ^M
164570 ^M
164571 // First, make sure we're not being used for DDoS!^M
164572 ^M
164573 if (gethostbyname(parse_url($pagelinkedfrom, PHP_URL_HOST)) <> $_SERVER['REMOTE_ADDR']) { ^M
164574 die ("Sorry, you will have to send this from your actual IP.");^M
164575 mail("office@polimedia.us","trackback",$pagelinkedfrom);^M
164576 }^M
164577 ^M
164578 $linea = wp_remote_fopen( $pagelinkedfrom );^M
164579 if ( !$linea )^M
164580 return new IXR_Error(16, __('The source URL does not exist.'));^M
164581 ^M
164582 $linea = apply_filters('pre_remote_source', $linea, $pagelinkedto);^M
164583 ^M
164584 // Work around bug in strip_tags():^M
164585 $linea = str_replace('<!DOC', '<DOC', $linea);^M
164586 $linea = preg_replace( '/[\s\r\n\t]+/', ' ', $linea ); // normalize spaces^M
164587 $linea = preg_replace( "/ <(h1|h2|h3|h4|h5|h6|p|th|td|li|dt|dd|pre|caption|input|textarea|button|body)[^>]*>/", "\n\n", $linea );^M
164588 ^M
164589 preg_match('|<title>([^<]*?)</title>|is', $linea, $matchtitle);^M
164590 $title = $matchtitle[1];^M
164591 if ( empty( $title ) )^M
164592 return new IXR_Error(32, __('We cannot find a title on that page.'));^M
164593 ^M
164594 $linea = strip_tags( $linea, '<a>' ); // just keep the tag we need^M
164595 ^M
164596 $p = explode( "\n\n", $linea );^M
164597 ^M
164598 $preg_target = preg_quote($pagelinkedto);^M
164599 ^M
164600 foreach ( $p as $para ) {^M
164601 if ( strpos($para, $pagelinkedto) !== false ) { // it exists, but is it a link?^M
164602 preg_match("|<a[^>]+?".$preg_target."[^>]*>([^>]+?)</a>|", $para, $context);^M
164603 ^M
164604 // If the URL isn't in a link context, keep looking^M
164605 if ( empty($context) )^M
164606 continue;^M
164607 ^M
164608 // We're going to use this fake tag to mark the context in a bit^M
164609 // the marker is needed in case the link text appears more than once in the paragraph^M
164610 $excerpt = preg_replace('|\</?wpcontext\>|', '', $para);^M
164611 ^M
164612 // prevent really long link text^M
164613 if ( strlen($context[1]) > 100 )^M
164614 $context[1] = substr($context[1], 0, 100) . '...';^M
164615 ^M
164616 $marker = '<wpcontext>'.$context[1].'</wpcontext>'; // set up our marker^M
164617 $excerpt= str_replace($context[0], $marker, $excerpt); // swap out the link for our marker^M
164618 $excerpt = strip_tags($excerpt, '<wpcontext>'); // strip all tags but our context marker^M
164619 $excerpt = trim($excerpt);^M
164620 $preg_marker = preg_quote($marker);^M
164621 $excerpt = preg_replace("|.*?\s(.{0,100}$preg_marker.{0,100})\s.*|s", '$1', $excerpt);^M
164622 $excerpt = strip_tags($excerpt); // YES, again, to remove the marker wrapper^M
164623 break;^M
164624 }^M
164625 }^M
164626 ^M
164627 if ( empty($context) ) // Link to target not found^M
164628 return new IXR_Error(17, __('The source URL does not contain a link to the target URL, and so cannot be used as a source.'));^M
164629 ^M
164630 $pagelinkedfrom = str_replace('&', '&', $pagelinkedfrom);^M
164631 ^M
164632 $context = '[...] ' . wp_specialchars( $excerpt ) . ' [...]';^M
164633 $pagelinkedfrom = $wpdb->escape( $pagelinkedfrom );^M
164634 ^M
164635 $comment_post_ID = (int) $post_ID;^M
164636 $comment_author = $title;^M
164637 $this->escape($comment_author);^M
164638 $comment_author_url = $pagelinkedfrom;^M
164639 $comment_content = $context;^M
164640 $this->escape($comment_content);^M
164641 $comment_type = 'pingback';^M
164642 ^M
164643 $commentdata = compact('comment_post_ID', 'comment_author', 'comment_author_url', 'comment_content', 'comment_type');^M
164644 ^M
164645 $comment_ID = wp_new_comment($commentdata);^M
164646 do_action('pingback_post', $comment_ID);^M
164647 ^M
164648 return sprintf(__('Pingback from %1$s to %2$s registered. Keep the web talking! :-)'), $pagelinkedfrom, $pagelinkedto);^M
164649 }^M
164650 ^M
164651 /**^M
164652 * Retrieve array of URLs that pingbacked the given URL.^M
164653 *^M
164654 * Specs on http://www.aquarionics.com/misc/archives/blogite/0198.html^M
164655 *^M
164656 * @since 1.5.0^M
164657 *^M
164658 * @param array $args Method parameters.^M
164659 * @return array^M
164660 */^M
164661 function pingback_extensions_getPingbacks($args) {^M
164662 ^M
164663 global $wpdb;^M
164664 ^M
164665 do_action('xmlrpc_call', 'pingback.extensions.getPingsbacks');^M
164666 ^M
164667 $this->escape($args);^M
164668 ^M
164669 $url = $args;^M
164670 ^M
164671 $post_ID = url_to_postid($url);^M
164672 if (!$post_ID) {^M
164673 // We aren't sure that the resource is available and/or pingback enabled^M
164674 return new IXR_Error(33, __('The specified target URL cannot be used as a target. It either doesn\'t exist, or it is not a pingback-enabled resource.'));^M
164675 }^M
164676 ^M
164677 $actual_post = wp_get_single_post($post_ID, ARRAY_A);^M
164678 ^M
164679 if (!$actual_post) {^M
164680 // No such post = resource not found^M
164681 return new IXR_Error(32, __('The specified target URL does not exist.'));^M
164682 }^M
164683 ^M
164684 $comments = $wpdb->get_results( $wpdb->prepare("SELECT comment_author_url, comment_content, comment_author_IP, comment_type FROM $wpdb->comments WHERE comment_post_ID = %d", $post_ID) );^M
164685 ^M
164686 if (!$comments) {^M
164687 return array();^M
164688 }^M
164689 ^M
164690 $pingbacks = array();^M
164691 foreach($comments as $comment) {^M
164692 if ( 'pingback' == $comment->comment_type )^M
164693 $pingbacks[] = $comment->comment_author_url;^M
164694 }^M
164695 ^M
164696 return $pingbacks;^M
164697 }^M
164698 }^M
164699 ^M
164700 $wp_xmlrpc_server = new wp_xmlrpc_server();^M
164701 ^M
164702 ?>^M