wp/wp-includes/class-wp-xmlrpc-server.php
changeset 5 5e2f62d02dcd
parent 0 d970ebf37754
child 7 cf61fcea0001
equal deleted inserted replaced
4:346c88efed21 5:5e2f62d02dcd
     1 <?php
     1 <?php
     2 /**
     2 /**
     3  * XML-RPC protocol support for WordPress
     3  * XML-RPC protocol support for WordPress
     4  *
     4  *
     5  * @package WordPress
     5  * @package WordPress
       
     6  * @subpackage Publishing
     6  */
     7  */
     7 
     8 
     8 /**
     9 /**
     9  * WordPress XMLRPC server implementation.
    10  * WordPress XMLRPC server implementation.
    10  *
    11  *
    18  * @package WordPress
    19  * @package WordPress
    19  * @subpackage Publishing
    20  * @subpackage Publishing
    20  * @since 1.5.0
    21  * @since 1.5.0
    21  */
    22  */
    22 class wp_xmlrpc_server extends IXR_Server {
    23 class wp_xmlrpc_server extends IXR_Server {
    23 
    24 	/**
       
    25 	 * @var array
       
    26 	 */
       
    27 	public $methods;
       
    28 	/**
       
    29 	 * @var array
       
    30 	 */
       
    31 	public $blog_options;
       
    32 	/**
       
    33 	 * @var IXR_Error
       
    34 	 */
       
    35 	public $error;
    24 	/**
    36 	/**
    25 	 * Register all of the XMLRPC methods that XMLRPC server understands.
    37 	 * Register all of the XMLRPC methods that XMLRPC server understands.
    26 	 *
    38 	 *
    27 	 * Sets up server and method property. Passes XMLRPC
    39 	 * Sets up server and method property. Passes XMLRPC
    28 	 * methods through the 'xmlrpc_methods' filter to allow plugins to extend
    40 	 * methods through the 'xmlrpc_methods' filter to allow plugins to extend
    29 	 * or replace XMLRPC methods.
    41 	 * or replace XMLRPC methods.
    30 	 *
    42 	 *
    31 	 * @since 1.5.0
    43 	 * @since 1.5.0
    32 	 *
    44 	 */
    33 	 * @return wp_xmlrpc_server
    45 	public function __construct() {
    34 	 */
       
    35 	function __construct() {
       
    36 		$this->methods = array(
    46 		$this->methods = array(
    37 			// WordPress API
    47 			// WordPress API
    38 			'wp.getUsersBlogs'		=> 'this:wp_getUsersBlogs',
    48 			'wp.getUsersBlogs'		=> 'this:wp_getUsersBlogs',
    39 			'wp.newPost'			=> 'this:wp_newPost',
    49 			'wp.newPost'			=> 'this:wp_newPost',
    40 			'wp.editPost'			=> 'this:wp_editPost',
    50 			'wp.editPost'			=> 'this:wp_editPost',
    63 			'wp.getTags'			=> 'this:wp_getTags',
    73 			'wp.getTags'			=> 'this:wp_getTags',
    64 			'wp.newCategory'		=> 'this:wp_newCategory',
    74 			'wp.newCategory'		=> 'this:wp_newCategory',
    65 			'wp.deleteCategory'		=> 'this:wp_deleteCategory',
    75 			'wp.deleteCategory'		=> 'this:wp_deleteCategory',
    66 			'wp.suggestCategories'	=> 'this:wp_suggestCategories',
    76 			'wp.suggestCategories'	=> 'this:wp_suggestCategories',
    67 			'wp.uploadFile'			=> 'this:mw_newMediaObject',	// Alias
    77 			'wp.uploadFile'			=> 'this:mw_newMediaObject',	// Alias
       
    78 			'wp.deleteFile'			=> 'this:wp_deletePost',		// Alias
    68 			'wp.getCommentCount'	=> 'this:wp_getCommentCount',
    79 			'wp.getCommentCount'	=> 'this:wp_getCommentCount',
    69 			'wp.getPostStatusList'	=> 'this:wp_getPostStatusList',
    80 			'wp.getPostStatusList'	=> 'this:wp_getPostStatusList',
    70 			'wp.getPageStatusList'	=> 'this:wp_getPageStatusList',
    81 			'wp.getPageStatusList'	=> 'this:wp_getPageStatusList',
    71 			'wp.getPageTemplates'	=> 'this:wp_getPageTemplates',
    82 			'wp.getPageTemplates'	=> 'this:wp_getPageTemplates',
    72 			'wp.getOptions'			=> 'this:wp_getOptions',
    83 			'wp.getOptions'			=> 'this:wp_getOptions',
   124 			'demo.sayHello' => 'this:sayHello',
   135 			'demo.sayHello' => 'this:sayHello',
   125 			'demo.addTwoNumbers' => 'this:addTwoNumbers'
   136 			'demo.addTwoNumbers' => 'this:addTwoNumbers'
   126 		);
   137 		);
   127 
   138 
   128 		$this->initialise_blog_option_info();
   139 		$this->initialise_blog_option_info();
   129 		$this->methods = apply_filters('xmlrpc_methods', $this->methods);
   140 
   130 	}
   141 		/**
   131 
   142 		 * Filter the methods exposed by the XML-RPC server.
   132 	function serve_request() {
   143 		 *
       
   144 		 * This filter can be used to add new methods, and remove built-in methods.
       
   145 		 *
       
   146 		 * @since 1.5.0
       
   147 		 *
       
   148 		 * @param array $methods An array of XML-RPC methods.
       
   149 		 */
       
   150 		$this->methods = apply_filters( 'xmlrpc_methods', $this->methods );
       
   151 	}
       
   152 
       
   153 	/**
       
   154 	 * Make private/protected methods readable for backwards compatibility.
       
   155 	 *
       
   156 	 * @since 4.0.0
       
   157 	 * @access public
       
   158 	 *
       
   159 	 * @param callable $name      Method to call.
       
   160 	 * @param array    $arguments Arguments to pass when calling.
       
   161 	 * @return mixed|bool Return value of the callback, false otherwise.
       
   162 	 */
       
   163 	public function __call( $name, $arguments ) {
       
   164 		if ( '_multisite_getUsersBlogs' === $name ) {
       
   165 			return call_user_func_array( array( $this, $name ), $arguments );
       
   166 		}
       
   167 		return false;
       
   168 	}
       
   169 
       
   170 	public function serve_request() {
   133 		$this->IXR_Server($this->methods);
   171 		$this->IXR_Server($this->methods);
   134 	}
   172 	}
   135 
   173 
   136 	/**
   174 	/**
   137 	 * Test XMLRPC API by saying, "Hello!" to client.
   175 	 * Test XMLRPC API by saying, "Hello!" to client.
   139 	 * @since 1.5.0
   177 	 * @since 1.5.0
   140 	 *
   178 	 *
   141 	 * @param array $args Method Parameters.
   179 	 * @param array $args Method Parameters.
   142 	 * @return string
   180 	 * @return string
   143 	 */
   181 	 */
   144 	function sayHello($args) {
   182 	public function sayHello($args) {
   145 		return 'Hello!';
   183 		return 'Hello!';
   146 	}
   184 	}
   147 
   185 
   148 	/**
   186 	/**
   149 	 * Test XMLRPC API by adding two numbers for client.
   187 	 * Test XMLRPC API by adding two numbers for client.
   151 	 * @since 1.5.0
   189 	 * @since 1.5.0
   152 	 *
   190 	 *
   153 	 * @param array $args Method Parameters.
   191 	 * @param array $args Method Parameters.
   154 	 * @return int
   192 	 * @return int
   155 	 */
   193 	 */
   156 	function addTwoNumbers($args) {
   194 	public function addTwoNumbers($args) {
   157 		$number1 = $args[0];
   195 		$number1 = $args[0];
   158 		$number2 = $args[1];
   196 		$number2 = $args[1];
   159 		return $number1 + $number2;
   197 		return $number1 + $number2;
   160 	}
   198 	}
   161 
   199 
   164 	 *
   202 	 *
   165 	 * @since 2.8.0
   203 	 * @since 2.8.0
   166 	 *
   204 	 *
   167 	 * @param string $username User's username.
   205 	 * @param string $username User's username.
   168 	 * @param string $password User's password.
   206 	 * @param string $password User's password.
   169 	 * @return mixed WP_User object if authentication passed, false otherwise
   207 	 * @return WP_User|bool WP_User object if authentication passed, false otherwise
   170 	 */
   208 	 */
   171 	function login( $username, $password ) {
   209 	public function login( $username, $password ) {
   172 		// Respect any old filters against get_option() for 'enable_xmlrpc'.
   210 		/*
   173 		$enabled = apply_filters( 'pre_option_enable_xmlrpc', false ); // Deprecated
   211 		 * Respect old get_option() filters left for back-compat when the 'enable_xmlrpc'
   174 		if ( false === $enabled )
   212 		 * option was deprecated in 3.5.0. Use the 'xmlrpc_enabled' hook instead.
   175 			$enabled = apply_filters( 'option_enable_xmlrpc', true ); // Deprecated
   213 		 */
   176 
   214 		$enabled = apply_filters( 'pre_option_enable_xmlrpc', false );
   177 		// Proper filter for turning off XML-RPC. It is on by default.
   215 		if ( false === $enabled ) {
       
   216 			$enabled = apply_filters( 'option_enable_xmlrpc', true );
       
   217 		}
       
   218 
       
   219 		/**
       
   220 		 * Filter whether XML-RPC is enabled.
       
   221 		 *
       
   222 		 * This is the proper filter for turning off XML-RPC.
       
   223 		 *
       
   224 		 * @since 3.5.0
       
   225 		 *
       
   226 		 * @param bool $enabled Whether XML-RPC is enabled. Default true.
       
   227 		 */
   178 		$enabled = apply_filters( 'xmlrpc_enabled', $enabled );
   228 		$enabled = apply_filters( 'xmlrpc_enabled', $enabled );
   179 
   229 
   180 		if ( ! $enabled ) {
   230 		if ( ! $enabled ) {
   181 			$this->error = new IXR_Error( 405, sprintf( __( 'XML-RPC services are disabled on this site.' ) ) );
   231 			$this->error = new IXR_Error( 405, sprintf( __( 'XML-RPC services are disabled on this site.' ) ) );
   182 			return false;
   232 			return false;
   184 
   234 
   185 		$user = wp_authenticate($username, $password);
   235 		$user = wp_authenticate($username, $password);
   186 
   236 
   187 		if (is_wp_error($user)) {
   237 		if (is_wp_error($user)) {
   188 			$this->error = new IXR_Error( 403, __( 'Incorrect username or password.' ) );
   238 			$this->error = new IXR_Error( 403, __( 'Incorrect username or password.' ) );
       
   239 
       
   240 			/**
       
   241 			 * Filter the XML-RPC user login error message.
       
   242 			 *
       
   243 			 * @since 3.5.0
       
   244 			 *
       
   245 			 * @param string  $error The XML-RPC error message.
       
   246 			 * @param WP_User $user  WP_User object.
       
   247 			 */
   189 			$this->error = apply_filters( 'xmlrpc_login_error', $this->error, $user );
   248 			$this->error = apply_filters( 'xmlrpc_login_error', $this->error, $user );
   190 			return false;
   249 			return false;
   191 		}
   250 		}
   192 
   251 
   193 		wp_set_current_user( $user->ID );
   252 		wp_set_current_user( $user->ID );
   204 	 *
   263 	 *
   205 	 * @param string $username User's username.
   264 	 * @param string $username User's username.
   206 	 * @param string $password User's password.
   265 	 * @param string $password User's password.
   207 	 * @return bool Whether authentication passed.
   266 	 * @return bool Whether authentication passed.
   208 	 */
   267 	 */
   209 	function login_pass_ok( $username, $password ) {
   268 	public function login_pass_ok( $username, $password ) {
   210 		return (bool) $this->login( $username, $password );
   269 		return (bool) $this->login( $username, $password );
   211 	}
   270 	}
   212 
   271 
   213 	/**
   272 	/**
   214 	 * Escape string or array of strings for database.
   273 	 * Escape string or array of strings for database.
   216 	 * @since 1.5.2
   275 	 * @since 1.5.2
   217 	 *
   276 	 *
   218 	 * @param string|array $data Escape single string or array of strings.
   277 	 * @param string|array $data Escape single string or array of strings.
   219 	 * @return string|array Type matches $data and sanitized for the database.
   278 	 * @return string|array Type matches $data and sanitized for the database.
   220 	 */
   279 	 */
   221 	function escape( &$data ) {
   280 	public function escape( &$data ) {
   222 		if ( ! is_array( $data ) )
   281 		if ( ! is_array( $data ) )
   223 			return wp_slash( $data );
   282 			return wp_slash( $data );
   224 
   283 
   225 		foreach ( $data as &$v ) {
   284 		foreach ( $data as &$v ) {
   226 			if ( is_array( $v ) )
   285 			if ( is_array( $v ) )
   236 	 * @since 2.5.0
   295 	 * @since 2.5.0
   237 	 *
   296 	 *
   238 	 * @param int $post_id Post ID.
   297 	 * @param int $post_id Post ID.
   239 	 * @return array Custom fields, if exist.
   298 	 * @return array Custom fields, if exist.
   240 	 */
   299 	 */
   241 	function get_custom_fields($post_id) {
   300 	public function get_custom_fields($post_id) {
   242 		$post_id = (int) $post_id;
   301 		$post_id = (int) $post_id;
   243 
   302 
   244 		$custom_fields = array();
   303 		$custom_fields = array();
   245 
   304 
   246 		foreach ( (array) has_meta($post_id) as $meta ) {
   305 		foreach ( (array) has_meta($post_id) as $meta ) {
   264 	 * @since 2.5.0
   323 	 * @since 2.5.0
   265 	 *
   324 	 *
   266 	 * @param int $post_id Post ID.
   325 	 * @param int $post_id Post ID.
   267 	 * @param array $fields Custom fields.
   326 	 * @param array $fields Custom fields.
   268 	 */
   327 	 */
   269 	function set_custom_fields($post_id, $fields) {
   328 	public function set_custom_fields($post_id, $fields) {
   270 		$post_id = (int) $post_id;
   329 		$post_id = (int) $post_id;
   271 
   330 
   272 		foreach ( (array) $fields as $meta ) {
   331 		foreach ( (array) $fields as $meta ) {
   273 			if ( isset($meta['id']) ) {
   332 			if ( isset($meta['id']) ) {
   274 				$meta['id'] = (int) $meta['id'];
   333 				$meta['id'] = (int) $meta['id'];
   294 	 *
   353 	 *
   295 	 * Passes property through 'xmlrpc_blog_options' filter.
   354 	 * Passes property through 'xmlrpc_blog_options' filter.
   296 	 *
   355 	 *
   297 	 * @since 2.6.0
   356 	 * @since 2.6.0
   298 	 */
   357 	 */
   299 	function initialise_blog_option_info() {
   358 	public function initialise_blog_option_info() {
   300 		global $wp_version;
   359 		global $wp_version;
   301 
   360 
   302 		$this->blog_options = array(
   361 		$this->blog_options = array(
   303 			// Read only options
   362 			// Read only options
   304 			'software_name'     => array(
   363 			'software_name'     => array(
   438 				'readonly'      => false,
   497 				'readonly'      => false,
   439 				'option'        => 'default_ping_status'
   498 				'option'        => 'default_ping_status'
   440 			)
   499 			)
   441 		);
   500 		);
   442 
   501 
       
   502 		/**
       
   503 		 * Filter the XML-RPC blog options property.
       
   504 		 *
       
   505 		 * @since 2.6.0
       
   506 		 *
       
   507 		 * @param array $blog_options An array of XML-RPC blog options.
       
   508 		 */
   443 		$this->blog_options = apply_filters( 'xmlrpc_blog_options', $this->blog_options );
   509 		$this->blog_options = apply_filters( 'xmlrpc_blog_options', $this->blog_options );
   444 	}
   510 	}
   445 
   511 
   446 	/**
   512 	/**
   447 	 * Retrieve the blogs of the user.
   513 	 * Retrieve the blogs of the user.
   449 	 * @since 2.6.0
   515 	 * @since 2.6.0
   450 	 *
   516 	 *
   451 	 * @param array $args Method parameters. Contains:
   517 	 * @param array $args Method parameters. Contains:
   452 	 *  - username
   518 	 *  - username
   453 	 *  - password
   519 	 *  - password
   454 	 * @return array. Contains:
   520 	 * @return array|IXR_Error Array contains:
   455 	 *  - 'isAdmin'
   521 	 *  - 'isAdmin'
   456 	 *  - 'url'
   522 	 *  - 'url'
   457 	 *  - 'blogid'
   523 	 *  - 'blogid'
   458 	 *  - 'blogName'
   524 	 *  - 'blogName'
   459 	 *  - 'xmlrpc' - url of xmlrpc endpoint
   525 	 *  - 'xmlrpc' - url of xmlrpc endpoint
   460 	 */
   526 	 */
   461 	function wp_getUsersBlogs( $args ) {
   527 	public function wp_getUsersBlogs( $args ) {
   462 		global $current_site;
       
   463 		// If this isn't on WPMU then just use blogger_getUsersBlogs
   528 		// If this isn't on WPMU then just use blogger_getUsersBlogs
   464 		if ( !is_multisite() ) {
   529 		if ( !is_multisite() ) {
   465 			array_unshift( $args, 1 );
   530 			array_unshift( $args, 1 );
   466 			return $this->blogger_getUsersBlogs( $args );
   531 			return $this->blogger_getUsersBlogs( $args );
   467 		}
   532 		}
   472 		$password = $args[1];
   537 		$password = $args[1];
   473 
   538 
   474 		if ( !$user = $this->login($username, $password) )
   539 		if ( !$user = $this->login($username, $password) )
   475 			return $this->error;
   540 			return $this->error;
   476 
   541 
       
   542 		/**
       
   543 		 * Fires after the XML-RPC user has been authenticated but before the rest of
       
   544 		 * the method logic begins.
       
   545 		 *
       
   546 		 * All built-in XML-RPC methods use the action xmlrpc_call, with a parameter
       
   547 		 * equal to the method's name, e.g., wp.getUsersBlogs, wp.newPost, etc.
       
   548 		 *
       
   549 		 * @since 2.5.0
       
   550 		 *
       
   551 		 * @param method $name The method name.
       
   552 		 */
   477 		do_action( 'xmlrpc_call', 'wp.getUsersBlogs' );
   553 		do_action( 'xmlrpc_call', 'wp.getUsersBlogs' );
   478 
   554 
   479 		$blogs = (array) get_blogs_of_user( $user->ID );
   555 		$blogs = (array) get_blogs_of_user( $user->ID );
   480 		$struct = array();
   556 		$struct = array();
   481 
   557 
   482 		foreach ( $blogs as $blog ) {
   558 		foreach ( $blogs as $blog ) {
   483 			// Don't include blogs that aren't hosted at this site
   559 			// Don't include blogs that aren't hosted at this site
   484 			if ( $blog->site_id != $current_site->id )
   560 			if ( $blog->site_id != get_current_site()->id )
   485 				continue;
   561 				continue;
   486 
   562 
   487 			$blog_id = $blog->userblog_id;
   563 			$blog_id = $blog->userblog_id;
   488 
   564 
   489 			switch_to_blog( $blog_id );
   565 			switch_to_blog( $blog_id );
   551 			$_taxonomy['show_in_menu'] = (bool) $_taxonomy->show_in_menu;
   627 			$_taxonomy['show_in_menu'] = (bool) $_taxonomy->show_in_menu;
   552 
   628 
   553 		if ( in_array( 'object_type', $fields ) )
   629 		if ( in_array( 'object_type', $fields ) )
   554 			$_taxonomy['object_type'] = array_unique( (array) $taxonomy->object_type );
   630 			$_taxonomy['object_type'] = array_unique( (array) $taxonomy->object_type );
   555 
   631 
       
   632 		/**
       
   633 		 * Filter XML-RPC-prepared data for the given taxonomy.
       
   634 		 *
       
   635 		 * @since 3.4.0
       
   636 		 *
       
   637 		 * @param array  $_taxonomy An array of taxonomy data.
       
   638 		 * @param object $taxonomy  Taxonomy object.
       
   639 		 * @param array  $fields    The subset of taxonomy fields to return.
       
   640 		 */
   556 		return apply_filters( 'xmlrpc_prepare_taxonomy', $_taxonomy, $taxonomy, $fields );
   641 		return apply_filters( 'xmlrpc_prepare_taxonomy', $_taxonomy, $taxonomy, $fields );
   557 	}
   642 	}
   558 
   643 
   559 	/**
   644 	/**
   560 	 * Prepares term data for return in an XML-RPC object.
   645 	 * Prepares term data for return in an XML-RPC object.
   576 		$_term['parent'] = strval( $_term['parent'] );
   661 		$_term['parent'] = strval( $_term['parent'] );
   577 
   662 
   578 		// Count we are happy to return as an integer because people really shouldn't use terms that much.
   663 		// Count we are happy to return as an integer because people really shouldn't use terms that much.
   579 		$_term['count'] = intval( $_term['count'] );
   664 		$_term['count'] = intval( $_term['count'] );
   580 
   665 
       
   666 		/**
       
   667 		 * Filter XML-RPC-prepared data for the given term.
       
   668 		 *
       
   669 		 * @since 3.4.0
       
   670 		 *
       
   671 		 * @param array        $_term An array of term data.
       
   672 		 * @param array|object $term  Term object or array.
       
   673 		 */
   581 		return apply_filters( 'xmlrpc_prepare_term', $_term, $term );
   674 		return apply_filters( 'xmlrpc_prepare_term', $_term, $term );
   582 	}
   675 	}
   583 
   676 
   584 	/**
   677 	/**
   585 	 * Convert a WordPress date string to an IXR_Date object.
   678 	 * Convert a WordPress date string to an IXR_Date object.
   697 				$_post['enclosure']['length'] = (int) trim( $encdata[1] );
   790 				$_post['enclosure']['length'] = (int) trim( $encdata[1] );
   698 				$_post['enclosure']['type'] = trim( $encdata[2] );
   791 				$_post['enclosure']['type'] = trim( $encdata[2] );
   699 			}
   792 			}
   700 		}
   793 		}
   701 
   794 
       
   795 		/**
       
   796 		 * Filter XML-RPC-prepared date for the given post.
       
   797 		 *
       
   798 		 * @since 3.4.0
       
   799 		 *
       
   800 		 * @param array $_post  An array of modified post data.
       
   801 		 * @param array $post   An array of post data.
       
   802 		 * @param array $fields An array of post fields.
       
   803 		 */
   702 		return apply_filters( 'xmlrpc_prepare_post', $_post, $post, $fields );
   804 		return apply_filters( 'xmlrpc_prepare_post', $_post, $post, $fields );
   703 	}
   805 	}
   704 
   806 
   705 	/**
   807 	/**
   706 	 * Prepares post data for return in an XML-RPC object.
   808 	 * Prepares post data for return in an XML-RPC object.
   739 		}
   841 		}
   740 
   842 
   741 		if ( in_array( 'taxonomies', $fields ) )
   843 		if ( in_array( 'taxonomies', $fields ) )
   742 			$_post_type['taxonomies'] = get_object_taxonomies( $post_type->name, 'names' );
   844 			$_post_type['taxonomies'] = get_object_taxonomies( $post_type->name, 'names' );
   743 
   845 
       
   846 		/**
       
   847 		 * Filter XML-RPC-prepared date for the given post type.
       
   848 		 *
       
   849 		 * @since 3.4.0
       
   850 		 *
       
   851 		 * @param array  $_post_type An array of post type data.
       
   852 		 * @param object $post_type  Post type object.
       
   853 		 */
   744 		return apply_filters( 'xmlrpc_prepare_post_type', $_post_type, $post_type );
   854 		return apply_filters( 'xmlrpc_prepare_post_type', $_post_type, $post_type );
   745 	}
   855 	}
   746 
   856 
   747 	/**
   857 	/**
   748 	 * Prepares media item data for return in an XML-RPC object.
   858 	 * Prepares media item data for return in an XML-RPC object.
   769 		if ( $thumbnail_src )
   879 		if ( $thumbnail_src )
   770 			$_media_item['thumbnail'] = $thumbnail_src[0];
   880 			$_media_item['thumbnail'] = $thumbnail_src[0];
   771 		else
   881 		else
   772 			$_media_item['thumbnail'] = $_media_item['link'];
   882 			$_media_item['thumbnail'] = $_media_item['link'];
   773 
   883 
       
   884 		/**
       
   885 		 * Filter XML-RPC-prepared data for the given media item.
       
   886 		 *
       
   887 		 * @since 3.4.0
       
   888 		 *
       
   889 		 * @param array  $_media_item    An array of media item data.
       
   890 		 * @param object $media_item     Media item object.
       
   891 		 * @param string $thumbnail_size Image size.
       
   892 		 */
   774 		return apply_filters( 'xmlrpc_prepare_media_item', $_media_item, $media_item, $thumbnail_size );
   893 		return apply_filters( 'xmlrpc_prepare_media_item', $_media_item, $media_item, $thumbnail_size );
   775 	}
   894 	}
   776 
   895 
   777 	/**
   896 	/**
   778 	 * Prepares page data for return in an XML-RPC object.
   897 	 * Prepares page data for return in an XML-RPC object.
   802 		$page_date = $this->_convert_date( $page->post_date );
   921 		$page_date = $this->_convert_date( $page->post_date );
   803 		$page_date_gmt = $this->_convert_date_gmt( $page->post_date_gmt, $page->post_date );
   922 		$page_date_gmt = $this->_convert_date_gmt( $page->post_date_gmt, $page->post_date );
   804 
   923 
   805 		// Pull the categories info together.
   924 		// Pull the categories info together.
   806 		$categories = array();
   925 		$categories = array();
   807 		foreach ( wp_get_post_categories( $page->ID ) as $cat_id ) {
   926 		if ( is_object_in_taxonomy( 'page', 'category' ) ) {
   808 			$categories[] = get_cat_name( $cat_id );
   927 			foreach ( wp_get_post_categories( $page->ID ) as $cat_id ) {
       
   928 				$categories[] = get_cat_name( $cat_id );
       
   929 			}
   809 		}
   930 		}
   810 
   931 
   811 		// Get the author info.
   932 		// Get the author info.
   812 		$author = get_userdata( $page->post_author );
   933 		$author = get_userdata( $page->post_author );
   813 
   934 
   840 			'date_created_gmt'       => $page_date_gmt,
   961 			'date_created_gmt'       => $page_date_gmt,
   841 			'custom_fields'          => $this->get_custom_fields( $page->ID ),
   962 			'custom_fields'          => $this->get_custom_fields( $page->ID ),
   842 			'wp_page_template'       => $page_template
   963 			'wp_page_template'       => $page_template
   843 		);
   964 		);
   844 
   965 
       
   966 		/**
       
   967 		 * Filter XML-RPC-prepared data for the given page.
       
   968 		 *
       
   969 		 * @since 3.4.0
       
   970 		 *
       
   971 		 * @param array   $_page An array of page data.
       
   972 		 * @param WP_Post $page  Page object.
       
   973 		 */
   845 		return apply_filters( 'xmlrpc_prepare_page', $_page, $page );
   974 		return apply_filters( 'xmlrpc_prepare_page', $_page, $page );
   846 	}
   975 	}
   847 
   976 
   848 	/**
   977 	/**
   849 	 * Prepares comment data for return in an XML-RPC object.
   978 	 * Prepares comment data for return in an XML-RPC object.
   853 	 * @param object $comment The unprepared comment data
   982 	 * @param object $comment The unprepared comment data
   854 	 * @return array The prepared comment data
   983 	 * @return array The prepared comment data
   855 	 */
   984 	 */
   856 	protected function _prepare_comment( $comment ) {
   985 	protected function _prepare_comment( $comment ) {
   857 		// Format page date.
   986 		// Format page date.
   858 		$comment_date = $this->_convert_date( $comment->comment_date );
       
   859 		$comment_date_gmt = $this->_convert_date_gmt( $comment->comment_date_gmt, $comment->comment_date );
   987 		$comment_date_gmt = $this->_convert_date_gmt( $comment->comment_date_gmt, $comment->comment_date );
   860 
   988 
   861 		if ( '0' == $comment->comment_approved )
   989 		if ( '0' == $comment->comment_approved ) {
   862 			$comment_status = 'hold';
   990 			$comment_status = 'hold';
   863 		else if ( 'spam' == $comment->comment_approved )
   991 		} elseif ( 'spam' == $comment->comment_approved ) {
   864 			$comment_status = 'spam';
   992 			$comment_status = 'spam';
   865 		else if ( '1' == $comment->comment_approved )
   993 		} elseif ( '1' == $comment->comment_approved ) {
   866 			$comment_status = 'approve';
   994 			$comment_status = 'approve';
   867 		else
   995 		} else {
   868 			$comment_status = $comment->comment_approved;
   996 			$comment_status = $comment->comment_approved;
   869 
   997 		}
   870 		$_comment = array(
   998 		$_comment = array(
   871 			'date_created_gmt' => $comment_date_gmt,
   999 			'date_created_gmt' => $comment_date_gmt,
   872 			'user_id'          => $comment->user_id,
  1000 			'user_id'          => $comment->user_id,
   873 			'comment_id'       => $comment->comment_ID,
  1001 			'comment_id'       => $comment->comment_ID,
   874 			'parent'           => $comment->comment_parent,
  1002 			'parent'           => $comment->comment_parent,
   882 			'author_email'     => $comment->comment_author_email,
  1010 			'author_email'     => $comment->comment_author_email,
   883 			'author_ip'        => $comment->comment_author_IP,
  1011 			'author_ip'        => $comment->comment_author_IP,
   884 			'type'             => $comment->comment_type,
  1012 			'type'             => $comment->comment_type,
   885 		);
  1013 		);
   886 
  1014 
       
  1015 		/**
       
  1016 		 * Filter XML-RPC-prepared data for the given comment.
       
  1017 		 *
       
  1018 		 * @since 3.4.0
       
  1019 		 *
       
  1020 		 * @param array  $_comment An array of prepared comment data.
       
  1021 		 * @param object $comment  Comment object.
       
  1022 		 */
   887 		return apply_filters( 'xmlrpc_prepare_comment', $_comment, $comment );
  1023 		return apply_filters( 'xmlrpc_prepare_comment', $_comment, $comment );
   888 	}
  1024 	}
   889 
  1025 
   890 	/**
  1026 	/**
   891 	 * Prepares user data for return in an XML-RPC object.
  1027 	 * Prepares user data for return in an XML-RPC object.
   922 			}
  1058 			}
   923 			$requested_fields = array_intersect_key( $user_fields, array_flip( $fields ) );
  1059 			$requested_fields = array_intersect_key( $user_fields, array_flip( $fields ) );
   924 			$_user = array_merge( $_user, $requested_fields );
  1060 			$_user = array_merge( $_user, $requested_fields );
   925 		}
  1061 		}
   926 
  1062 
       
  1063 		/**
       
  1064 		 * Filter XML-RPC-prepared data for the given user.
       
  1065 		 *
       
  1066 		 * @since 3.5.0
       
  1067 		 *
       
  1068 		 * @param array   $_user  An array of user data.
       
  1069 		 * @param WP_User $user   User object.
       
  1070 		 * @param array   $fields An array of user fields.
       
  1071 		 */
   927 		return apply_filters( 'xmlrpc_prepare_user', $_user, $user, $fields );
  1072 		return apply_filters( 'xmlrpc_prepare_user', $_user, $user, $fields );
   928 	}
  1073 	}
   929 
  1074 
   930 	/**
  1075 	/**
   931 	 * Create a new post for any registered post type.
  1076 	 * Create a new post for any registered post type.
   932 	 *
  1077 	 *
   933 	 * @since 3.4.0
  1078 	 * @since 3.4.0
   934 	 *
  1079 	 *
   935 	 * @param array $args Method parameters. Contains:
  1080 	 * @param array $args Method parameters. Contains:
   936 	 *  - int     $blog_id
  1081 	 *  - int     $blog_id (unused)
   937 	 *  - string  $username
  1082 	 *  - string  $username
   938 	 *  - string  $password
  1083 	 *  - string  $password
   939 	 *  - array   $content_struct
  1084 	 *  - array   $content_struct
   940 	 *      $content_struct can contain:
  1085 	 *      $content_struct can contain:
   941 	 *      - post_type (default: 'post')
  1086 	 *      - post_type (default: 'post')
   954 	 *      - custom_fields - array, with each element containing 'key' and 'value'
  1099 	 *      - custom_fields - array, with each element containing 'key' and 'value'
   955 	 *      - terms - array, with taxonomy names as keys and arrays of term IDs as values
  1100 	 *      - terms - array, with taxonomy names as keys and arrays of term IDs as values
   956 	 *      - terms_names - array, with taxonomy names as keys and arrays of term names as values
  1101 	 *      - terms_names - array, with taxonomy names as keys and arrays of term names as values
   957 	 *      - enclosure
  1102 	 *      - enclosure
   958 	 *      - any other fields supported by wp_insert_post()
  1103 	 *      - any other fields supported by wp_insert_post()
   959 	 * @return string post_id
  1104 	 * @return string|IXR_Error post_id
   960 	 */
  1105 	 */
   961 	function wp_newPost( $args ) {
  1106 	public function wp_newPost( $args ) {
   962 		if ( ! $this->minimum_args( $args, 4 ) )
  1107 		if ( ! $this->minimum_args( $args, 4 ) )
   963 			return $this->error;
  1108 			return $this->error;
   964 
  1109 
   965 		$this->escape( $args );
  1110 		$this->escape( $args );
   966 
  1111 
   967 		$blog_id        = (int) $args[0];
       
   968 		$username       = $args[1];
  1112 		$username       = $args[1];
   969 		$password       = $args[2];
  1113 		$password       = $args[2];
   970 		$content_struct = $args[3];
  1114 		$content_struct = $args[3];
   971 
  1115 
   972 		if ( ! $user = $this->login( $username, $password ) )
  1116 		if ( ! $user = $this->login( $username, $password ) )
   973 			return $this->error;
  1117 			return $this->error;
   974 
  1118 
       
  1119 		// convert the date field back to IXR form
       
  1120 		if ( isset( $content_struct['post_date'] ) && ! ( $content_struct['post_date'] instanceof IXR_Date ) ) {
       
  1121 			$content_struct['post_date'] = $this->_convert_date( $content_struct['post_date'] );
       
  1122 		}
       
  1123 
       
  1124 		// ignore the existing GMT date if it is empty or a non-GMT date was supplied in $content_struct,
       
  1125 		// since _insert_post will ignore the non-GMT date if the GMT date is set
       
  1126 		if ( isset( $content_struct['post_date_gmt'] ) && ! ( $content_struct['post_date_gmt'] instanceof IXR_Date ) ) {
       
  1127 			if ( $content_struct['post_date_gmt'] == '0000-00-00 00:00:00' || isset( $content_struct['post_date'] ) ) {
       
  1128 				unset( $content_struct['post_date_gmt'] );
       
  1129 			} else {
       
  1130 				$content_struct['post_date_gmt'] = $this->_convert_date( $content_struct['post_date_gmt'] );
       
  1131 			}
       
  1132 		}
       
  1133 
       
  1134 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
   975 		do_action( 'xmlrpc_call', 'wp.newPost' );
  1135 		do_action( 'xmlrpc_call', 'wp.newPost' );
   976 
  1136 
   977 		unset( $content_struct['ID'] );
  1137 		unset( $content_struct['ID'] );
   978 
  1138 
   979 		return $this->_insert_post( $user, $content_struct );
  1139 		return $this->_insert_post( $user, $content_struct );
   995 	 *
  1155 	 *
   996 	 * @since 3.4.0
  1156 	 * @since 3.4.0
   997 	 * @uses wp_insert_post()
  1157 	 * @uses wp_insert_post()
   998 	 *
  1158 	 *
   999 	 * @param WP_User $user The post author if post_author isn't set in $content_struct.
  1159 	 * @param WP_User $user The post author if post_author isn't set in $content_struct.
  1000 	 * @param array $content_struct Post data to insert.
  1160 	 * @param array|IXR_Error $content_struct Post data to insert.
  1001 	 */
  1161 	 */
  1002 	protected function _insert_post( $user, $content_struct ) {
  1162 	protected function _insert_post( $user, $content_struct ) {
  1003 		$defaults = array( 'post_status' => 'draft', 'post_type' => 'post', 'post_author' => 0,
  1163 		$defaults = array( 'post_status' => 'draft', 'post_type' => 'post', 'post_author' => 0,
  1004 			'post_password' => '', 'post_excerpt' => '', 'post_content' => '', 'post_title' => '' );
  1164 			'post_password' => '', 'post_excerpt' => '', 'post_content' => '', 'post_title' => '' );
  1005 
  1165 
  1129 
  1289 
  1130 					if ( ! current_user_can( $post_type_taxonomies[$taxonomy]->cap->assign_terms ) )
  1290 					if ( ! current_user_can( $post_type_taxonomies[$taxonomy]->cap->assign_terms ) )
  1131 						return new IXR_Error( 401, __( 'Sorry, you are not allowed to assign a term to one of the given taxonomies.' ) );
  1291 						return new IXR_Error( 401, __( 'Sorry, you are not allowed to assign a term to one of the given taxonomies.' ) );
  1132 
  1292 
  1133 					$term_ids = $post_data['terms'][$taxonomy];
  1293 					$term_ids = $post_data['terms'][$taxonomy];
       
  1294 					$terms[ $taxonomy ] = array();
  1134 					foreach ( $term_ids as $term_id ) {
  1295 					foreach ( $term_ids as $term_id ) {
  1135 						$term = get_term_by( 'id', $term_id, $taxonomy );
  1296 						$term = get_term_by( 'id', $term_id, $taxonomy );
  1136 
  1297 
  1137 						if ( ! $term )
  1298 						if ( ! $term )
  1138 							return new IXR_Error( 403, __( 'Invalid term ID' ) );
  1299 							return new IXR_Error( 403, __( 'Invalid term ID' ) );
  1212 		$enclosure = isset( $post_data['enclosure'] ) ? $post_data['enclosure'] : null;
  1373 		$enclosure = isset( $post_data['enclosure'] ) ? $post_data['enclosure'] : null;
  1213 		$this->add_enclosure_if_new( $post_ID, $enclosure );
  1374 		$this->add_enclosure_if_new( $post_ID, $enclosure );
  1214 
  1375 
  1215 		$this->attach_uploads( $post_ID, $post_data['post_content'] );
  1376 		$this->attach_uploads( $post_ID, $post_data['post_content'] );
  1216 
  1377 
       
  1378 		/**
       
  1379 		 * Filter post data array to be inserted via XML-RPC.
       
  1380 		 *
       
  1381 		 * @since 3.4.0
       
  1382 		 *
       
  1383 		 * @param array $post_data      Parsed array of post data.
       
  1384 		 * @param array $content_struct Post data array.
       
  1385 		 */
  1217 		$post_data = apply_filters( 'xmlrpc_wp_insert_post_data', $post_data, $content_struct );
  1386 		$post_data = apply_filters( 'xmlrpc_wp_insert_post_data', $post_data, $content_struct );
  1218 
  1387 
  1219 		$post_ID = $update ? wp_update_post( $post_data, true ) : wp_insert_post( $post_data, true );
  1388 		$post_ID = $update ? wp_update_post( $post_data, true ) : wp_insert_post( $post_data, true );
  1220 		if ( is_wp_error( $post_ID ) )
  1389 		if ( is_wp_error( $post_ID ) )
  1221 			return new IXR_Error( 500, $post_ID->get_error_message() );
  1390 			return new IXR_Error( 500, $post_ID->get_error_message() );
  1233 	 * should be changed. All other fields will retain their existing values.
  1402 	 * should be changed. All other fields will retain their existing values.
  1234 	 *
  1403 	 *
  1235 	 * @since 3.4.0
  1404 	 * @since 3.4.0
  1236 	 *
  1405 	 *
  1237 	 * @param array $args Method parameters. Contains:
  1406 	 * @param array $args Method parameters. Contains:
  1238 	 *  - int     $blog_id
  1407 	 *  - int     $blog_id (unused)
  1239 	 *  - string  $username
  1408 	 *  - string  $username
  1240 	 *  - string  $password
  1409 	 *  - string  $password
  1241 	 *  - int     $post_id
  1410 	 *  - int     $post_id
  1242 	 *  - array   $content_struct
  1411 	 *  - array   $content_struct
  1243 	 * @return true on success
  1412 	 * @return bool|IXR_Error true on success
  1244 	 */
  1413 	 */
  1245 	function wp_editPost( $args ) {
  1414 	public function wp_editPost( $args ) {
  1246 		if ( ! $this->minimum_args( $args, 5 ) )
  1415 		if ( ! $this->minimum_args( $args, 5 ) )
  1247 			return $this->error;
  1416 			return $this->error;
  1248 
  1417 
  1249 		$this->escape( $args );
  1418 		$this->escape( $args );
  1250 
  1419 
  1251 		$blog_id        = (int) $args[0];
       
  1252 		$username       = $args[1];
  1420 		$username       = $args[1];
  1253 		$password       = $args[2];
  1421 		$password       = $args[2];
  1254 		$post_id        = (int) $args[3];
  1422 		$post_id        = (int) $args[3];
  1255 		$content_struct = $args[4];
  1423 		$content_struct = $args[4];
  1256 
  1424 
  1257 		if ( ! $user = $this->login( $username, $password ) )
  1425 		if ( ! $user = $this->login( $username, $password ) )
  1258 			return $this->error;
  1426 			return $this->error;
  1259 
  1427 
       
  1428 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  1260 		do_action( 'xmlrpc_call', 'wp.editPost' );
  1429 		do_action( 'xmlrpc_call', 'wp.editPost' );
  1261 
  1430 
  1262 		$post = get_post( $post_id, ARRAY_A );
  1431 		$post = get_post( $post_id, ARRAY_A );
  1263 
  1432 
  1264 		if ( empty( $post['ID'] ) )
  1433 		if ( empty( $post['ID'] ) )
  1296 	 *
  1465 	 *
  1297 	 * @since 3.4.0
  1466 	 * @since 3.4.0
  1298 	 *
  1467 	 *
  1299 	 * @uses wp_delete_post()
  1468 	 * @uses wp_delete_post()
  1300 	 * @param array $args Method parameters. Contains:
  1469 	 * @param array $args Method parameters. Contains:
  1301 	 *  - int     $blog_id
  1470 	 *  - int     $blog_id (unused)
  1302 	 *  - string  $username
  1471 	 *  - string  $username
  1303 	 *  - string  $password
  1472 	 *  - string  $password
  1304 	 *  - int     $post_id
  1473 	 *  - int     $post_id
  1305 	 * @return true on success
  1474 	 * @return bool|IXR_Error true on success
  1306 	 */
  1475 	 */
  1307 	function wp_deletePost( $args ) {
  1476 	public function wp_deletePost( $args ) {
  1308 		if ( ! $this->minimum_args( $args, 4 ) )
  1477 		if ( ! $this->minimum_args( $args, 4 ) )
  1309 			return $this->error;
  1478 			return $this->error;
  1310 
  1479 
  1311 		$this->escape( $args );
  1480 		$this->escape( $args );
  1312 
  1481 
  1313 		$blog_id    = (int) $args[0];
       
  1314 		$username   = $args[1];
  1482 		$username   = $args[1];
  1315 		$password   = $args[2];
  1483 		$password   = $args[2];
  1316 		$post_id    = (int) $args[3];
  1484 		$post_id    = (int) $args[3];
  1317 
  1485 
  1318 		if ( ! $user = $this->login( $username, $password ) )
  1486 		if ( ! $user = $this->login( $username, $password ) )
  1319 			return $this->error;
  1487 			return $this->error;
  1320 
  1488 
       
  1489 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  1321 		do_action( 'xmlrpc_call', 'wp.deletePost' );
  1490 		do_action( 'xmlrpc_call', 'wp.deletePost' );
  1322 
  1491 
  1323 		$post = get_post( $post_id, ARRAY_A );
  1492 		$post = get_post( $post_id, ARRAY_A );
  1324 		if ( empty( $post['ID'] ) )
  1493 		if ( empty( $post['ID'] ) )
  1325 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  1494 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  1349 	 * groups are 'post' (all basic fields), 'taxonomies', 'custom_fields',
  1518 	 * groups are 'post' (all basic fields), 'taxonomies', 'custom_fields',
  1350 	 * and 'enclosure'.
  1519 	 * and 'enclosure'.
  1351 	 *
  1520 	 *
  1352 	 * @uses get_post()
  1521 	 * @uses get_post()
  1353 	 * @param array $args Method parameters. Contains:
  1522 	 * @param array $args Method parameters. Contains:
  1354 	 *  - int     $post_id
  1523 	 *  - int     $blog_id (unused)
  1355 	 *  - string  $username
  1524 	 *  - string  $username
  1356 	 *  - string  $password
  1525 	 *  - string  $password
       
  1526 	 *  - int     $post_id
  1357 	 *  - array   $fields optional
  1527 	 *  - array   $fields optional
  1358 	 * @return array contains (based on $fields parameter):
  1528 	 * @return array|IXR_Error Array contains (based on $fields parameter):
  1359 	 *  - 'post_id'
  1529 	 *  - 'post_id'
  1360 	 *  - 'post_title'
  1530 	 *  - 'post_title'
  1361 	 *  - 'post_date'
  1531 	 *  - 'post_date'
  1362 	 *  - 'post_date_gmt'
  1532 	 *  - 'post_date_gmt'
  1363 	 *  - 'post_modified'
  1533 	 *  - 'post_modified'
  1377 	 *  - 'terms'
  1547 	 *  - 'terms'
  1378 	 *  - 'categories'
  1548 	 *  - 'categories'
  1379 	 *  - 'tags'
  1549 	 *  - 'tags'
  1380 	 *  - 'enclosure'
  1550 	 *  - 'enclosure'
  1381 	 */
  1551 	 */
  1382 	function wp_getPost( $args ) {
  1552 	public function wp_getPost( $args ) {
  1383 		if ( ! $this->minimum_args( $args, 4 ) )
  1553 		if ( ! $this->minimum_args( $args, 4 ) )
  1384 			return $this->error;
  1554 			return $this->error;
  1385 
  1555 
  1386 		$this->escape( $args );
  1556 		$this->escape( $args );
  1387 
  1557 
  1388 		$blog_id            = (int) $args[0];
       
  1389 		$username           = $args[1];
  1558 		$username           = $args[1];
  1390 		$password           = $args[2];
  1559 		$password           = $args[2];
  1391 		$post_id            = (int) $args[3];
  1560 		$post_id            = (int) $args[3];
  1392 
  1561 
  1393 		if ( isset( $args[4] ) )
  1562 		if ( isset( $args[4] ) ) {
  1394 			$fields = $args[4];
  1563 			$fields = $args[4];
  1395 		else
  1564 		} else {
       
  1565 			/**
       
  1566 			 * Filter the list of post query fields used by the given XML-RPC method.
       
  1567 			 *
       
  1568 			 * @since 3.4.0
       
  1569 			 *
       
  1570 			 * @param array $fields  Array of post fields.
       
  1571 			 * @param string $method Method name.
       
  1572 			 */
  1396 			$fields = apply_filters( 'xmlrpc_default_post_fields', array( 'post', 'terms', 'custom_fields' ), 'wp.getPost' );
  1573 			$fields = apply_filters( 'xmlrpc_default_post_fields', array( 'post', 'terms', 'custom_fields' ), 'wp.getPost' );
       
  1574 		}
  1397 
  1575 
  1398 		if ( ! $user = $this->login( $username, $password ) )
  1576 		if ( ! $user = $this->login( $username, $password ) )
  1399 			return $this->error;
  1577 			return $this->error;
  1400 
  1578 
       
  1579 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  1401 		do_action( 'xmlrpc_call', 'wp.getPost' );
  1580 		do_action( 'xmlrpc_call', 'wp.getPost' );
  1402 
  1581 
  1403 		$post = get_post( $post_id, ARRAY_A );
  1582 		$post = get_post( $post_id, ARRAY_A );
  1404 
  1583 
  1405 		if ( empty( $post['ID'] ) )
  1584 		if ( empty( $post['ID'] ) )
  1426 	 * @uses wp_get_recent_posts()
  1605 	 * @uses wp_get_recent_posts()
  1427 	 * @see wp_getPost() for more on $fields
  1606 	 * @see wp_getPost() for more on $fields
  1428 	 * @see get_posts() for more on $filter values
  1607 	 * @see get_posts() for more on $filter values
  1429 	 *
  1608 	 *
  1430 	 * @param array $args Method parameters. Contains:
  1609 	 * @param array $args Method parameters. Contains:
  1431 	 *  - int     $blog_id
  1610 	 *  - int     $blog_id (unused)
  1432 	 *  - string  $username
  1611 	 *  - string  $username
  1433 	 *  - string  $password
  1612 	 *  - string  $password
  1434 	 *  - array   $filter optional
  1613 	 *  - array   $filter optional
  1435 	 *  - array   $fields optional
  1614 	 *  - array   $fields optional
  1436 	 * @return array contains a collection of posts.
  1615 	 * @return array|IXR_Error Array contains a collection of posts.
  1437 	 */
  1616 	 */
  1438 	function wp_getPosts( $args ) {
  1617 	public function wp_getPosts( $args ) {
  1439 		if ( ! $this->minimum_args( $args, 3 ) )
  1618 		if ( ! $this->minimum_args( $args, 3 ) )
  1440 			return $this->error;
  1619 			return $this->error;
  1441 
  1620 
  1442 		$this->escape( $args );
  1621 		$this->escape( $args );
  1443 
  1622 
  1444 		$blog_id    = (int) $args[0];
       
  1445 		$username   = $args[1];
  1623 		$username   = $args[1];
  1446 		$password   = $args[2];
  1624 		$password   = $args[2];
  1447 		$filter     = isset( $args[3] ) ? $args[3] : array();
  1625 		$filter     = isset( $args[3] ) ? $args[3] : array();
  1448 
  1626 
  1449 		if ( isset( $args[4] ) )
  1627 		if ( isset( $args[4] ) ) {
  1450 			$fields = $args[4];
  1628 			$fields = $args[4];
  1451 		else
  1629 		} else {
       
  1630 			/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  1452 			$fields = apply_filters( 'xmlrpc_default_post_fields', array( 'post', 'terms', 'custom_fields' ), 'wp.getPosts' );
  1631 			$fields = apply_filters( 'xmlrpc_default_post_fields', array( 'post', 'terms', 'custom_fields' ), 'wp.getPosts' );
       
  1632 		}
  1453 
  1633 
  1454 		if ( ! $user = $this->login( $username, $password ) )
  1634 		if ( ! $user = $this->login( $username, $password ) )
  1455 			return $this->error;
  1635 			return $this->error;
  1456 
  1636 
       
  1637 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  1457 		do_action( 'xmlrpc_call', 'wp.getPosts' );
  1638 		do_action( 'xmlrpc_call', 'wp.getPosts' );
  1458 
  1639 
  1459 		$query = array();
  1640 		$query = array();
  1460 
  1641 
  1461 		if ( isset( $filter['post_type'] ) ) {
  1642 		if ( isset( $filter['post_type'] ) ) {
  1514 	 *
  1695 	 *
  1515 	 * @since 3.4.0
  1696 	 * @since 3.4.0
  1516 	 *
  1697 	 *
  1517 	 * @uses wp_insert_term()
  1698 	 * @uses wp_insert_term()
  1518 	 * @param array $args Method parameters. Contains:
  1699 	 * @param array $args Method parameters. Contains:
  1519 	 *  - int     $blog_id
  1700 	 *  - int     $blog_id (unused)
  1520 	 *  - string  $username
  1701 	 *  - string  $username
  1521 	 *  - string  $password
  1702 	 *  - string  $password
  1522 	 *  - array   $content_struct
  1703 	 *  - array   $content_struct
  1523 	 *      The $content_struct must contain:
  1704 	 *      The $content_struct must contain:
  1524 	 *      - 'name'
  1705 	 *      - 'name'
  1525 	 *      - 'taxonomy'
  1706 	 *      - 'taxonomy'
  1526 	 *      Also, it can optionally contain:
  1707 	 *      Also, it can optionally contain:
  1527 	 *      - 'parent'
  1708 	 *      - 'parent'
  1528 	 *      - 'description'
  1709 	 *      - 'description'
  1529 	 *      - 'slug'
  1710 	 *      - 'slug'
  1530 	 * @return string term_id
  1711 	 * @return string|IXR_Error term_id
  1531 	 */
  1712 	 */
  1532 	function wp_newTerm( $args ) {
  1713 	public function wp_newTerm( $args ) {
  1533 		if ( ! $this->minimum_args( $args, 4 ) )
  1714 		if ( ! $this->minimum_args( $args, 4 ) )
  1534 			return $this->error;
  1715 			return $this->error;
  1535 
  1716 
  1536 		$this->escape( $args );
  1717 		$this->escape( $args );
  1537 
  1718 
  1538 		$blog_id            = (int) $args[0];
       
  1539 		$username           = $args[1];
  1719 		$username           = $args[1];
  1540 		$password           = $args[2];
  1720 		$password           = $args[2];
  1541 		$content_struct     = $args[3];
  1721 		$content_struct     = $args[3];
  1542 
  1722 
  1543 		if ( ! $user = $this->login( $username, $password ) )
  1723 		if ( ! $user = $this->login( $username, $password ) )
  1544 			return $this->error;
  1724 			return $this->error;
  1545 
  1725 
       
  1726 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  1546 		do_action( 'xmlrpc_call', 'wp.newTerm' );
  1727 		do_action( 'xmlrpc_call', 'wp.newTerm' );
  1547 
  1728 
  1548 		if ( ! taxonomy_exists( $content_struct['taxonomy'] ) )
  1729 		if ( ! taxonomy_exists( $content_struct['taxonomy'] ) )
  1549 			return new IXR_Error( 403, __( 'Invalid taxonomy' ) );
  1730 			return new IXR_Error( 403, __( 'Invalid taxonomy' ) );
  1550 
  1731 
  1600 	 *
  1781 	 *
  1601 	 * @since 3.4.0
  1782 	 * @since 3.4.0
  1602 	 *
  1783 	 *
  1603 	 * @uses wp_update_term()
  1784 	 * @uses wp_update_term()
  1604 	 * @param array $args Method parameters. Contains:
  1785 	 * @param array $args Method parameters. Contains:
  1605 	 *  - int     $blog_id
  1786 	 *  - int     $blog_id (unused)
  1606 	 *  - string  $username
  1787 	 *  - string  $username
  1607 	 *  - string  $password
  1788 	 *  - string  $password
  1608 	 *  - string  $term_id
  1789 	 *  - string  $term_id
  1609 	 *  - array   $content_struct
  1790 	 *  - array   $content_struct
  1610 	 *      The $content_struct must contain:
  1791 	 *      The $content_struct must contain:
  1612 	 *      Also, it can optionally contain:
  1793 	 *      Also, it can optionally contain:
  1613 	 *      - 'name'
  1794 	 *      - 'name'
  1614 	 *      - 'parent'
  1795 	 *      - 'parent'
  1615 	 *      - 'description'
  1796 	 *      - 'description'
  1616 	 *      - 'slug'
  1797 	 *      - 'slug'
  1617 	 * @return bool True, on success.
  1798 	 * @return bool|IXR_Error True, on success.
  1618 	 */
  1799 	 */
  1619 	function wp_editTerm( $args ) {
  1800 	public function wp_editTerm( $args ) {
  1620 		if ( ! $this->minimum_args( $args, 5 ) )
  1801 		if ( ! $this->minimum_args( $args, 5 ) )
  1621 			return $this->error;
  1802 			return $this->error;
  1622 
  1803 
  1623 		$this->escape( $args );
  1804 		$this->escape( $args );
  1624 
  1805 
  1625 		$blog_id            = (int) $args[0];
       
  1626 		$username           = $args[1];
  1806 		$username           = $args[1];
  1627 		$password           = $args[2];
  1807 		$password           = $args[2];
  1628 		$term_id            = (int) $args[3];
  1808 		$term_id            = (int) $args[3];
  1629 		$content_struct     = $args[4];
  1809 		$content_struct     = $args[4];
  1630 
  1810 
  1631 		if ( ! $user = $this->login( $username, $password ) )
  1811 		if ( ! $user = $this->login( $username, $password ) )
  1632 			return $this->error;
  1812 			return $this->error;
  1633 
  1813 
       
  1814 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  1634 		do_action( 'xmlrpc_call', 'wp.editTerm' );
  1815 		do_action( 'xmlrpc_call', 'wp.editTerm' );
  1635 
  1816 
  1636 		if ( ! taxonomy_exists( $content_struct['taxonomy'] ) )
  1817 		if ( ! taxonomy_exists( $content_struct['taxonomy'] ) )
  1637 			return new IXR_Error( 403, __( 'Invalid taxonomy' ) );
  1818 			return new IXR_Error( 403, __( 'Invalid taxonomy' ) );
  1638 
  1819 
  1699 	 *
  1880 	 *
  1700 	 * @since 3.4.0
  1881 	 * @since 3.4.0
  1701 	 *
  1882 	 *
  1702 	 * @uses wp_delete_term()
  1883 	 * @uses wp_delete_term()
  1703 	 * @param array $args Method parameters. Contains:
  1884 	 * @param array $args Method parameters. Contains:
  1704 	 *  - int     $blog_id
  1885 	 *  - int     $blog_id (unused)
  1705 	 *  - string  $username
  1886 	 *  - string  $username
  1706 	 *  - string  $password
  1887 	 *  - string  $password
  1707 	 *  - string  $taxnomy_name
  1888 	 *  - string  $taxnomy_name
  1708 	 *  - string     $term_id
  1889 	 *  - string     $term_id
  1709 	 * @return boolean|IXR_Error If it suceeded true else a reason why not
  1890 	 * @return boolean|IXR_Error If it suceeded true else a reason why not
  1710 	 */
  1891 	 */
  1711 	function wp_deleteTerm( $args ) {
  1892 	public function wp_deleteTerm( $args ) {
  1712 		if ( ! $this->minimum_args( $args, 5 ) )
  1893 		if ( ! $this->minimum_args( $args, 5 ) )
  1713 			return $this->error;
  1894 			return $this->error;
  1714 
  1895 
  1715 		$this->escape( $args );
  1896 		$this->escape( $args );
  1716 
  1897 
  1717 		$blog_id            = (int) $args[0];
       
  1718 		$username           = $args[1];
  1898 		$username           = $args[1];
  1719 		$password           = $args[2];
  1899 		$password           = $args[2];
  1720 		$taxonomy           = $args[3];
  1900 		$taxonomy           = $args[3];
  1721 		$term_id            = (int) $args[4];
  1901 		$term_id            = (int) $args[4];
  1722 
  1902 
  1723 		if ( ! $user = $this->login( $username, $password ) )
  1903 		if ( ! $user = $this->login( $username, $password ) )
  1724 			return $this->error;
  1904 			return $this->error;
  1725 
  1905 
       
  1906 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  1726 		do_action( 'xmlrpc_call', 'wp.deleteTerm' );
  1907 		do_action( 'xmlrpc_call', 'wp.deleteTerm' );
  1727 
  1908 
  1728 		if ( ! taxonomy_exists( $taxonomy ) )
  1909 		if ( ! taxonomy_exists( $taxonomy ) )
  1729 			return new IXR_Error( 403, __( 'Invalid taxonomy' ) );
  1910 			return new IXR_Error( 403, __( 'Invalid taxonomy' ) );
  1730 
  1911 
  1757 	 *
  1938 	 *
  1758 	 * @since 3.4.0
  1939 	 * @since 3.4.0
  1759 	 *
  1940 	 *
  1760 	 * @uses get_term()
  1941 	 * @uses get_term()
  1761 	 * @param array $args Method parameters. Contains:
  1942 	 * @param array $args Method parameters. Contains:
  1762 	 *  - int     $blog_id
  1943 	 *  - int     $blog_id (unused)
  1763 	 *  - string  $username
  1944 	 *  - string  $username
  1764 	 *  - string  $password
  1945 	 *  - string  $password
  1765 	 *  - string  $taxonomy
  1946 	 *  - string  $taxonomy
  1766 	 *  - string  $term_id
  1947 	 *  - string  $term_id
  1767 	 * @return array contains:
  1948 	 * @return array|IXR_Error Array contains:
  1768 	 *  - 'term_id'
  1949 	 *  - 'term_id'
  1769 	 *  - 'name'
  1950 	 *  - 'name'
  1770 	 *  - 'slug'
  1951 	 *  - 'slug'
  1771 	 *  - 'term_group'
  1952 	 *  - 'term_group'
  1772 	 *  - 'term_taxonomy_id'
  1953 	 *  - 'term_taxonomy_id'
  1773 	 *  - 'taxonomy'
  1954 	 *  - 'taxonomy'
  1774 	 *  - 'description'
  1955 	 *  - 'description'
  1775 	 *  - 'parent'
  1956 	 *  - 'parent'
  1776 	 *  - 'count'
  1957 	 *  - 'count'
  1777 	 */
  1958 	 */
  1778 	function wp_getTerm( $args ) {
  1959 	public function wp_getTerm( $args ) {
  1779 		if ( ! $this->minimum_args( $args, 5 ) )
  1960 		if ( ! $this->minimum_args( $args, 5 ) )
  1780 			return $this->error;
  1961 			return $this->error;
  1781 
  1962 
  1782 		$this->escape( $args );
  1963 		$this->escape( $args );
  1783 
  1964 
  1784 		$blog_id            = (int) $args[0];
       
  1785 		$username           = $args[1];
  1965 		$username           = $args[1];
  1786 		$password           = $args[2];
  1966 		$password           = $args[2];
  1787 		$taxonomy           = $args[3];
  1967 		$taxonomy           = $args[3];
  1788 		$term_id            = (int) $args[4];
  1968 		$term_id            = (int) $args[4];
  1789 
  1969 
  1790 		if ( ! $user = $this->login( $username, $password ) )
  1970 		if ( ! $user = $this->login( $username, $password ) )
  1791 			return $this->error;
  1971 			return $this->error;
  1792 
  1972 
       
  1973 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  1793 		do_action( 'xmlrpc_call', 'wp.getTerm' );
  1974 		do_action( 'xmlrpc_call', 'wp.getTerm' );
  1794 
  1975 
  1795 		if ( ! taxonomy_exists( $taxonomy ) )
  1976 		if ( ! taxonomy_exists( $taxonomy ) )
  1796 			return new IXR_Error( 403, __( 'Invalid taxonomy' ) );
  1977 			return new IXR_Error( 403, __( 'Invalid taxonomy' ) );
  1797 
  1978 
  1819 	 * The optional $filter parameter modifies the query used to retrieve terms.
  2000 	 * The optional $filter parameter modifies the query used to retrieve terms.
  1820 	 * Accepted keys are 'number', 'offset', 'orderby', 'order', 'hide_empty', and 'search'.
  2001 	 * Accepted keys are 'number', 'offset', 'orderby', 'order', 'hide_empty', and 'search'.
  1821 	 *
  2002 	 *
  1822 	 * @uses get_terms()
  2003 	 * @uses get_terms()
  1823 	 * @param array $args Method parameters. Contains:
  2004 	 * @param array $args Method parameters. Contains:
  1824 	 *  - int     $blog_id
  2005 	 *  - int     $blog_id (unused)
  1825 	 *  - string  $username
  2006 	 *  - string  $username
  1826 	 *  - string  $password
  2007 	 *  - string  $password
  1827 	 *  - string  $taxonomy
  2008 	 *  - string  $taxonomy
  1828 	 *  - array   $filter optional
  2009 	 *  - array   $filter optional
  1829 	 * @return array terms
  2010 	 * @return array|IXR_Error terms
  1830 	 */
  2011 	 */
  1831 	function wp_getTerms( $args ) {
  2012 	public function wp_getTerms( $args ) {
  1832 		if ( ! $this->minimum_args( $args, 4 ) )
  2013 		if ( ! $this->minimum_args( $args, 4 ) )
  1833 			return $this->error;
  2014 			return $this->error;
  1834 
  2015 
  1835 		$this->escape( $args );
  2016 		$this->escape( $args );
  1836 
  2017 
  1837 		$blog_id        = (int) $args[0];
       
  1838 		$username       = $args[1];
  2018 		$username       = $args[1];
  1839 		$password       = $args[2];
  2019 		$password       = $args[2];
  1840 		$taxonomy       = $args[3];
  2020 		$taxonomy       = $args[3];
  1841 		$filter         = isset( $args[4] ) ? $args[4] : array();
  2021 		$filter         = isset( $args[4] ) ? $args[4] : array();
  1842 
  2022 
  1843 		if ( ! $user = $this->login( $username, $password ) )
  2023 		if ( ! $user = $this->login( $username, $password ) )
  1844 			return $this->error;
  2024 			return $this->error;
  1845 
  2025 
       
  2026 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  1846 		do_action( 'xmlrpc_call', 'wp.getTerms' );
  2027 		do_action( 'xmlrpc_call', 'wp.getTerms' );
  1847 
  2028 
  1848 		if ( ! taxonomy_exists( $taxonomy ) )
  2029 		if ( ! taxonomy_exists( $taxonomy ) )
  1849 			return new IXR_Error( 403, __( 'Invalid taxonomy' ) );
  2030 			return new IXR_Error( 403, __( 'Invalid taxonomy' ) );
  1850 
  2031 
  1895 	 *
  2076 	 *
  1896 	 * @since 3.4.0
  2077 	 * @since 3.4.0
  1897 	 *
  2078 	 *
  1898 	 * @uses get_taxonomy()
  2079 	 * @uses get_taxonomy()
  1899 	 * @param array $args Method parameters. Contains:
  2080 	 * @param array $args Method parameters. Contains:
  1900 	 *  - int     $blog_id
  2081 	 *  - int     $blog_id (unused)
  1901 	 *  - string  $username
  2082 	 *  - string  $username
  1902 	 *  - string  $password
  2083 	 *  - string  $password
  1903 	 *  - string  $taxonomy
  2084 	 *  - string  $taxonomy
  1904 	 * @return array (@see get_taxonomy())
  2085 	 * @return array|IXR_Error (@see get_taxonomy())
  1905 	 */
  2086 	 */
  1906 	function wp_getTaxonomy( $args ) {
  2087 	public function wp_getTaxonomy( $args ) {
  1907 		if ( ! $this->minimum_args( $args, 4 ) )
  2088 		if ( ! $this->minimum_args( $args, 4 ) )
  1908 			return $this->error;
  2089 			return $this->error;
  1909 
  2090 
  1910 		$this->escape( $args );
  2091 		$this->escape( $args );
  1911 
  2092 
  1912 		$blog_id        = (int) $args[0];
       
  1913 		$username       = $args[1];
  2093 		$username       = $args[1];
  1914 		$password       = $args[2];
  2094 		$password       = $args[2];
  1915 		$taxonomy       = $args[3];
  2095 		$taxonomy       = $args[3];
  1916 
  2096 
  1917 		if ( isset( $args[4] ) )
  2097 		if ( isset( $args[4] ) ) {
  1918 			$fields = $args[4];
  2098 			$fields = $args[4];
  1919 		else
  2099 		} else {
       
  2100 			/**
       
  2101 			 * Filter the taxonomy query fields used by the given XML-RPC method.
       
  2102 			 *
       
  2103 			 * @since 3.4.0
       
  2104 			 *
       
  2105 			 * @param array  $fields An array of taxonomy fields to retrieve.
       
  2106 			 * @param string $method The method name.
       
  2107 			 */
  1920 			$fields = apply_filters( 'xmlrpc_default_taxonomy_fields', array( 'labels', 'cap', 'object_type' ), 'wp.getTaxonomy' );
  2108 			$fields = apply_filters( 'xmlrpc_default_taxonomy_fields', array( 'labels', 'cap', 'object_type' ), 'wp.getTaxonomy' );
       
  2109 		}
  1921 
  2110 
  1922 		if ( ! $user = $this->login( $username, $password ) )
  2111 		if ( ! $user = $this->login( $username, $password ) )
  1923 			return $this->error;
  2112 			return $this->error;
  1924 
  2113 
       
  2114 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  1925 		do_action( 'xmlrpc_call', 'wp.getTaxonomy' );
  2115 		do_action( 'xmlrpc_call', 'wp.getTaxonomy' );
  1926 
  2116 
  1927 		if ( ! taxonomy_exists( $taxonomy ) )
  2117 		if ( ! taxonomy_exists( $taxonomy ) )
  1928 			return new IXR_Error( 403, __( 'Invalid taxonomy' ) );
  2118 			return new IXR_Error( 403, __( 'Invalid taxonomy' ) );
  1929 
  2119 
  1940 	 *
  2130 	 *
  1941 	 * @since 3.4.0
  2131 	 * @since 3.4.0
  1942 	 *
  2132 	 *
  1943 	 * @uses get_taxonomies()
  2133 	 * @uses get_taxonomies()
  1944 	 * @param array $args Method parameters. Contains:
  2134 	 * @param array $args Method parameters. Contains:
  1945 	 *  - int     $blog_id
  2135 	 *  - int     $blog_id (unused)
  1946 	 *  - string  $username
  2136 	 *  - string  $username
  1947 	 *  - string  $password
  2137 	 *  - string  $password
  1948 	 * @return array taxonomies
  2138 	 * @return array taxonomies
  1949 	 */
  2139 	 */
  1950 	function wp_getTaxonomies( $args ) {
  2140 	public function wp_getTaxonomies( $args ) {
  1951 		if ( ! $this->minimum_args( $args, 3 ) )
  2141 		if ( ! $this->minimum_args( $args, 3 ) )
  1952 			return $this->error;
  2142 			return $this->error;
  1953 
  2143 
  1954 		$this->escape( $args );
  2144 		$this->escape( $args );
  1955 
  2145 
  1956 		$blog_id            = (int) $args[0];
       
  1957 		$username           = $args[1];
  2146 		$username           = $args[1];
  1958 		$password           = $args[2];
  2147 		$password           = $args[2];
  1959 		$filter             = isset( $args[3] ) ? $args[3] : array( 'public' => true );
  2148 		$filter             = isset( $args[3] ) ? $args[3] : array( 'public' => true );
  1960 
  2149 
  1961 		if ( isset( $args[4] ) )
  2150 		if ( isset( $args[4] ) ) {
  1962 			$fields = $args[4];
  2151 			$fields = $args[4];
  1963 		else
  2152 		} else {
       
  2153 			/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  1964 			$fields = apply_filters( 'xmlrpc_default_taxonomy_fields', array( 'labels', 'cap', 'object_type' ), 'wp.getTaxonomies' );
  2154 			$fields = apply_filters( 'xmlrpc_default_taxonomy_fields', array( 'labels', 'cap', 'object_type' ), 'wp.getTaxonomies' );
       
  2155 		}
  1965 
  2156 
  1966 		if ( ! $user = $this->login( $username, $password ) )
  2157 		if ( ! $user = $this->login( $username, $password ) )
  1967 			return $this->error;
  2158 			return $this->error;
  1968 
  2159 
       
  2160 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  1969 		do_action( 'xmlrpc_call', 'wp.getTaxonomies' );
  2161 		do_action( 'xmlrpc_call', 'wp.getTaxonomies' );
  1970 
  2162 
  1971 		$taxonomies = get_taxonomies( $filter, 'objects' );
  2163 		$taxonomies = get_taxonomies( $filter, 'objects' );
  1972 
  2164 
  1973 		// holds all the taxonomy data
  2165 		// holds all the taxonomy data
  1995 	 * names can be used to specify multiple fields. The available conceptual
  2187 	 * names can be used to specify multiple fields. The available conceptual
  1996 	 * groups are 'basic' and 'all'.
  2188 	 * groups are 'basic' and 'all'.
  1997 	 *
  2189 	 *
  1998 	 * @uses get_userdata()
  2190 	 * @uses get_userdata()
  1999 	 * @param array $args Method parameters. Contains:
  2191 	 * @param array $args Method parameters. Contains:
  2000 	 *  - int     $blog_id
  2192 	 *  - int     $blog_id (unused)
  2001 	 *  - string  $username
  2193 	 *  - string  $username
  2002 	 *  - string  $password
  2194 	 *  - string  $password
  2003 	 *  - int     $user_id
  2195 	 *  - int     $user_id
  2004 	 *  - array   $fields optional
  2196 	 *  - array   $fields optional
  2005 	 * @return array contains (based on $fields parameter):
  2197 	 * @return array|IXR_Error Array contains (based on $fields parameter):
  2006 	 *  - 'user_id'
  2198 	 *  - 'user_id'
  2007 	 *  - 'username'
  2199 	 *  - 'username'
  2008 	 *  - 'first_name'
  2200 	 *  - 'first_name'
  2009 	 *  - 'last_name'
  2201 	 *  - 'last_name'
  2010 	 *  - 'registered'
  2202 	 *  - 'registered'
  2014 	 *  - 'nicename'
  2206 	 *  - 'nicename'
  2015 	 *  - 'url'
  2207 	 *  - 'url'
  2016 	 *  - 'display_name'
  2208 	 *  - 'display_name'
  2017 	 *  - 'roles'
  2209 	 *  - 'roles'
  2018 	 */
  2210 	 */
  2019 	function wp_getUser( $args ) {
  2211 	public function wp_getUser( $args ) {
  2020 		if ( ! $this->minimum_args( $args, 4 ) )
  2212 		if ( ! $this->minimum_args( $args, 4 ) )
  2021 			return $this->error;
  2213 			return $this->error;
  2022 
  2214 
  2023 		$this->escape( $args );
  2215 		$this->escape( $args );
  2024 
  2216 
  2025 		$blog_id    = (int) $args[0];
       
  2026 		$username   = $args[1];
  2217 		$username   = $args[1];
  2027 		$password   = $args[2];
  2218 		$password   = $args[2];
  2028 		$user_id    = (int) $args[3];
  2219 		$user_id    = (int) $args[3];
  2029 
  2220 
  2030 		if ( isset( $args[4] ) )
  2221 		if ( isset( $args[4] ) ) {
  2031 			$fields = $args[4];
  2222 			$fields = $args[4];
  2032 		else
  2223 		} else {
       
  2224 			/**
       
  2225 			 * Filter the default user query fields used by the given XML-RPC method.
       
  2226 			 *
       
  2227 			 * @since 3.5.0
       
  2228 			 *
       
  2229 			 * @param array  $fields User query fields for given method. Default 'all'.
       
  2230 			 * @param string $method The method name.
       
  2231 			 */
  2033 			$fields = apply_filters( 'xmlrpc_default_user_fields', array( 'all' ), 'wp.getUser' );
  2232 			$fields = apply_filters( 'xmlrpc_default_user_fields', array( 'all' ), 'wp.getUser' );
       
  2233 		}
  2034 
  2234 
  2035 		if ( ! $user = $this->login( $username, $password ) )
  2235 		if ( ! $user = $this->login( $username, $password ) )
  2036 			return $this->error;
  2236 			return $this->error;
  2037 
  2237 
       
  2238 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2038 		do_action( 'xmlrpc_call', 'wp.getUser' );
  2239 		do_action( 'xmlrpc_call', 'wp.getUser' );
  2039 
  2240 
  2040 		if ( ! current_user_can( 'edit_user', $user_id ) )
  2241 		if ( ! current_user_can( 'edit_user', $user_id ) )
  2041 			return new IXR_Error( 401, __( 'Sorry, you cannot edit users.' ) );
  2242 			return new IXR_Error( 401, __( 'Sorry, you cannot edit users.' ) );
  2042 
  2243 
  2060 	 *
  2261 	 *
  2061 	 * @uses get_users()
  2262 	 * @uses get_users()
  2062 	 * @see wp_getUser() for more on $fields and return values
  2263 	 * @see wp_getUser() for more on $fields and return values
  2063 	 *
  2264 	 *
  2064 	 * @param array $args Method parameters. Contains:
  2265 	 * @param array $args Method parameters. Contains:
  2065 	 *  - int     $blog_id
  2266 	 *  - int     $blog_id (unused)
  2066 	 *  - string  $username
  2267 	 *  - string  $username
  2067 	 *  - string  $password
  2268 	 *  - string  $password
  2068 	 *  - array   $filter optional
  2269 	 *  - array   $filter optional
  2069 	 *  - array   $fields optional
  2270 	 *  - array   $fields optional
  2070 	 * @return array users data
  2271 	 * @return array|IXR_Error users data
  2071 	 */
  2272 	 */
  2072 	function wp_getUsers( $args ) {
  2273 	public function wp_getUsers( $args ) {
  2073 		if ( ! $this->minimum_args( $args, 3 ) )
  2274 		if ( ! $this->minimum_args( $args, 3 ) )
  2074 			return $this->error;
  2275 			return $this->error;
  2075 
  2276 
  2076 		$this->escape( $args );
  2277 		$this->escape( $args );
  2077 
  2278 
  2078 		$blog_id    = (int) $args[0];
       
  2079 		$username   = $args[1];
  2279 		$username   = $args[1];
  2080 		$password   = $args[2];
  2280 		$password   = $args[2];
  2081 		$filter     = isset( $args[3] ) ? $args[3] : array();
  2281 		$filter     = isset( $args[3] ) ? $args[3] : array();
  2082 
  2282 
  2083 		if ( isset( $args[4] ) )
  2283 		if ( isset( $args[4] ) ) {
  2084 			$fields = $args[4];
  2284 			$fields = $args[4];
  2085 		else
  2285 		} else {
       
  2286 			/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2086 			$fields = apply_filters( 'xmlrpc_default_user_fields', array( 'all' ), 'wp.getUsers' );
  2287 			$fields = apply_filters( 'xmlrpc_default_user_fields', array( 'all' ), 'wp.getUsers' );
       
  2288 		}
  2087 
  2289 
  2088 		if ( ! $user = $this->login( $username, $password ) )
  2290 		if ( ! $user = $this->login( $username, $password ) )
  2089 			return $this->error;
  2291 			return $this->error;
  2090 
  2292 
       
  2293 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2091 		do_action( 'xmlrpc_call', 'wp.getUsers' );
  2294 		do_action( 'xmlrpc_call', 'wp.getUsers' );
  2092 
  2295 
  2093 		if ( ! current_user_can( 'list_users' ) )
  2296 		if ( ! current_user_can( 'list_users' ) )
  2094 			return new IXR_Error( 401, __( 'Sorry, you cannot list users.' ) );
  2297 			return new IXR_Error( 401, __( 'Sorry, you cannot list users.' ) );
  2095 
  2298 
  2129 	/**
  2332 	/**
  2130 	 * Retrieve information about the requesting user.
  2333 	 * Retrieve information about the requesting user.
  2131 	 *
  2334 	 *
  2132 	 * @uses get_userdata()
  2335 	 * @uses get_userdata()
  2133 	 * @param array $args Method parameters. Contains:
  2336 	 * @param array $args Method parameters. Contains:
  2134 	 *  - int     $blog_id
  2337 	 *  - int     $blog_id (unused)
  2135 	 *  - string  $username
  2338 	 *  - string  $username
  2136 	 *  - string  $password
  2339 	 *  - string  $password
  2137 	 *  - array   $fields optional
  2340 	 *  - array   $fields optional
  2138 	 * @return array (@see wp_getUser)
  2341 	 * @return array|IXR_Error (@see wp_getUser)
  2139 	 */
  2342 	 */
  2140 	function wp_getProfile( $args ) {
  2343 	public function wp_getProfile( $args ) {
  2141 		if ( ! $this->minimum_args( $args, 3 ) )
  2344 		if ( ! $this->minimum_args( $args, 3 ) )
  2142 			return $this->error;
  2345 			return $this->error;
  2143 
  2346 
  2144 		$this->escape( $args );
  2347 		$this->escape( $args );
  2145 
  2348 
  2146 		$blog_id    = (int) $args[0];
       
  2147 		$username   = $args[1];
  2349 		$username   = $args[1];
  2148 		$password   = $args[2];
  2350 		$password   = $args[2];
  2149 
  2351 
  2150 		if ( isset( $args[3] ) )
  2352 		if ( isset( $args[3] ) ) {
  2151 			$fields = $args[3];
  2353 			$fields = $args[3];
  2152 		else
  2354 		} else {
       
  2355 			/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2153 			$fields = apply_filters( 'xmlrpc_default_user_fields', array( 'all' ), 'wp.getProfile' );
  2356 			$fields = apply_filters( 'xmlrpc_default_user_fields', array( 'all' ), 'wp.getProfile' );
       
  2357 		}
  2154 
  2358 
  2155 		if ( ! $user = $this->login( $username, $password ) )
  2359 		if ( ! $user = $this->login( $username, $password ) )
  2156 			return $this->error;
  2360 			return $this->error;
  2157 
  2361 
       
  2362 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2158 		do_action( 'xmlrpc_call', 'wp.getProfile' );
  2363 		do_action( 'xmlrpc_call', 'wp.getProfile' );
  2159 
  2364 
  2160 		if ( ! current_user_can( 'edit_user', $user->ID ) )
  2365 		if ( ! current_user_can( 'edit_user', $user->ID ) )
  2161 			return new IXR_Error( 401, __( 'Sorry, you cannot edit your profile.' ) );
  2366 			return new IXR_Error( 401, __( 'Sorry, you cannot edit your profile.' ) );
  2162 
  2367 
  2168 	/**
  2373 	/**
  2169 	 * Edit user's profile.
  2374 	 * Edit user's profile.
  2170 	 *
  2375 	 *
  2171 	 * @uses wp_update_user()
  2376 	 * @uses wp_update_user()
  2172 	 * @param array $args Method parameters. Contains:
  2377 	 * @param array $args Method parameters. Contains:
  2173 	 *  - int     $blog_id
  2378 	 *  - int     $blog_id (unused)
  2174 	 *  - string  $username
  2379 	 *  - string  $username
  2175 	 *  - string  $password
  2380 	 *  - string  $password
  2176 	 *  - array   $content_struct
  2381 	 *  - array   $content_struct
  2177 	 *      It can optionally contain:
  2382 	 *      It can optionally contain:
  2178 	 *      - 'first_name'
  2383 	 *      - 'first_name'
  2180 	 *      - 'website'
  2385 	 *      - 'website'
  2181 	 *      - 'display_name'
  2386 	 *      - 'display_name'
  2182 	 *      - 'nickname'
  2387 	 *      - 'nickname'
  2183 	 *      - 'nicename'
  2388 	 *      - 'nicename'
  2184 	 *      - 'bio'
  2389 	 *      - 'bio'
  2185 	 * @return bool True, on success.
  2390 	 * @return bool|IXR_Error True, on success.
  2186 	 */
  2391 	 */
  2187 	function wp_editProfile( $args ) {
  2392 	public function wp_editProfile( $args ) {
  2188 		if ( ! $this->minimum_args( $args, 4 ) )
  2393 		if ( ! $this->minimum_args( $args, 4 ) )
  2189 			return $this->error;
  2394 			return $this->error;
  2190 
  2395 
  2191 		$this->escape( $args );
  2396 		$this->escape( $args );
  2192 
  2397 
  2193 		$blog_id        = (int) $args[0];
       
  2194 		$username       = $args[1];
  2398 		$username       = $args[1];
  2195 		$password       = $args[2];
  2399 		$password       = $args[2];
  2196 		$content_struct = $args[3];
  2400 		$content_struct = $args[3];
  2197 
  2401 
  2198 		if ( ! $user = $this->login( $username, $password ) )
  2402 		if ( ! $user = $this->login( $username, $password ) )
  2199 			return $this->error;
  2403 			return $this->error;
  2200 
  2404 
       
  2405 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2201 		do_action( 'xmlrpc_call', 'wp.editProfile' );
  2406 		do_action( 'xmlrpc_call', 'wp.editProfile' );
  2202 
  2407 
  2203 		if ( ! current_user_can( 'edit_user', $user->ID ) )
  2408 		if ( ! current_user_can( 'edit_user', $user->ID ) )
  2204 			return new IXR_Error( 401, __( 'Sorry, you cannot edit your profile.' ) );
  2409 			return new IXR_Error( 401, __( 'Sorry, you cannot edit your profile.' ) );
  2205 
  2410 
  2244 	 * Retrieve page.
  2449 	 * Retrieve page.
  2245 	 *
  2450 	 *
  2246 	 * @since 2.2.0
  2451 	 * @since 2.2.0
  2247 	 *
  2452 	 *
  2248 	 * @param array $args Method parameters. Contains:
  2453 	 * @param array $args Method parameters. Contains:
  2249 	 *  - blog_id
  2454 	 *  - blog_id (unused)
  2250 	 *  - page_id
  2455 	 *  - page_id
  2251 	 *  - username
  2456 	 *  - username
  2252 	 *  - password
  2457 	 *  - password
  2253 	 * @return array
  2458 	 * @return array|IXR_Error
  2254 	 */
  2459 	 */
  2255 	function wp_getPage($args) {
  2460 	public function wp_getPage($args) {
  2256 		$this->escape($args);
  2461 		$this->escape($args);
  2257 
  2462 
  2258 		$blog_id	= (int) $args[0];
       
  2259 		$page_id	= (int) $args[1];
  2463 		$page_id	= (int) $args[1];
  2260 		$username	= $args[2];
  2464 		$username	= $args[2];
  2261 		$password	= $args[3];
  2465 		$password	= $args[3];
  2262 
  2466 
  2263 		if ( !$user = $this->login($username, $password) ) {
  2467 		if ( !$user = $this->login($username, $password) ) {
  2269 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  2473 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  2270 
  2474 
  2271 		if ( !current_user_can( 'edit_page', $page_id ) )
  2475 		if ( !current_user_can( 'edit_page', $page_id ) )
  2272 			return new IXR_Error( 401, __( 'Sorry, you cannot edit this page.' ) );
  2476 			return new IXR_Error( 401, __( 'Sorry, you cannot edit this page.' ) );
  2273 
  2477 
  2274 		do_action('xmlrpc_call', 'wp.getPage');
  2478 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  2479 		do_action( 'xmlrpc_call', 'wp.getPage' );
  2275 
  2480 
  2276 		// If we found the page then format the data.
  2481 		// If we found the page then format the data.
  2277 		if ( $page->ID && ($page->post_type == 'page') ) {
  2482 		if ( $page->ID && ($page->post_type == 'page') ) {
  2278 			return $this->_prepare_page( $page );
  2483 			return $this->_prepare_page( $page );
  2279 		}
  2484 		}
  2280 		// If the page doesn't exist indicate that.
  2485 		// If the page doesn't exist indicate that.
  2281 		else {
  2486 		else {
  2282 			return(new IXR_Error(404, __('Sorry, no such page.')));
  2487 			return new IXR_Error( 404, __( 'Sorry, no such page.' ) );
  2283 		}
  2488 		}
  2284 	}
  2489 	}
  2285 
  2490 
  2286 	/**
  2491 	/**
  2287 	 * Retrieve Pages.
  2492 	 * Retrieve Pages.
  2288 	 *
  2493 	 *
  2289 	 * @since 2.2.0
  2494 	 * @since 2.2.0
  2290 	 *
  2495 	 *
  2291 	 * @param array $args Method parameters. Contains:
  2496 	 * @param array $args Method parameters. Contains:
  2292 	 *  - blog_id
  2497 	 *  - blog_id (unused)
  2293 	 *  - username
  2498 	 *  - username
  2294 	 *  - password
  2499 	 *  - password
  2295 	 *  - num_pages
  2500 	 *  - num_pages
  2296 	 * @return array
  2501 	 * @return array|IXR_Error
  2297 	 */
  2502 	 */
  2298 	function wp_getPages($args) {
  2503 	public function wp_getPages($args) {
  2299 		$this->escape($args);
  2504 		$this->escape($args);
  2300 
  2505 
  2301 		$blog_id	= (int) $args[0];
       
  2302 		$username	= $args[1];
  2506 		$username	= $args[1];
  2303 		$password	= $args[2];
  2507 		$password	= $args[2];
  2304 		$num_pages	= isset($args[3]) ? (int) $args[3] : 10;
  2508 		$num_pages	= isset($args[3]) ? (int) $args[3] : 10;
  2305 
  2509 
  2306 		if ( !$user = $this->login($username, $password) )
  2510 		if ( !$user = $this->login($username, $password) )
  2307 			return $this->error;
  2511 			return $this->error;
  2308 
  2512 
  2309 		if ( !current_user_can( 'edit_pages' ) )
  2513 		if ( !current_user_can( 'edit_pages' ) )
  2310 			return new IXR_Error( 401, __( 'Sorry, you cannot edit pages.' ) );
  2514 			return new IXR_Error( 401, __( 'Sorry, you cannot edit pages.' ) );
  2311 
  2515 
  2312 		do_action('xmlrpc_call', 'wp.getPages');
  2516 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  2517 		do_action( 'xmlrpc_call', 'wp.getPages' );
  2313 
  2518 
  2314 		$pages = get_posts( array('post_type' => 'page', 'post_status' => 'any', 'numberposts' => $num_pages) );
  2519 		$pages = get_posts( array('post_type' => 'page', 'post_status' => 'any', 'numberposts' => $num_pages) );
  2315 		$num_pages = count($pages);
  2520 		$num_pages = count($pages);
  2316 
  2521 
  2317 		// If we have pages, put together their info.
  2522 		// If we have pages, put together their info.
  2321 			foreach ($pages as $page) {
  2526 			foreach ($pages as $page) {
  2322 				if ( current_user_can( 'edit_page', $page->ID ) )
  2527 				if ( current_user_can( 'edit_page', $page->ID ) )
  2323 					$pages_struct[] = $this->_prepare_page( $page );
  2528 					$pages_struct[] = $this->_prepare_page( $page );
  2324 			}
  2529 			}
  2325 
  2530 
  2326 			return($pages_struct);
  2531 			return $pages_struct;
  2327 		}
  2532 		}
  2328 		// If no pages were found return an error.
  2533 
  2329 		else {
  2534 		return array();
  2330 			return(array());
       
  2331 		}
       
  2332 	}
  2535 	}
  2333 
  2536 
  2334 	/**
  2537 	/**
  2335 	 * Create new page.
  2538 	 * Create new page.
  2336 	 *
  2539 	 *
  2337 	 * @since 2.2.0
  2540 	 * @since 2.2.0
  2338 	 *
  2541 	 *
  2339 	 * @param array $args Method parameters. See {@link wp_xmlrpc_server::mw_newPost()}
  2542 	 * @param array $args Method parameters. See {@link wp_xmlrpc_server::mw_newPost()}
  2340 	 * @return unknown
  2543 	 * @return int|IXR_Error
  2341 	 */
  2544 	 */
  2342 	function wp_newPage($args) {
  2545 	public function wp_newPage($args) {
  2343 		// Items not escaped here will be escaped in newPost.
  2546 		// Items not escaped here will be escaped in newPost.
  2344 		$username	= $this->escape($args[1]);
  2547 		$username	= $this->escape($args[1]);
  2345 		$password	= $this->escape($args[2]);
  2548 		$password	= $this->escape($args[2]);
  2346 		$page		= $args[3];
       
  2347 		$publish	= $args[4];
       
  2348 
  2549 
  2349 		if ( !$user = $this->login($username, $password) )
  2550 		if ( !$user = $this->login($username, $password) )
  2350 			return $this->error;
  2551 			return $this->error;
  2351 
  2552 
  2352 		do_action('xmlrpc_call', 'wp.newPage');
  2553 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  2554 		do_action( 'xmlrpc_call', 'wp.newPage' );
  2353 
  2555 
  2354 		// Mark this as content for a page.
  2556 		// Mark this as content for a page.
  2355 		$args[3]["post_type"] = 'page';
  2557 		$args[3]["post_type"] = 'page';
  2356 
  2558 
  2357 		// Let mw_newPost do all of the heavy lifting.
  2559 		// Let mw_newPost do all of the heavy lifting.
  2358 		return($this->mw_newPost($args));
  2560 		return $this->mw_newPost( $args );
  2359 	}
  2561 	}
  2360 
  2562 
  2361 	/**
  2563 	/**
  2362 	 * Delete page.
  2564 	 * Delete page.
  2363 	 *
  2565 	 *
  2364 	 * @since 2.2.0
  2566 	 * @since 2.2.0
  2365 	 *
  2567 	 *
  2366 	 * @param array $args Method parameters.
  2568 	 * @param array $args Method parameters.
  2367 	 * @return bool True, if success.
  2569 	 * @return bool|IXR_Error True, if success.
  2368 	 */
  2570 	 */
  2369 	function wp_deletePage($args) {
  2571 	public function wp_deletePage($args) {
  2370 		$this->escape($args);
  2572 		$this->escape($args);
  2371 
  2573 
  2372 		$blog_id	= (int) $args[0];
       
  2373 		$username	= $args[1];
  2574 		$username	= $args[1];
  2374 		$password	= $args[2];
  2575 		$password	= $args[2];
  2375 		$page_id	= (int) $args[3];
  2576 		$page_id	= (int) $args[3];
  2376 
  2577 
  2377 		if ( !$user = $this->login($username, $password) )
  2578 		if ( !$user = $this->login($username, $password) )
  2378 			return $this->error;
  2579 			return $this->error;
  2379 
  2580 
  2380 		do_action('xmlrpc_call', 'wp.deletePage');
  2581 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  2582 		do_action( 'xmlrpc_call', 'wp.deletePage' );
  2381 
  2583 
  2382 		// Get the current page based on the page_id and
  2584 		// Get the current page based on the page_id and
  2383 		// make sure it is a page and not a post.
  2585 		// make sure it is a page and not a post.
  2384 		$actual_page = get_post($page_id, ARRAY_A);
  2586 		$actual_page = get_post($page_id, ARRAY_A);
  2385 		if ( !$actual_page || ($actual_page['post_type'] != 'page') )
  2587 		if ( !$actual_page || ($actual_page['post_type'] != 'page') )
  2386 			return(new IXR_Error(404, __('Sorry, no such page.')));
  2588 			return new IXR_Error( 404, __( 'Sorry, no such page.' ) );
  2387 
  2589 
  2388 		// Make sure the user can delete pages.
  2590 		// Make sure the user can delete pages.
  2389 		if ( !current_user_can('delete_page', $page_id) )
  2591 		if ( !current_user_can('delete_page', $page_id) )
  2390 			return(new IXR_Error(401, __('Sorry, you do not have the right to delete this page.')));
  2592 			return new IXR_Error( 401, __( 'Sorry, you do not have the right to delete this page.' ) );
  2391 
  2593 
  2392 		// Attempt to delete the page.
  2594 		// Attempt to delete the page.
  2393 		$result = wp_delete_post($page_id);
  2595 		$result = wp_delete_post($page_id);
  2394 		if ( !$result )
  2596 		if ( !$result )
  2395 			return(new IXR_Error(500, __('Failed to delete the page.')));
  2597 			return new IXR_Error( 500, __( 'Failed to delete the page.' ) );
  2396 
  2598 
       
  2599 		/**
       
  2600 		 * Fires after a page has been successfully deleted via XML-RPC.
       
  2601 		 *
       
  2602 		 * @since 3.4.0
       
  2603 		 *
       
  2604 		 * @param int   $page_id ID of the deleted page.
       
  2605 		 * @param array $args    An array of arguments to delete the page.
       
  2606 		 */
  2397 		do_action( 'xmlrpc_call_success_wp_deletePage', $page_id, $args );
  2607 		do_action( 'xmlrpc_call_success_wp_deletePage', $page_id, $args );
  2398 
  2608 
  2399 		return(true);
  2609 		return true;
  2400 	}
  2610 	}
  2401 
  2611 
  2402 	/**
  2612 	/**
  2403 	 * Edit page.
  2613 	 * Edit page.
  2404 	 *
  2614 	 *
  2405 	 * @since 2.2.0
  2615 	 * @since 2.2.0
  2406 	 *
  2616 	 *
  2407 	 * @param array $args Method parameters.
  2617 	 * @param array $args Method parameters.
  2408 	 * @return unknown
  2618 	 * @return array|IXR_Error
  2409 	 */
  2619 	 */
  2410 	function wp_editPage($args) {
  2620 	public function wp_editPage($args) {
  2411 		// Items not escaped here will be escaped in editPost.
  2621 		// Items not escaped here will be escaped in editPost.
  2412 		$blog_id	= (int) $args[0];
       
  2413 		$page_id	= (int) $this->escape($args[1]);
  2622 		$page_id	= (int) $this->escape($args[1]);
  2414 		$username	= $this->escape($args[2]);
  2623 		$username	= $this->escape($args[2]);
  2415 		$password	= $this->escape($args[3]);
  2624 		$password	= $this->escape($args[3]);
  2416 		$content	= $args[4];
  2625 		$content	= $args[4];
  2417 		$publish	= $args[5];
  2626 		$publish	= $args[5];
  2418 
  2627 
  2419 		if ( !$user = $this->login($username, $password) )
  2628 		if ( !$user = $this->login($username, $password) )
  2420 			return $this->error;
  2629 			return $this->error;
  2421 
  2630 
  2422 		do_action('xmlrpc_call', 'wp.editPage');
  2631 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  2632 		do_action( 'xmlrpc_call', 'wp.editPage' );
  2423 
  2633 
  2424 		// Get the page data and make sure it is a page.
  2634 		// Get the page data and make sure it is a page.
  2425 		$actual_page = get_post($page_id, ARRAY_A);
  2635 		$actual_page = get_post($page_id, ARRAY_A);
  2426 		if ( !$actual_page || ($actual_page['post_type'] != 'page') )
  2636 		if ( !$actual_page || ($actual_page['post_type'] != 'page') )
  2427 			return(new IXR_Error(404, __('Sorry, no such page.')));
  2637 			return new IXR_Error( 404, __( 'Sorry, no such page.' ) );
  2428 
  2638 
  2429 		// Make sure the user is allowed to edit pages.
  2639 		// Make sure the user is allowed to edit pages.
  2430 		if ( !current_user_can('edit_page', $page_id) )
  2640 		if ( !current_user_can('edit_page', $page_id) )
  2431 			return(new IXR_Error(401, __('Sorry, you do not have the right to edit this page.')));
  2641 			return new IXR_Error( 401, __( 'Sorry, you do not have the right to edit this page.' ) );
  2432 
  2642 
  2433 		// Mark this as content for a page.
  2643 		// Mark this as content for a page.
  2434 		$content['post_type'] = 'page';
  2644 		$content['post_type'] = 'page';
  2435 
  2645 
  2436 		// Arrange args in the way mw_editPost understands.
  2646 		// Arrange args in the way mw_editPost understands.
  2441 			$content,
  2651 			$content,
  2442 			$publish
  2652 			$publish
  2443 		);
  2653 		);
  2444 
  2654 
  2445 		// Let mw_editPost do all of the heavy lifting.
  2655 		// Let mw_editPost do all of the heavy lifting.
  2446 		return($this->mw_editPost($args));
  2656 		return $this->mw_editPost( $args );
  2447 	}
  2657 	}
  2448 
  2658 
  2449 	/**
  2659 	/**
  2450 	 * Retrieve page list.
  2660 	 * Retrieve page list.
  2451 	 *
  2661 	 *
  2452 	 * @since 2.2.0
  2662 	 * @since 2.2.0
  2453 	 *
  2663 	 *
  2454 	 * @param array $args Method parameters.
  2664 	 * @param array $args Method parameters.
  2455 	 * @return unknown
  2665 	 * @return array|IXR_Error
  2456 	 */
  2666 	 */
  2457 	function wp_getPageList($args) {
  2667 	public function wp_getPageList($args) {
  2458 		global $wpdb;
  2668 		global $wpdb;
  2459 
  2669 
  2460 		$this->escape($args);
  2670 		$this->escape($args);
  2461 
  2671 
  2462 		$blog_id				= (int) $args[0];
       
  2463 		$username				= $args[1];
  2672 		$username				= $args[1];
  2464 		$password				= $args[2];
  2673 		$password				= $args[2];
  2465 
  2674 
  2466 		if ( !$user = $this->login($username, $password) )
  2675 		if ( !$user = $this->login($username, $password) )
  2467 			return $this->error;
  2676 			return $this->error;
  2468 
  2677 
  2469 		if ( !current_user_can( 'edit_pages' ) )
  2678 		if ( !current_user_can( 'edit_pages' ) )
  2470 			return new IXR_Error( 401, __( 'Sorry, you cannot edit pages.' ) );
  2679 			return new IXR_Error( 401, __( 'Sorry, you cannot edit pages.' ) );
  2471 
  2680 
  2472 		do_action('xmlrpc_call', 'wp.getPageList');
  2681 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  2682 		do_action( 'xmlrpc_call', 'wp.getPageList' );
  2473 
  2683 
  2474 		// Get list of pages ids and titles
  2684 		// Get list of pages ids and titles
  2475 		$page_list = $wpdb->get_results("
  2685 		$page_list = $wpdb->get_results("
  2476 			SELECT ID page_id,
  2686 			SELECT ID page_id,
  2477 				post_title page_title,
  2687 				post_title page_title,
  2493 			unset($page_list[$i]->post_date_gmt);
  2703 			unset($page_list[$i]->post_date_gmt);
  2494 			unset($page_list[$i]->post_date);
  2704 			unset($page_list[$i]->post_date);
  2495 			unset($page_list[$i]->post_status);
  2705 			unset($page_list[$i]->post_status);
  2496 		}
  2706 		}
  2497 
  2707 
  2498 		return($page_list);
  2708 		return $page_list;
  2499 	}
  2709 	}
  2500 
  2710 
  2501 	/**
  2711 	/**
  2502 	 * Retrieve authors list.
  2712 	 * Retrieve authors list.
  2503 	 *
  2713 	 *
  2504 	 * @since 2.2.0
  2714 	 * @since 2.2.0
  2505 	 *
  2715 	 *
  2506 	 * @param array $args Method parameters.
  2716 	 * @param array $args Method parameters.
  2507 	 * @return array
  2717 	 * @return array|IXR_Error
  2508 	 */
  2718 	 */
  2509 	function wp_getAuthors($args) {
  2719 	public function wp_getAuthors($args) {
  2510 
  2720 
  2511 		$this->escape($args);
  2721 		$this->escape($args);
  2512 
  2722 
  2513 		$blog_id	= (int) $args[0];
       
  2514 		$username	= $args[1];
  2723 		$username	= $args[1];
  2515 		$password	= $args[2];
  2724 		$password	= $args[2];
  2516 
  2725 
  2517 		if ( !$user = $this->login($username, $password) )
  2726 		if ( !$user = $this->login($username, $password) )
  2518 			return $this->error;
  2727 			return $this->error;
  2519 
  2728 
  2520 		if ( !current_user_can('edit_posts') )
  2729 		if ( !current_user_can('edit_posts') )
  2521 			return(new IXR_Error(401, __('Sorry, you cannot edit posts on this site.')));
  2730 			return new IXR_Error( 401, __( 'Sorry, you cannot edit posts on this site.' ) );
  2522 
  2731 
  2523 		do_action('xmlrpc_call', 'wp.getAuthors');
  2732 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  2733 		do_action( 'xmlrpc_call', 'wp.getAuthors' );
  2524 
  2734 
  2525 		$authors = array();
  2735 		$authors = array();
  2526 		foreach ( get_users( array( 'fields' => array('ID','user_login','display_name') ) ) as $user ) {
  2736 		foreach ( get_users( array( 'fields' => array('ID','user_login','display_name') ) ) as $user ) {
  2527 			$authors[] = array(
  2737 			$authors[] = array(
  2528 				'user_id'       => $user->ID,
  2738 				'user_id'       => $user->ID,
  2538 	 * Get list of all tags
  2748 	 * Get list of all tags
  2539 	 *
  2749 	 *
  2540 	 * @since 2.7.0
  2750 	 * @since 2.7.0
  2541 	 *
  2751 	 *
  2542 	 * @param array $args Method parameters.
  2752 	 * @param array $args Method parameters.
  2543 	 * @return array
  2753 	 * @return array|IXR_Error
  2544 	 */
  2754 	 */
  2545 	function wp_getTags( $args ) {
  2755 	public function wp_getTags( $args ) {
  2546 		$this->escape( $args );
  2756 		$this->escape( $args );
  2547 
  2757 
  2548 		$blog_id		= (int) $args[0];
       
  2549 		$username		= $args[1];
  2758 		$username		= $args[1];
  2550 		$password		= $args[2];
  2759 		$password		= $args[2];
  2551 
  2760 
  2552 		if ( !$user = $this->login($username, $password) )
  2761 		if ( !$user = $this->login($username, $password) )
  2553 			return $this->error;
  2762 			return $this->error;
  2554 
  2763 
  2555 		if ( !current_user_can( 'edit_posts' ) )
  2764 		if ( !current_user_can( 'edit_posts' ) )
  2556 			return new IXR_Error( 401, __( 'Sorry, you must be able to edit posts on this site in order to view tags.' ) );
  2765 			return new IXR_Error( 401, __( 'Sorry, you must be able to edit posts on this site in order to view tags.' ) );
  2557 
  2766 
       
  2767 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2558 		do_action( 'xmlrpc_call', 'wp.getKeywords' );
  2768 		do_action( 'xmlrpc_call', 'wp.getKeywords' );
  2559 
  2769 
  2560 		$tags = array();
  2770 		$tags = array();
  2561 
  2771 
  2562 		if ( $all_tags = get_tags() ) {
  2772 		if ( $all_tags = get_tags() ) {
  2563 			foreach( (array) $all_tags as $tag ) {
  2773 			foreach( (array) $all_tags as $tag ) {
       
  2774 				$struct = array();
  2564 				$struct['tag_id']			= $tag->term_id;
  2775 				$struct['tag_id']			= $tag->term_id;
  2565 				$struct['name']				= $tag->name;
  2776 				$struct['name']				= $tag->name;
  2566 				$struct['count']			= $tag->count;
  2777 				$struct['count']			= $tag->count;
  2567 				$struct['slug']				= $tag->slug;
  2778 				$struct['slug']				= $tag->slug;
  2568 				$struct['html_url']			= esc_html( get_tag_link( $tag->term_id ) );
  2779 				$struct['html_url']			= esc_html( get_tag_link( $tag->term_id ) );
  2579 	 * Create new category.
  2790 	 * Create new category.
  2580 	 *
  2791 	 *
  2581 	 * @since 2.2.0
  2792 	 * @since 2.2.0
  2582 	 *
  2793 	 *
  2583 	 * @param array $args Method parameters.
  2794 	 * @param array $args Method parameters.
  2584 	 * @return int Category ID.
  2795 	 * @return int|IXR_Error Category ID.
  2585 	 */
  2796 	 */
  2586 	function wp_newCategory($args) {
  2797 	public function wp_newCategory($args) {
  2587 		$this->escape($args);
  2798 		$this->escape($args);
  2588 
  2799 
  2589 		$blog_id				= (int) $args[0];
       
  2590 		$username				= $args[1];
  2800 		$username				= $args[1];
  2591 		$password				= $args[2];
  2801 		$password				= $args[2];
  2592 		$category				= $args[3];
  2802 		$category				= $args[3];
  2593 
  2803 
  2594 		if ( !$user = $this->login($username, $password) )
  2804 		if ( !$user = $this->login($username, $password) )
  2595 			return $this->error;
  2805 			return $this->error;
  2596 
  2806 
  2597 		do_action('xmlrpc_call', 'wp.newCategory');
  2807 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  2808 		do_action( 'xmlrpc_call', 'wp.newCategory' );
  2598 
  2809 
  2599 		// Make sure the user is allowed to add a category.
  2810 		// Make sure the user is allowed to add a category.
  2600 		if ( !current_user_can('manage_categories') )
  2811 		if ( !current_user_can('manage_categories') )
  2601 			return(new IXR_Error(401, __('Sorry, you do not have the right to add a category.')));
  2812 			return new IXR_Error(401, __('Sorry, you do not have the right to add a category.'));
  2602 
  2813 
  2603 		// If no slug was provided make it empty so that
  2814 		// If no slug was provided make it empty so that
  2604 		// WordPress will generate one.
  2815 		// WordPress will generate one.
  2605 		if ( empty($category['slug']) )
  2816 		if ( empty($category['slug']) )
  2606 			$category['slug'] = '';
  2817 			$category['slug'] = '';
  2624 		$cat_id = wp_insert_category($new_category, true);
  2835 		$cat_id = wp_insert_category($new_category, true);
  2625 		if ( is_wp_error( $cat_id ) ) {
  2836 		if ( is_wp_error( $cat_id ) ) {
  2626 			if ( 'term_exists' == $cat_id->get_error_code() )
  2837 			if ( 'term_exists' == $cat_id->get_error_code() )
  2627 				return (int) $cat_id->get_error_data();
  2838 				return (int) $cat_id->get_error_data();
  2628 			else
  2839 			else
  2629 				return(new IXR_Error(500, __('Sorry, the new category failed.')));
  2840 				return new IXR_Error(500, __('Sorry, the new category failed.'));
  2630 		} elseif ( ! $cat_id ) {
  2841 		} elseif ( ! $cat_id ) {
  2631 			return(new IXR_Error(500, __('Sorry, the new category failed.')));
  2842 			return new IXR_Error(500, __('Sorry, the new category failed.'));
  2632 		}
  2843 		}
  2633 
  2844 
       
  2845 		/**
       
  2846 		 * Fires after a new category has been successfully created via XML-RPC.
       
  2847 		 *
       
  2848 		 * @since 3.4.0
       
  2849 		 *
       
  2850 		 * @param int   $cat_id ID of the new category.
       
  2851 		 * @param array $args   An array of new category arguments.
       
  2852 		 */
  2634 		do_action( 'xmlrpc_call_success_wp_newCategory', $cat_id, $args );
  2853 		do_action( 'xmlrpc_call_success_wp_newCategory', $cat_id, $args );
  2635 
  2854 
  2636 		return $cat_id;
  2855 		return $cat_id;
  2637 	}
  2856 	}
  2638 
  2857 
  2640 	 * Remove category.
  2859 	 * Remove category.
  2641 	 *
  2860 	 *
  2642 	 * @since 2.5.0
  2861 	 * @since 2.5.0
  2643 	 *
  2862 	 *
  2644 	 * @param array $args Method parameters.
  2863 	 * @param array $args Method parameters.
  2645 	 * @return mixed See {@link wp_delete_term()} for return info.
  2864 	 * @return bool|IXR_Error See {@link wp_delete_term()} for return info.
  2646 	 */
  2865 	 */
  2647 	function wp_deleteCategory($args) {
  2866 	public function wp_deleteCategory($args) {
  2648 		$this->escape($args);
  2867 		$this->escape($args);
  2649 
  2868 
  2650 		$blog_id		= (int) $args[0];
       
  2651 		$username		= $args[1];
  2869 		$username		= $args[1];
  2652 		$password		= $args[2];
  2870 		$password		= $args[2];
  2653 		$category_id	= (int) $args[3];
  2871 		$category_id	= (int) $args[3];
  2654 
  2872 
  2655 		if ( !$user = $this->login($username, $password) )
  2873 		if ( !$user = $this->login($username, $password) )
  2656 			return $this->error;
  2874 			return $this->error;
  2657 
  2875 
  2658 		do_action('xmlrpc_call', 'wp.deleteCategory');
  2876 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  2877 		do_action( 'xmlrpc_call', 'wp.deleteCategory' );
  2659 
  2878 
  2660 		if ( !current_user_can('manage_categories') )
  2879 		if ( !current_user_can('manage_categories') )
  2661 			return new IXR_Error( 401, __( 'Sorry, you do not have the right to delete a category.' ) );
  2880 			return new IXR_Error( 401, __( 'Sorry, you do not have the right to delete a category.' ) );
  2662 
  2881 
  2663 		$status = wp_delete_term( $category_id, 'category' );
  2882 		$status = wp_delete_term( $category_id, 'category' );
  2664 
  2883 
  2665 		if( true == $status )
  2884 		if ( true == $status ) {
       
  2885 			/**
       
  2886 			 * Fires after a category has been successfully deleted via XML-RPC.
       
  2887 			 *
       
  2888 			 * @since 3.4.0
       
  2889 			 *
       
  2890 			 * @param int   $category_id ID of the deleted category.
       
  2891 			 * @param array $args        An array of arguments to delete the category.
       
  2892 			 */
  2666 			do_action( 'xmlrpc_call_success_wp_deleteCategory', $category_id, $args );
  2893 			do_action( 'xmlrpc_call_success_wp_deleteCategory', $category_id, $args );
       
  2894 		}
  2667 
  2895 
  2668 		return $status;
  2896 		return $status;
  2669 	}
  2897 	}
  2670 
  2898 
  2671 	/**
  2899 	/**
  2672 	 * Retrieve category list.
  2900 	 * Retrieve category list.
  2673 	 *
  2901 	 *
  2674 	 * @since 2.2.0
  2902 	 * @since 2.2.0
  2675 	 *
  2903 	 *
  2676 	 * @param array $args Method parameters.
  2904 	 * @param array $args Method parameters.
  2677 	 * @return array
  2905 	 * @return array|IXR_Error
  2678 	 */
  2906 	 */
  2679 	function wp_suggestCategories($args) {
  2907 	public function wp_suggestCategories($args) {
  2680 		$this->escape($args);
  2908 		$this->escape($args);
  2681 
  2909 
  2682 		$blog_id				= (int) $args[0];
       
  2683 		$username				= $args[1];
  2910 		$username				= $args[1];
  2684 		$password				= $args[2];
  2911 		$password				= $args[2];
  2685 		$category				= $args[3];
  2912 		$category				= $args[3];
  2686 		$max_results			= (int) $args[4];
  2913 		$max_results			= (int) $args[4];
  2687 
  2914 
  2688 		if ( !$user = $this->login($username, $password) )
  2915 		if ( !$user = $this->login($username, $password) )
  2689 			return $this->error;
  2916 			return $this->error;
  2690 
  2917 
  2691 		if ( !current_user_can( 'edit_posts' ) )
  2918 		if ( !current_user_can( 'edit_posts' ) )
  2692 			return new IXR_Error( 401, __( 'Sorry, you must be able to edit posts to this site in order to view categories.' ) );
  2919 			return new IXR_Error( 401, __( 'Sorry, you must be able to edit posts on this site in order to view categories.' ) );
  2693 
  2920 
  2694 		do_action('xmlrpc_call', 'wp.suggestCategories');
  2921 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  2922 		do_action( 'xmlrpc_call', 'wp.suggestCategories' );
  2695 
  2923 
  2696 		$category_suggestions = array();
  2924 		$category_suggestions = array();
  2697 		$args = array('get' => 'all', 'number' => $max_results, 'name__like' => $category);
  2925 		$args = array('get' => 'all', 'number' => $max_results, 'name__like' => $category);
  2698 		foreach ( (array) get_categories($args) as $cat ) {
  2926 		foreach ( (array) get_categories($args) as $cat ) {
  2699 			$category_suggestions[] = array(
  2927 			$category_suggestions[] = array(
  2700 				'category_id'	=> $cat->term_id,
  2928 				'category_id'	=> $cat->term_id,
  2701 				'category_name'	=> $cat->name
  2929 				'category_name'	=> $cat->name
  2702 			);
  2930 			);
  2703 		}
  2931 		}
  2704 
  2932 
  2705 		return($category_suggestions);
  2933 		return $category_suggestions;
  2706 	}
  2934 	}
  2707 
  2935 
  2708 	/**
  2936 	/**
  2709 	 * Retrieve comment.
  2937 	 * Retrieve comment.
  2710 	 *
  2938 	 *
  2711 	 * @since 2.7.0
  2939 	 * @since 2.7.0
  2712 	 *
  2940 	 *
  2713 	 * @param array $args Method parameters.
  2941 	 * @param array $args Method parameters.
  2714 	 * @return array
  2942 	 * @return array|IXR_Error
  2715 	 */
  2943 	 */
  2716 	function wp_getComment($args) {
  2944 	public function wp_getComment($args) {
  2717 		$this->escape($args);
  2945 		$this->escape($args);
  2718 
  2946 
  2719 		$blog_id	= (int) $args[0];
       
  2720 		$username	= $args[1];
  2947 		$username	= $args[1];
  2721 		$password	= $args[2];
  2948 		$password	= $args[2];
  2722 		$comment_id	= (int) $args[3];
  2949 		$comment_id	= (int) $args[3];
  2723 
  2950 
  2724 		if ( !$user = $this->login($username, $password) )
  2951 		if ( !$user = $this->login($username, $password) )
  2725 			return $this->error;
  2952 			return $this->error;
  2726 
  2953 
  2727 		if ( !current_user_can( 'moderate_comments' ) )
  2954 		if ( !current_user_can( 'moderate_comments' ) )
  2728 			return new IXR_Error( 403, __( 'You are not allowed to moderate comments on this site.' ) );
  2955 			return new IXR_Error( 403, __( 'You are not allowed to moderate comments on this site.' ) );
  2729 
  2956 
  2730 		do_action('xmlrpc_call', 'wp.getComment');
  2957 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  2958 		do_action( 'xmlrpc_call', 'wp.getComment' );
  2731 
  2959 
  2732 		if ( ! $comment = get_comment($comment_id) )
  2960 		if ( ! $comment = get_comment($comment_id) )
  2733 			return new IXR_Error( 404, __( 'Invalid comment ID.' ) );
  2961 			return new IXR_Error( 404, __( 'Invalid comment ID.' ) );
  2734 
  2962 
  2735 		return $this->_prepare_comment( $comment );
  2963 		return $this->_prepare_comment( $comment );
  2736 	}
  2964 	}
  2737 
  2965 
  2738 	/**
  2966 	/**
  2739 	 * Retrieve comments.
  2967 	 * Retrieve comments.
  2740 	 *
  2968 	 *
  2741 	 * Besides the common blog_id, username, and password arguments, it takes a filter
  2969 	 * Besides the common blog_id (unused), username, and password arguments, it takes a filter
  2742 	 * array as last argument.
  2970 	 * array as last argument.
  2743 	 *
  2971 	 *
  2744 	 * Accepted 'filter' keys are 'status', 'post_id', 'offset', and 'number'.
  2972 	 * Accepted 'filter' keys are 'status', 'post_id', 'offset', and 'number'.
  2745 	 *
  2973 	 *
  2746 	 * The defaults are as follows:
  2974 	 * The defaults are as follows:
  2750 	 * - 'offset' - Default is 0. See {@link WP_Query::query()} for more.
  2978 	 * - 'offset' - Default is 0. See {@link WP_Query::query()} for more.
  2751 	 *
  2979 	 *
  2752 	 * @since 2.7.0
  2980 	 * @since 2.7.0
  2753 	 *
  2981 	 *
  2754 	 * @param array $args Method parameters.
  2982 	 * @param array $args Method parameters.
  2755 	 * @return array. Contains a collection of comments. See {@link wp_xmlrpc_server::wp_getComment()} for a description of each item contents
  2983 	 * @return array|IXR_Error Contains a collection of comments. See {@link wp_xmlrpc_server::wp_getComment()} for a description of each item contents
  2756 	 */
  2984 	 */
  2757 	function wp_getComments($args) {
  2985 	public function wp_getComments($args) {
  2758 		$this->escape($args);
  2986 		$this->escape($args);
  2759 
  2987 
  2760 		$blog_id	= (int) $args[0];
       
  2761 		$username	= $args[1];
  2988 		$username	= $args[1];
  2762 		$password	= $args[2];
  2989 		$password	= $args[2];
  2763 		$struct		= isset( $args[3] ) ? $args[3] : array();
  2990 		$struct		= isset( $args[3] ) ? $args[3] : array();
  2764 
  2991 
  2765 		if ( !$user = $this->login($username, $password) )
  2992 		if ( !$user = $this->login($username, $password) )
  2766 			return $this->error;
  2993 			return $this->error;
  2767 
  2994 
  2768 		if ( !current_user_can( 'moderate_comments' ) )
  2995 		if ( !current_user_can( 'moderate_comments' ) )
  2769 			return new IXR_Error( 401, __( 'Sorry, you cannot edit comments.' ) );
  2996 			return new IXR_Error( 401, __( 'Sorry, you cannot edit comments.' ) );
  2770 
  2997 
  2771 		do_action('xmlrpc_call', 'wp.getComments');
  2998 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  2999 		do_action( 'xmlrpc_call', 'wp.getComments' );
  2772 
  3000 
  2773 		if ( isset($struct['status']) )
  3001 		if ( isset($struct['status']) )
  2774 			$status = $struct['status'];
  3002 			$status = $struct['status'];
  2775 		else
  3003 		else
  2776 			$status = '';
  3004 			$status = '';
  2806 	 * this behavior.
  3034 	 * this behavior.
  2807 	 *
  3035 	 *
  2808 	 * @since 2.7.0
  3036 	 * @since 2.7.0
  2809 	 *
  3037 	 *
  2810 	 * @param array $args Method parameters. Contains:
  3038 	 * @param array $args Method parameters. Contains:
  2811 	 *  - blog_id
  3039 	 *  - blog_id (unused)
  2812 	 *  - username
  3040 	 *  - username
  2813 	 *  - password
  3041 	 *  - password
  2814 	 *  - comment_id
  3042 	 *  - comment_id
  2815 	 * @return mixed {@link wp_delete_comment()}
  3043 	 * @return bool|IXR_Error {@link wp_delete_comment()}
  2816 	 */
  3044 	 */
  2817 	function wp_deleteComment($args) {
  3045 	public function wp_deleteComment($args) {
  2818 		$this->escape($args);
  3046 		$this->escape($args);
  2819 
  3047 
  2820 		$blog_id	= (int) $args[0];
       
  2821 		$username	= $args[1];
  3048 		$username	= $args[1];
  2822 		$password	= $args[2];
  3049 		$password	= $args[2];
  2823 		$comment_ID	= (int) $args[3];
  3050 		$comment_ID	= (int) $args[3];
  2824 
  3051 
  2825 		if ( !$user = $this->login($username, $password) )
  3052 		if ( !$user = $this->login($username, $password) )
  2832 			return new IXR_Error( 404, __( 'Invalid comment ID.' ) );
  3059 			return new IXR_Error( 404, __( 'Invalid comment ID.' ) );
  2833 
  3060 
  2834 		if ( !current_user_can( 'edit_comment', $comment_ID ) )
  3061 		if ( !current_user_can( 'edit_comment', $comment_ID ) )
  2835 			return new IXR_Error( 403, __( 'You are not allowed to moderate comments on this site.' ) );
  3062 			return new IXR_Error( 403, __( 'You are not allowed to moderate comments on this site.' ) );
  2836 
  3063 
  2837 		do_action('xmlrpc_call', 'wp.deleteComment');
  3064 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  3065 		do_action( 'xmlrpc_call', 'wp.deleteComment' );
  2838 
  3066 
  2839 		$status = wp_delete_comment( $comment_ID );
  3067 		$status = wp_delete_comment( $comment_ID );
  2840 
  3068 
  2841 		if( true == $status )
  3069 		if ( true == $status ) {
       
  3070 			/**
       
  3071 			 * Fires after a comment has been successfully deleted via XML-RPC.
       
  3072 			 *
       
  3073 			 * @since 3.4.0
       
  3074 			 *
       
  3075 			 * @param int   $comment_ID ID of the deleted comment.
       
  3076 			 * @param array $args       An array of arguments to delete the comment.
       
  3077 			 */
  2842 			do_action( 'xmlrpc_call_success_wp_deleteComment', $comment_ID, $args );
  3078 			do_action( 'xmlrpc_call_success_wp_deleteComment', $comment_ID, $args );
       
  3079 		}
  2843 
  3080 
  2844 		return $status;
  3081 		return $status;
  2845 	}
  3082 	}
  2846 
  3083 
  2847 	/**
  3084 	/**
  2848 	 * Edit comment.
  3085 	 * Edit comment.
  2849 	 *
  3086 	 *
  2850 	 * Besides the common blog_id, username, and password arguments, it takes a
  3087 	 * Besides the common blog_id (unused), username, and password arguments, it takes a
  2851 	 * comment_id integer and a content_struct array as last argument.
  3088 	 * comment_id integer and a content_struct array as last argument.
  2852 	 *
  3089 	 *
  2853 	 * The allowed keys in the content_struct array are:
  3090 	 * The allowed keys in the content_struct array are:
  2854 	 *  - 'author'
  3091 	 *  - 'author'
  2855 	 *  - 'author_url'
  3092 	 *  - 'author_url'
  2858 	 *  - 'date_created_gmt'
  3095 	 *  - 'date_created_gmt'
  2859 	 *  - 'status'. Common statuses are 'approve', 'hold', 'spam'. See {@link get_comment_statuses()} for more details
  3096 	 *  - 'status'. Common statuses are 'approve', 'hold', 'spam'. See {@link get_comment_statuses()} for more details
  2860 	 *
  3097 	 *
  2861 	 * @since 2.7.0
  3098 	 * @since 2.7.0
  2862 	 *
  3099 	 *
  2863 	 * @param array $args. Contains:
  3100 	 * @param array $args Contains:
  2864 	 *  - blog_id
  3101 	 *  - blog_id (unused)
  2865 	 *  - username
  3102 	 *  - username
  2866 	 *  - password
  3103 	 *  - password
  2867 	 *  - comment_id
  3104 	 *  - comment_id
  2868 	 *  - content_struct
  3105 	 *  - content_struct
  2869 	 * @return bool True, on success.
  3106 	 * @return bool|IXR_Error True, on success.
  2870 	 */
  3107 	 */
  2871 	function wp_editComment($args) {
  3108 	public function wp_editComment($args) {
  2872 		$this->escape($args);
  3109 		$this->escape($args);
  2873 
  3110 
  2874 		$blog_id	= (int) $args[0];
       
  2875 		$username	= $args[1];
  3111 		$username	= $args[1];
  2876 		$password	= $args[2];
  3112 		$password	= $args[2];
  2877 		$comment_ID	= (int) $args[3];
  3113 		$comment_ID	= (int) $args[3];
  2878 		$content_struct = $args[4];
  3114 		$content_struct = $args[4];
  2879 
  3115 
  2887 			return new IXR_Error( 404, __( 'Invalid comment ID.' ) );
  3123 			return new IXR_Error( 404, __( 'Invalid comment ID.' ) );
  2888 
  3124 
  2889 		if ( !current_user_can( 'edit_comment', $comment_ID ) )
  3125 		if ( !current_user_can( 'edit_comment', $comment_ID ) )
  2890 			return new IXR_Error( 403, __( 'You are not allowed to moderate comments on this site.' ) );
  3126 			return new IXR_Error( 403, __( 'You are not allowed to moderate comments on this site.' ) );
  2891 
  3127 
  2892 		do_action('xmlrpc_call', 'wp.editComment');
  3128 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  3129 		do_action( 'xmlrpc_call', 'wp.editComment' );
  2893 
  3130 
  2894 		if ( isset($content_struct['status']) ) {
  3131 		if ( isset($content_struct['status']) ) {
  2895 			$statuses = get_comment_statuses();
  3132 			$statuses = get_comment_statuses();
  2896 			$statuses = array_keys($statuses);
  3133 			$statuses = array_keys($statuses);
  2897 
  3134 
  2928 			return new IXR_Error(500, $result->get_error_message());
  3165 			return new IXR_Error(500, $result->get_error_message());
  2929 
  3166 
  2930 		if ( !$result )
  3167 		if ( !$result )
  2931 			return new IXR_Error(500, __('Sorry, the comment could not be edited. Something wrong happened.'));
  3168 			return new IXR_Error(500, __('Sorry, the comment could not be edited. Something wrong happened.'));
  2932 
  3169 
       
  3170 		/**
       
  3171 		 * Fires after a comment has been successfully updated via XML-RPC.
       
  3172 		 *
       
  3173 		 * @since 3.4.0
       
  3174 		 *
       
  3175 		 * @param int   $comment_ID ID of the updated comment.
       
  3176 		 * @param array $args       An array of arguments to update the comment.
       
  3177 		 */
  2933 		do_action( 'xmlrpc_call_success_wp_editComment', $comment_ID, $args );
  3178 		do_action( 'xmlrpc_call_success_wp_editComment', $comment_ID, $args );
  2934 
  3179 
  2935 		return true;
  3180 		return true;
  2936 	}
  3181 	}
  2937 
  3182 
  2939 	 * Create new comment.
  3184 	 * Create new comment.
  2940 	 *
  3185 	 *
  2941 	 * @since 2.7.0
  3186 	 * @since 2.7.0
  2942 	 *
  3187 	 *
  2943 	 * @param array $args Method parameters.
  3188 	 * @param array $args Method parameters.
  2944 	 * @return mixed {@link wp_new_comment()}
  3189 	 * @return int|IXR_Error {@link wp_new_comment()}
  2945 	 */
  3190 	 */
  2946 	function wp_newComment($args) {
  3191 	public function wp_newComment($args) {
  2947 		global $wpdb;
       
  2948 
       
  2949 		$this->escape($args);
  3192 		$this->escape($args);
  2950 
  3193 
  2951 		$blog_id	= (int) $args[0];
       
  2952 		$username	= $args[1];
  3194 		$username	= $args[1];
  2953 		$password	= $args[2];
  3195 		$password	= $args[2];
  2954 		$post		= $args[3];
  3196 		$post		= $args[3];
  2955 		$content_struct = $args[4];
  3197 		$content_struct = $args[4];
  2956 
  3198 
  2957 		$allow_anon = apply_filters('xmlrpc_allow_anonymous_comments', false);
  3199 		/**
       
  3200 		 * Filter whether to allow anonymous comments over XML-RPC.
       
  3201 		 *
       
  3202 		 * @since 2.7.0
       
  3203 		 *
       
  3204 		 * @param bool $allow Whether to allow anonymous commenting via XML-RPC.
       
  3205 		 *                    Default false.
       
  3206 		 */
       
  3207 		$allow_anon = apply_filters( 'xmlrpc_allow_anonymous_comments', false );
  2958 
  3208 
  2959 		$user = $this->login($username, $password);
  3209 		$user = $this->login($username, $password);
  2960 
  3210 
  2961 		if ( !$user ) {
  3211 		if ( !$user ) {
  2962 			$logged_in = false;
  3212 			$logged_in = false;
  2963 			if ( $allow_anon && get_option('comment_registration') )
  3213 			if ( $allow_anon && get_option('comment_registration') ) {
  2964 				return new IXR_Error( 403, __( 'You must be registered to comment' ) );
  3214 				return new IXR_Error( 403, __( 'You must be registered to comment' ) );
  2965 			else if ( !$allow_anon )
  3215 			} elseif ( ! $allow_anon ) {
  2966 				return $this->error;
  3216 				return $this->error;
       
  3217 			}
  2967 		} else {
  3218 		} else {
  2968 			$logged_in = true;
  3219 			$logged_in = true;
  2969 		}
  3220 		}
  2970 
  3221 
  2971 		if ( is_numeric($post) )
  3222 		if ( is_numeric($post) )
  2977 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  3228 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  2978 
  3229 
  2979 		if ( ! get_post($post_id) )
  3230 		if ( ! get_post($post_id) )
  2980 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  3231 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  2981 
  3232 
       
  3233 		$comment = array();
  2982 		$comment['comment_post_ID'] = $post_id;
  3234 		$comment['comment_post_ID'] = $post_id;
  2983 
  3235 
  2984 		if ( $logged_in ) {
  3236 		if ( $logged_in ) {
  2985 			$comment['comment_author'] = $this->escape( $user->display_name );
  3237 			$comment['comment_author'] = $this->escape( $user->display_name );
  2986 			$comment['comment_author_email'] = $this->escape( $user->user_email );
  3238 			$comment['comment_author_email'] = $this->escape( $user->user_email );
  3011 
  3263 
  3012 		$comment['comment_parent'] = isset($content_struct['comment_parent']) ? absint($content_struct['comment_parent']) : 0;
  3264 		$comment['comment_parent'] = isset($content_struct['comment_parent']) ? absint($content_struct['comment_parent']) : 0;
  3013 
  3265 
  3014 		$comment['comment_content'] =  isset($content_struct['content']) ? $content_struct['content'] : null;
  3266 		$comment['comment_content'] =  isset($content_struct['content']) ? $content_struct['content'] : null;
  3015 
  3267 
  3016 		do_action('xmlrpc_call', 'wp.newComment');
  3268 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  3269 		do_action( 'xmlrpc_call', 'wp.newComment' );
  3017 
  3270 
  3018 		$comment_ID = wp_new_comment( $comment );
  3271 		$comment_ID = wp_new_comment( $comment );
  3019 
  3272 
       
  3273 		/**
       
  3274 		 * Fires after a new comment has been successfully created via XML-RPC.
       
  3275 		 *
       
  3276 		 * @since 3.4.0
       
  3277 		 *
       
  3278 		 * @param int   $comment_ID ID of the new comment.
       
  3279 		 * @param array $args       An array of new comment arguments.
       
  3280 		 */
  3020 		do_action( 'xmlrpc_call_success_wp_newComment', $comment_ID, $args );
  3281 		do_action( 'xmlrpc_call_success_wp_newComment', $comment_ID, $args );
  3021 
  3282 
  3022 		return $comment_ID;
  3283 		return $comment_ID;
  3023 	}
  3284 	}
  3024 
  3285 
  3026 	 * Retrieve all of the comment status.
  3287 	 * Retrieve all of the comment status.
  3027 	 *
  3288 	 *
  3028 	 * @since 2.7.0
  3289 	 * @since 2.7.0
  3029 	 *
  3290 	 *
  3030 	 * @param array $args Method parameters.
  3291 	 * @param array $args Method parameters.
  3031 	 * @return array
  3292 	 * @return array|IXR_Error
  3032 	 */
  3293 	 */
  3033 	function wp_getCommentStatusList($args) {
  3294 	public function wp_getCommentStatusList($args) {
  3034 		$this->escape( $args );
  3295 		$this->escape( $args );
  3035 
  3296 
  3036 		$blog_id	= (int) $args[0];
       
  3037 		$username	= $args[1];
  3297 		$username	= $args[1];
  3038 		$password	= $args[2];
  3298 		$password	= $args[2];
  3039 
  3299 
  3040 		if ( !$user = $this->login($username, $password) )
  3300 		if ( !$user = $this->login($username, $password) )
  3041 			return $this->error;
  3301 			return $this->error;
  3042 
  3302 
  3043 		if ( !current_user_can( 'moderate_comments' ) )
  3303 		if ( !current_user_can( 'moderate_comments' ) )
  3044 			return new IXR_Error( 403, __( 'You are not allowed access to details about this site.' ) );
  3304 			return new IXR_Error( 403, __( 'You are not allowed access to details about this site.' ) );
  3045 
  3305 
  3046 		do_action('xmlrpc_call', 'wp.getCommentStatusList');
  3306 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  3307 		do_action( 'xmlrpc_call', 'wp.getCommentStatusList' );
  3047 
  3308 
  3048 		return get_comment_statuses();
  3309 		return get_comment_statuses();
  3049 	}
  3310 	}
  3050 
  3311 
  3051 	/**
  3312 	/**
  3052 	 * Retrieve comment count.
  3313 	 * Retrieve comment count.
  3053 	 *
  3314 	 *
  3054 	 * @since 2.5.0
  3315 	 * @since 2.5.0
  3055 	 *
  3316 	 *
  3056 	 * @param array $args Method parameters.
  3317 	 * @param array $args Method parameters.
  3057 	 * @return array
  3318 	 * @return array|IXR_Error
  3058 	 */
  3319 	 */
  3059 	function wp_getCommentCount( $args ) {
  3320 	public function wp_getCommentCount( $args ) {
  3060 		$this->escape($args);
  3321 		$this->escape($args);
  3061 
  3322 
  3062 		$blog_id	= (int) $args[0];
       
  3063 		$username	= $args[1];
  3323 		$username	= $args[1];
  3064 		$password	= $args[2];
  3324 		$password	= $args[2];
  3065 		$post_id	= (int) $args[3];
  3325 		$post_id	= (int) $args[3];
  3066 
  3326 
  3067 		if ( !$user = $this->login($username, $password) )
  3327 		if ( !$user = $this->login($username, $password) )
  3068 			return $this->error;
  3328 			return $this->error;
  3069 
  3329 
  3070 		if ( !current_user_can( 'edit_posts' ) )
  3330 		if ( !current_user_can( 'edit_posts' ) )
  3071 			return new IXR_Error( 403, __( 'You are not allowed access to details about comments.' ) );
  3331 			return new IXR_Error( 403, __( 'You are not allowed access to details about comments.' ) );
  3072 
  3332 
  3073 		do_action('xmlrpc_call', 'wp.getCommentCount');
  3333 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  3334 		do_action( 'xmlrpc_call', 'wp.getCommentCount' );
  3074 
  3335 
  3075 		$count = wp_count_comments( $post_id );
  3336 		$count = wp_count_comments( $post_id );
  3076 		return array(
  3337 		return array(
  3077 			'approved' => $count->approved,
  3338 			'approved' => $count->approved,
  3078 			'awaiting_moderation' => $count->moderated,
  3339 			'awaiting_moderation' => $count->moderated,
  3085 	 * Retrieve post statuses.
  3346 	 * Retrieve post statuses.
  3086 	 *
  3347 	 *
  3087 	 * @since 2.5.0
  3348 	 * @since 2.5.0
  3088 	 *
  3349 	 *
  3089 	 * @param array $args Method parameters.
  3350 	 * @param array $args Method parameters.
  3090 	 * @return array
  3351 	 * @return array|IXR_Error
  3091 	 */
  3352 	 */
  3092 	function wp_getPostStatusList( $args ) {
  3353 	public function wp_getPostStatusList( $args ) {
  3093 		$this->escape( $args );
  3354 		$this->escape( $args );
  3094 
  3355 
  3095 		$blog_id	= (int) $args[0];
       
  3096 		$username	= $args[1];
  3356 		$username	= $args[1];
  3097 		$password	= $args[2];
  3357 		$password	= $args[2];
  3098 
  3358 
  3099 		if ( !$user = $this->login($username, $password) )
  3359 		if ( !$user = $this->login($username, $password) )
  3100 			return $this->error;
  3360 			return $this->error;
  3101 
  3361 
  3102 		if ( !current_user_can( 'edit_posts' ) )
  3362 		if ( !current_user_can( 'edit_posts' ) )
  3103 			return new IXR_Error( 403, __( 'You are not allowed access to details about this site.' ) );
  3363 			return new IXR_Error( 403, __( 'You are not allowed access to details about this site.' ) );
  3104 
  3364 
  3105 		do_action('xmlrpc_call', 'wp.getPostStatusList');
  3365 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  3366 		do_action( 'xmlrpc_call', 'wp.getPostStatusList' );
  3106 
  3367 
  3107 		return get_post_statuses();
  3368 		return get_post_statuses();
  3108 	}
  3369 	}
  3109 
  3370 
  3110 	/**
  3371 	/**
  3111 	 * Retrieve page statuses.
  3372 	 * Retrieve page statuses.
  3112 	 *
  3373 	 *
  3113 	 * @since 2.5.0
  3374 	 * @since 2.5.0
  3114 	 *
  3375 	 *
  3115 	 * @param array $args Method parameters.
  3376 	 * @param array $args Method parameters.
  3116 	 * @return array
  3377 	 * @return array|IXR_Error
  3117 	 */
  3378 	 */
  3118 	function wp_getPageStatusList( $args ) {
  3379 	public function wp_getPageStatusList( $args ) {
  3119 		$this->escape( $args );
  3380 		$this->escape( $args );
  3120 
  3381 
  3121 		$blog_id	= (int) $args[0];
       
  3122 		$username	= $args[1];
  3382 		$username	= $args[1];
  3123 		$password	= $args[2];
  3383 		$password	= $args[2];
  3124 
  3384 
  3125 		if ( !$user = $this->login($username, $password) )
  3385 		if ( !$user = $this->login($username, $password) )
  3126 			return $this->error;
  3386 			return $this->error;
  3127 
  3387 
  3128 		if ( !current_user_can( 'edit_pages' ) )
  3388 		if ( !current_user_can( 'edit_pages' ) )
  3129 			return new IXR_Error( 403, __( 'You are not allowed access to details about this site.' ) );
  3389 			return new IXR_Error( 403, __( 'You are not allowed access to details about this site.' ) );
  3130 
  3390 
  3131 		do_action('xmlrpc_call', 'wp.getPageStatusList');
  3391 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  3392 		do_action( 'xmlrpc_call', 'wp.getPageStatusList' );
  3132 
  3393 
  3133 		return get_page_statuses();
  3394 		return get_page_statuses();
  3134 	}
  3395 	}
  3135 
  3396 
  3136 	/**
  3397 	/**
  3137 	 * Retrieve page templates.
  3398 	 * Retrieve page templates.
  3138 	 *
  3399 	 *
  3139 	 * @since 2.6.0
  3400 	 * @since 2.6.0
  3140 	 *
  3401 	 *
  3141 	 * @param array $args Method parameters.
  3402 	 * @param array $args Method parameters.
  3142 	 * @return array
  3403 	 * @return array|IXR_Error
  3143 	 */
  3404 	 */
  3144 	function wp_getPageTemplates( $args ) {
  3405 	public function wp_getPageTemplates( $args ) {
  3145 		$this->escape( $args );
  3406 		$this->escape( $args );
  3146 
  3407 
  3147 		$blog_id	= (int) $args[0];
       
  3148 		$username	= $args[1];
  3408 		$username	= $args[1];
  3149 		$password	= $args[2];
  3409 		$password	= $args[2];
  3150 
  3410 
  3151 		if ( !$user = $this->login($username, $password) )
  3411 		if ( !$user = $this->login($username, $password) )
  3152 			return $this->error;
  3412 			return $this->error;
  3164 	 * Retrieve blog options.
  3424 	 * Retrieve blog options.
  3165 	 *
  3425 	 *
  3166 	 * @since 2.6.0
  3426 	 * @since 2.6.0
  3167 	 *
  3427 	 *
  3168 	 * @param array $args Method parameters.
  3428 	 * @param array $args Method parameters.
  3169 	 * @return array
  3429 	 * @return array|IXR_Error
  3170 	 */
  3430 	 */
  3171 	function wp_getOptions( $args ) {
  3431 	public function wp_getOptions( $args ) {
  3172 		$this->escape( $args );
  3432 		$this->escape( $args );
  3173 
  3433 
  3174 		$blog_id	= (int) $args[0];
       
  3175 		$username	= $args[1];
  3434 		$username	= $args[1];
  3176 		$password	= $args[2];
  3435 		$password	= $args[2];
  3177 		$options	= isset( $args[3] ) ? (array) $args[3] : array();
  3436 		$options	= isset( $args[3] ) ? (array) $args[3] : array();
  3178 
  3437 
  3179 		if ( !$user = $this->login($username, $password) )
  3438 		if ( !$user = $this->login($username, $password) )
  3192 	 * @since 2.6.0
  3451 	 * @since 2.6.0
  3193 	 *
  3452 	 *
  3194 	 * @param array $options Options to retrieve.
  3453 	 * @param array $options Options to retrieve.
  3195 	 * @return array
  3454 	 * @return array
  3196 	 */
  3455 	 */
  3197 	function _getOptions($options) {
  3456 	public function _getOptions($options) {
  3198 		$data = array();
  3457 		$data = array();
  3199 		$can_manage = current_user_can( 'manage_options' );
  3458 		$can_manage = current_user_can( 'manage_options' );
  3200 		foreach ( $options as $option ) {
  3459 		foreach ( $options as $option ) {
  3201 			if ( array_key_exists( $option, $this->blog_options ) ) {
  3460 			if ( array_key_exists( $option, $this->blog_options ) ) {
  3202 				$data[$option] = $this->blog_options[$option];
  3461 				$data[$option] = $this->blog_options[$option];
  3218 	 * Update blog options.
  3477 	 * Update blog options.
  3219 	 *
  3478 	 *
  3220 	 * @since 2.6.0
  3479 	 * @since 2.6.0
  3221 	 *
  3480 	 *
  3222 	 * @param array $args Method parameters.
  3481 	 * @param array $args Method parameters.
  3223 	 * @return unknown
  3482 	 * @return array|IXR_Error
  3224 	 */
  3483 	 */
  3225 	function wp_setOptions( $args ) {
  3484 	public function wp_setOptions( $args ) {
  3226 		$this->escape( $args );
  3485 		$this->escape( $args );
  3227 
  3486 
  3228 		$blog_id	= (int) $args[0];
       
  3229 		$username	= $args[1];
  3487 		$username	= $args[1];
  3230 		$password	= $args[2];
  3488 		$password	= $args[2];
  3231 		$options	= (array) $args[3];
  3489 		$options	= (array) $args[3];
  3232 
  3490 
  3233 		if ( !$user = $this->login($username, $password) )
  3491 		if ( !$user = $this->login($username, $password) )
  3234 			return $this->error;
  3492 			return $this->error;
  3235 
  3493 
  3236 		if ( !current_user_can( 'manage_options' ) )
  3494 		if ( !current_user_can( 'manage_options' ) )
  3237 			return new IXR_Error( 403, __( 'You are not allowed to update options.' ) );
  3495 			return new IXR_Error( 403, __( 'You are not allowed to update options.' ) );
  3238 
  3496 
       
  3497 		$option_names = array();
  3239 		foreach ( $options as $o_name => $o_value ) {
  3498 		foreach ( $options as $o_name => $o_value ) {
  3240 			$option_names[] = $o_name;
  3499 			$option_names[] = $o_name;
  3241 			if ( !array_key_exists( $o_name, $this->blog_options ) )
  3500 			if ( !array_key_exists( $o_name, $this->blog_options ) )
  3242 				continue;
  3501 				continue;
  3243 
  3502 
  3244 			if ( $this->blog_options[$o_name]['readonly'] == true )
  3503 			if ( $this->blog_options[$o_name]['readonly'] == true )
  3245 				continue;
  3504 				continue;
  3246 
  3505 
  3247 			update_option( $this->blog_options[$o_name]['option'], $o_value );
  3506 			update_option( $this->blog_options[$o_name]['option'], wp_unslash( $o_value ) );
  3248 		}
  3507 		}
  3249 
  3508 
  3250 		//Now return the updated values
  3509 		//Now return the updated values
  3251 		return $this->_getOptions($option_names);
  3510 		return $this->_getOptions($option_names);
  3252 	}
  3511 	}
  3255 	 * Retrieve a media item by ID
  3514 	 * Retrieve a media item by ID
  3256 	 *
  3515 	 *
  3257 	 * @since 3.1.0
  3516 	 * @since 3.1.0
  3258 	 *
  3517 	 *
  3259 	 * @param array $args Method parameters. Contains:
  3518 	 * @param array $args Method parameters. Contains:
  3260 	 *  - blog_id
  3519 	 *  - blog_id (unused)
  3261 	 *  - username
  3520 	 *  - username
  3262 	 *  - password
  3521 	 *  - password
  3263 	 *  - attachment_id
  3522 	 *  - attachment_id
  3264 	 * @return array. Associative array containing:
  3523 	 * @return array|IXR_Error Associative array contains:
  3265 	 *  - 'date_created_gmt'
  3524 	 *  - 'date_created_gmt'
  3266 	 *  - 'parent'
  3525 	 *  - 'parent'
  3267 	 *  - 'link'
  3526 	 *  - 'link'
  3268 	 *  - 'thumbnail'
  3527 	 *  - 'thumbnail'
  3269 	 *  - 'title'
  3528 	 *  - 'title'
  3270 	 *  - 'caption'
  3529 	 *  - 'caption'
  3271 	 *  - 'description'
  3530 	 *  - 'description'
  3272 	 *  - 'metadata'
  3531 	 *  - 'metadata'
  3273 	 */
  3532 	 */
  3274 	function wp_getMediaItem($args) {
  3533 	public function wp_getMediaItem($args) {
  3275 		$this->escape($args);
  3534 		$this->escape($args);
  3276 
  3535 
  3277 		$blog_id		= (int) $args[0];
       
  3278 		$username		= $args[1];
  3536 		$username		= $args[1];
  3279 		$password		= $args[2];
  3537 		$password		= $args[2];
  3280 		$attachment_id	= (int) $args[3];
  3538 		$attachment_id	= (int) $args[3];
  3281 
  3539 
  3282 		if ( !$user = $this->login($username, $password) )
  3540 		if ( !$user = $this->login($username, $password) )
  3283 			return $this->error;
  3541 			return $this->error;
  3284 
  3542 
  3285 		if ( !current_user_can( 'upload_files' ) )
  3543 		if ( !current_user_can( 'upload_files' ) )
  3286 			return new IXR_Error( 403, __( 'You do not have permission to upload files.' ) );
  3544 			return new IXR_Error( 403, __( 'You do not have permission to upload files.' ) );
  3287 
  3545 
  3288 		do_action('xmlrpc_call', 'wp.getMediaItem');
  3546 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  3547 		do_action( 'xmlrpc_call', 'wp.getMediaItem' );
  3289 
  3548 
  3290 		if ( ! $attachment = get_post($attachment_id) )
  3549 		if ( ! $attachment = get_post($attachment_id) )
  3291 			return new IXR_Error( 404, __( 'Invalid attachment ID.' ) );
  3550 			return new IXR_Error( 404, __( 'Invalid attachment ID.' ) );
  3292 
  3551 
  3293 		return $this->_prepare_media_item( $attachment );
  3552 		return $this->_prepare_media_item( $attachment );
  3294 	}
  3553 	}
  3295 
  3554 
  3296 	/**
  3555 	/**
  3297 	 * Retrieves a collection of media library items (or attachments)
  3556 	 * Retrieves a collection of media library items (or attachments)
  3298 	 *
  3557 	 *
  3299 	 * Besides the common blog_id, username, and password arguments, it takes a filter
  3558 	 * Besides the common blog_id (unused), username, and password arguments, it takes a filter
  3300 	 * array as last argument.
  3559 	 * array as last argument.
  3301 	 *
  3560 	 *
  3302 	 * Accepted 'filter' keys are 'parent_id', 'mime_type', 'offset', and 'number'.
  3561 	 * Accepted 'filter' keys are 'parent_id', 'mime_type', 'offset', and 'number'.
  3303 	 *
  3562 	 *
  3304 	 * The defaults are as follows:
  3563 	 * The defaults are as follows:
  3308 	 * - 'mime_type' - Default is ''. Filter by mime type (e.g., 'image/jpeg', 'application/pdf')
  3567 	 * - 'mime_type' - Default is ''. Filter by mime type (e.g., 'image/jpeg', 'application/pdf')
  3309 	 *
  3568 	 *
  3310 	 * @since 3.1.0
  3569 	 * @since 3.1.0
  3311 	 *
  3570 	 *
  3312 	 * @param array $args Method parameters. Contains:
  3571 	 * @param array $args Method parameters. Contains:
  3313 	 *  - blog_id
  3572 	 *  - blog_id (unused)
  3314 	 *  - username
  3573 	 *  - username
  3315 	 *  - password
  3574 	 *  - password
  3316 	 *  - filter
  3575 	 *  - filter
  3317 	 * @return array. Contains a collection of media items. See {@link wp_xmlrpc_server::wp_getMediaItem()} for a description of each item contents
  3576 	 * @return array|IXR_Error Contains a collection of media items. See {@link wp_xmlrpc_server::wp_getMediaItem()} for a description of each item contents
  3318 	 */
  3577 	 */
  3319 	function wp_getMediaLibrary($args) {
  3578 	public function wp_getMediaLibrary($args) {
  3320 		$this->escape($args);
  3579 		$this->escape($args);
  3321 
  3580 
  3322 		$blog_id	= (int) $args[0];
       
  3323 		$username	= $args[1];
  3581 		$username	= $args[1];
  3324 		$password	= $args[2];
  3582 		$password	= $args[2];
  3325 		$struct		= isset( $args[3] ) ? $args[3] : array() ;
  3583 		$struct		= isset( $args[3] ) ? $args[3] : array() ;
  3326 
  3584 
  3327 		if ( !$user = $this->login($username, $password) )
  3585 		if ( !$user = $this->login($username, $password) )
  3328 			return $this->error;
  3586 			return $this->error;
  3329 
  3587 
  3330 		if ( !current_user_can( 'upload_files' ) )
  3588 		if ( !current_user_can( 'upload_files' ) )
  3331 			return new IXR_Error( 401, __( 'You do not have permission to upload files.' ) );
  3589 			return new IXR_Error( 401, __( 'You do not have permission to upload files.' ) );
  3332 
  3590 
  3333 		do_action('xmlrpc_call', 'wp.getMediaLibrary');
  3591 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  3592 		do_action( 'xmlrpc_call', 'wp.getMediaLibrary' );
  3334 
  3593 
  3335 		$parent_id = ( isset($struct['parent_id']) ) ? absint($struct['parent_id']) : '' ;
  3594 		$parent_id = ( isset($struct['parent_id']) ) ? absint($struct['parent_id']) : '' ;
  3336 		$mime_type = ( isset($struct['mime_type']) ) ? $struct['mime_type'] : '' ;
  3595 		$mime_type = ( isset($struct['mime_type']) ) ? $struct['mime_type'] : '' ;
  3337 		$offset = ( isset($struct['offset']) ) ? absint($struct['offset']) : 0 ;
  3596 		$offset = ( isset($struct['offset']) ) ? absint($struct['offset']) : 0 ;
  3338 		$number = ( isset($struct['number']) ) ? absint($struct['number']) : -1 ;
  3597 		$number = ( isset($struct['number']) ) ? absint($struct['number']) : -1 ;
  3348 	}
  3607 	}
  3349 
  3608 
  3350 	/**
  3609 	/**
  3351 	  * Retrieves a list of post formats used by the site
  3610 	  * Retrieves a list of post formats used by the site
  3352 	  *
  3611 	  *
  3353 	  * @since 3.1
  3612 	  * @since 3.1.0
  3354 	  *
  3613 	  *
  3355 	  * @param array $args Method parameters. Contains:
  3614 	  * @param array $args Method parameters. Contains:
  3356 	  *  - blog_id
  3615 	  *  - blog_id (unused)
  3357 	  *  - username
  3616 	  *  - username
  3358 	  *  - password
  3617 	  *  - password
  3359 	  * @return array
  3618 	  * @return array|IXR_Error
  3360 	  */
  3619 	  */
  3361 	function wp_getPostFormats( $args ) {
  3620 	public function wp_getPostFormats( $args ) {
  3362 		$this->escape( $args );
  3621 		$this->escape( $args );
  3363 
  3622 
  3364 		$blog_id = (int) $args[0];
       
  3365 		$username = $args[1];
  3623 		$username = $args[1];
  3366 		$password = $args[2];
  3624 		$password = $args[2];
  3367 
  3625 
  3368 		if ( !$user = $this->login( $username, $password ) )
  3626 		if ( !$user = $this->login( $username, $password ) )
  3369 			return $this->error;
  3627 			return $this->error;
  3370 
  3628 
  3371 		if ( !current_user_can( 'edit_posts' ) )
  3629 		if ( !current_user_can( 'edit_posts' ) )
  3372 			return new IXR_Error( 403, __( 'You are not allowed access to details about this site.' ) );
  3630 			return new IXR_Error( 403, __( 'You are not allowed access to details about this site.' ) );
  3373 
  3631 
       
  3632 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3374 		do_action( 'xmlrpc_call', 'wp.getPostFormats' );
  3633 		do_action( 'xmlrpc_call', 'wp.getPostFormats' );
  3375 
  3634 
  3376 		$formats = get_post_format_strings();
  3635 		$formats = get_post_format_strings();
  3377 
  3636 
  3378 		# find out if they want a list of currently supports formats
  3637 		// find out if they want a list of currently supports formats
  3379 		if ( isset( $args[3] ) && is_array( $args[3] ) ) {
  3638 		if ( isset( $args[3] ) && is_array( $args[3] ) ) {
  3380 			if ( $args[3]['show-supported'] ) {
  3639 			if ( $args[3]['show-supported'] ) {
  3381 				if ( current_theme_supports( 'post-formats' ) ) {
  3640 				if ( current_theme_supports( 'post-formats' ) ) {
  3382 					$supported = get_theme_support( 'post-formats' );
  3641 					$supported = get_theme_support( 'post-formats' );
  3383 
  3642 
       
  3643 					$data = array();
  3384 					$data['all'] = $formats;
  3644 					$data['all'] = $formats;
  3385 					$data['supported'] = $supported[0];
  3645 					$data['supported'] = $supported[0];
  3386 
  3646 
  3387 					$formats = $data;
  3647 					$formats = $data;
  3388 				}
  3648 				}
  3397 	 *
  3657 	 *
  3398 	 * @since 3.4.0
  3658 	 * @since 3.4.0
  3399 	 *
  3659 	 *
  3400 	 * @uses get_post_type_object()
  3660 	 * @uses get_post_type_object()
  3401 	 * @param array $args Method parameters. Contains:
  3661 	 * @param array $args Method parameters. Contains:
  3402 	 *  - int     $blog_id
  3662 	 *  - int     $blog_id (unused)
  3403 	 *  - string  $username
  3663 	 *  - string  $username
  3404 	 *  - string  $password
  3664 	 *  - string  $password
  3405 	 *  - string  $post_type_name
  3665 	 *  - string  $post_type_name
  3406 	 *  - array   $fields
  3666 	 *  - array   $fields
  3407 	 * @return array contains:
  3667 	 * @return array|IXR_Error Array contains:
  3408 	 *  - 'labels'
  3668 	 *  - 'labels'
  3409 	 *  - 'description'
  3669 	 *  - 'description'
  3410 	 *  - 'capability_type'
  3670 	 *  - 'capability_type'
  3411 	 *  - 'cap'
  3671 	 *  - 'cap'
  3412 	 *  - 'map_meta_cap'
  3672 	 *  - 'map_meta_cap'
  3413 	 *  - 'hierarchical'
  3673 	 *  - 'hierarchical'
  3414 	 *  - 'menu_position'
  3674 	 *  - 'menu_position'
  3415 	 *  - 'taxonomies'
  3675 	 *  - 'taxonomies'
  3416 	 *  - 'supports'
  3676 	 *  - 'supports'
  3417 	 */
  3677 	 */
  3418 	function wp_getPostType( $args ) {
  3678 	public function wp_getPostType( $args ) {
  3419 		if ( ! $this->minimum_args( $args, 4 ) )
  3679 		if ( ! $this->minimum_args( $args, 4 ) )
  3420 			return $this->error;
  3680 			return $this->error;
  3421 
  3681 
  3422 		$this->escape( $args );
  3682 		$this->escape( $args );
  3423 
  3683 
  3424 		$blog_id        = (int) $args[0];
       
  3425 		$username       = $args[1];
  3684 		$username       = $args[1];
  3426 		$password       = $args[2];
  3685 		$password       = $args[2];
  3427 		$post_type_name = $args[3];
  3686 		$post_type_name = $args[3];
  3428 
  3687 
  3429 		if ( isset( $args[4] ) )
  3688 		if ( isset( $args[4] ) ) {
  3430 			$fields = $args[4];
  3689 			$fields = $args[4];
  3431 		else
  3690 		} else {
       
  3691 			/**
       
  3692 			 * Filter the default query fields used by the given XML-RPC method.
       
  3693 			 *
       
  3694 			 * @since 3.4.0
       
  3695 			 *
       
  3696 			 * @param array  $fields An array of post type query fields for the given method.
       
  3697 			 * @param string $method The method name.
       
  3698 			 */
  3432 			$fields = apply_filters( 'xmlrpc_default_posttype_fields', array( 'labels', 'cap', 'taxonomies' ), 'wp.getPostType' );
  3699 			$fields = apply_filters( 'xmlrpc_default_posttype_fields', array( 'labels', 'cap', 'taxonomies' ), 'wp.getPostType' );
       
  3700 		}
  3433 
  3701 
  3434 		if ( !$user = $this->login( $username, $password ) )
  3702 		if ( !$user = $this->login( $username, $password ) )
  3435 			return $this->error;
  3703 			return $this->error;
  3436 
  3704 
       
  3705 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3437 		do_action( 'xmlrpc_call', 'wp.getPostType' );
  3706 		do_action( 'xmlrpc_call', 'wp.getPostType' );
  3438 
  3707 
  3439 		if( ! post_type_exists( $post_type_name ) )
  3708 		if( ! post_type_exists( $post_type_name ) )
  3440 			return new IXR_Error( 403, __( 'Invalid post type' ) );
  3709 			return new IXR_Error( 403, __( 'Invalid post type' ) );
  3441 
  3710 
  3452 	 *
  3721 	 *
  3453 	 * @since 3.4.0
  3722 	 * @since 3.4.0
  3454 	 *
  3723 	 *
  3455 	 * @uses get_post_types()
  3724 	 * @uses get_post_types()
  3456 	 * @param array $args Method parameters. Contains:
  3725 	 * @param array $args Method parameters. Contains:
  3457 	 *  - int     $blog_id
  3726 	 *  - int     $blog_id (unused)
  3458 	 *  - string  $username
  3727 	 *  - string  $username
  3459 	 *  - string  $password
  3728 	 *  - string  $password
  3460 	 *  - array   $filter
  3729 	 *  - array   $filter
  3461 	 *  - array   $fields
  3730 	 *  - array   $fields
  3462 	 * @return array
  3731 	 * @return array|IXR_Error
  3463 	 */
  3732 	 */
  3464 	function wp_getPostTypes( $args ) {
  3733 	public function wp_getPostTypes( $args ) {
  3465 		if ( ! $this->minimum_args( $args, 3 ) )
  3734 		if ( ! $this->minimum_args( $args, 3 ) )
  3466 			return $this->error;
  3735 			return $this->error;
  3467 
  3736 
  3468 		$this->escape( $args );
  3737 		$this->escape( $args );
  3469 
  3738 
  3470 		$blog_id            = (int) $args[0];
       
  3471 		$username           = $args[1];
  3739 		$username           = $args[1];
  3472 		$password           = $args[2];
  3740 		$password           = $args[2];
  3473 		$filter             = isset( $args[3] ) ? $args[3] : array( 'public' => true );
  3741 		$filter             = isset( $args[3] ) ? $args[3] : array( 'public' => true );
  3474 
  3742 
  3475 		if ( isset( $args[4] ) )
  3743 		if ( isset( $args[4] ) ) {
  3476 			$fields = $args[4];
  3744 			$fields = $args[4];
  3477 		else
  3745 		} else {
       
  3746 			/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3478 			$fields = apply_filters( 'xmlrpc_default_posttype_fields', array( 'labels', 'cap', 'taxonomies' ), 'wp.getPostTypes' );
  3747 			$fields = apply_filters( 'xmlrpc_default_posttype_fields', array( 'labels', 'cap', 'taxonomies' ), 'wp.getPostTypes' );
       
  3748 		}
  3479 
  3749 
  3480 		if ( ! $user = $this->login( $username, $password ) )
  3750 		if ( ! $user = $this->login( $username, $password ) )
  3481 			return $this->error;
  3751 			return $this->error;
  3482 
  3752 
       
  3753 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3483 		do_action( 'xmlrpc_call', 'wp.getPostTypes' );
  3754 		do_action( 'xmlrpc_call', 'wp.getPostTypes' );
  3484 
  3755 
  3485 		$post_types = get_post_types( $filter, 'objects' );
  3756 		$post_types = get_post_types( $filter, 'objects' );
  3486 
  3757 
  3487 		$struct = array();
  3758 		$struct = array();
  3506 	 *
  3777 	 *
  3507 	 * @uses wp_get_post_revisions()
  3778 	 * @uses wp_get_post_revisions()
  3508 	 * @see wp_getPost() for more on $fields
  3779 	 * @see wp_getPost() for more on $fields
  3509 	 *
  3780 	 *
  3510 	 * @param array $args Method parameters. Contains:
  3781 	 * @param array $args Method parameters. Contains:
  3511 	 *  - int     $blog_id
  3782 	 *  - int     $blog_id (unused)
  3512 	 *  - string  $username
  3783 	 *  - string  $username
  3513 	 *  - string  $password
  3784 	 *  - string  $password
  3514 	 *  - int     $post_id
  3785 	 *  - int     $post_id
  3515 	 *  - array   $fields
  3786 	 *  - array   $fields
  3516 	 * @return array contains a collection of posts.
  3787 	 * @return array|IXR_Error contains a collection of posts.
  3517 	 */
  3788 	 */
  3518 	function wp_getRevisions( $args ) {
  3789 	public function wp_getRevisions( $args ) {
  3519 		if ( ! $this->minimum_args( $args, 4 ) )
  3790 		if ( ! $this->minimum_args( $args, 4 ) )
  3520 			return $this->error;
  3791 			return $this->error;
  3521 
  3792 
  3522 		$this->escape( $args );
  3793 		$this->escape( $args );
  3523 
  3794 
  3524 		$blog_id    = (int) $args[0];
       
  3525 		$username   = $args[1];
  3795 		$username   = $args[1];
  3526 		$password   = $args[2];
  3796 		$password   = $args[2];
  3527 		$post_id    = (int) $args[3];
  3797 		$post_id    = (int) $args[3];
  3528 
  3798 
  3529 		if ( isset( $args[4] ) )
  3799 		if ( isset( $args[4] ) ) {
  3530 			$fields = $args[4];
  3800 			$fields = $args[4];
  3531 		else
  3801 		} else {
       
  3802 			/**
       
  3803 			 * Filter the default revision query fields used by the given XML-RPC method.
       
  3804 			 *
       
  3805 			 * @since 3.5.0
       
  3806 			 *
       
  3807 			 * @param array  $field  An array of revision query fields.
       
  3808 			 * @param string $method The method name.
       
  3809 			 */
  3532 			$fields = apply_filters( 'xmlrpc_default_revision_fields', array( 'post_date', 'post_date_gmt' ), 'wp.getRevisions' );
  3810 			$fields = apply_filters( 'xmlrpc_default_revision_fields', array( 'post_date', 'post_date_gmt' ), 'wp.getRevisions' );
       
  3811 		}
  3533 
  3812 
  3534 		if ( ! $user = $this->login( $username, $password ) )
  3813 		if ( ! $user = $this->login( $username, $password ) )
  3535 			return $this->error;
  3814 			return $this->error;
  3536 
  3815 
       
  3816 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3537 		do_action( 'xmlrpc_call', 'wp.getRevisions' );
  3817 		do_action( 'xmlrpc_call', 'wp.getRevisions' );
  3538 
  3818 
  3539 		if ( ! $post = get_post( $post_id ) )
  3819 		if ( ! $post = get_post( $post_id ) )
  3540 			return new IXR_Error( 404, __( 'Invalid post ID' ) );
  3820 			return new IXR_Error( 404, __( 'Invalid post ID' ) );
  3541 
  3821 
  3573 	 * @since 3.5.0
  3853 	 * @since 3.5.0
  3574 	 *
  3854 	 *
  3575 	 * @uses wp_restore_post_revision()
  3855 	 * @uses wp_restore_post_revision()
  3576 	 *
  3856 	 *
  3577 	 * @param array $args Method parameters. Contains:
  3857 	 * @param array $args Method parameters. Contains:
  3578 	 *  - int     $blog_id
  3858 	 *  - int     $blog_id (unused)
  3579 	 *  - string  $username
  3859 	 *  - string  $username
  3580 	 *  - string  $password
  3860 	 *  - string  $password
  3581 	 *  - int     $post_id
  3861 	 *  - int     $post_id
  3582 	 * @return bool false if there was an error restoring, true if success.
  3862 	 * @return bool|IXR_Error false if there was an error restoring, true if success.
  3583 	 */
  3863 	 */
  3584 	function wp_restoreRevision( $args ) {
  3864 	public function wp_restoreRevision( $args ) {
  3585 		if ( ! $this->minimum_args( $args, 3 ) )
  3865 		if ( ! $this->minimum_args( $args, 3 ) )
  3586 			return $this->error;
  3866 			return $this->error;
  3587 
  3867 
  3588 		$this->escape( $args );
  3868 		$this->escape( $args );
  3589 
  3869 
  3590 		$blog_id     = (int) $args[0];
       
  3591 		$username    = $args[1];
  3870 		$username    = $args[1];
  3592 		$password    = $args[2];
  3871 		$password    = $args[2];
  3593 		$revision_id = (int) $args[3];
  3872 		$revision_id = (int) $args[3];
  3594 
  3873 
  3595 		if ( ! $user = $this->login( $username, $password ) )
  3874 		if ( ! $user = $this->login( $username, $password ) )
  3596 			return $this->error;
  3875 			return $this->error;
  3597 
  3876 
       
  3877 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3598 		do_action( 'xmlrpc_call', 'wp.restoreRevision' );
  3878 		do_action( 'xmlrpc_call', 'wp.restoreRevision' );
  3599 
  3879 
  3600 		if ( ! $revision = wp_get_post_revision( $revision_id ) )
  3880 		if ( ! $revision = wp_get_post_revision( $revision_id ) )
  3601 			return new IXR_Error( 404, __( 'Invalid post ID' ) );
  3881 			return new IXR_Error( 404, __( 'Invalid post ID' ) );
  3602 
  3882 
  3628 	 * Will make more sense once we support multiple blogs.
  3908 	 * Will make more sense once we support multiple blogs.
  3629 	 *
  3909 	 *
  3630 	 * @since 1.5.0
  3910 	 * @since 1.5.0
  3631 	 *
  3911 	 *
  3632 	 * @param array $args Method parameters.
  3912 	 * @param array $args Method parameters.
  3633 	 * @return array
  3913 	 * @return array|IXR_Error
  3634 	 */
  3914 	 */
  3635 	function blogger_getUsersBlogs($args) {
  3915 	public function blogger_getUsersBlogs($args) {
  3636 		if ( is_multisite() )
  3916 		if ( is_multisite() )
  3637 			return $this->_multisite_getUsersBlogs($args);
  3917 			return $this->_multisite_getUsersBlogs($args);
  3638 
  3918 
  3639 		$this->escape($args);
  3919 		$this->escape($args);
  3640 
  3920 
  3642 		$password  = $args[2];
  3922 		$password  = $args[2];
  3643 
  3923 
  3644 		if ( !$user = $this->login($username, $password) )
  3924 		if ( !$user = $this->login($username, $password) )
  3645 			return $this->error;
  3925 			return $this->error;
  3646 
  3926 
  3647 		do_action('xmlrpc_call', 'blogger.getUsersBlogs');
  3927 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  3928 		do_action( 'xmlrpc_call', 'blogger.getUsersBlogs' );
  3648 
  3929 
  3649 		$is_admin = current_user_can('manage_options');
  3930 		$is_admin = current_user_can('manage_options');
  3650 
  3931 
  3651 		$struct = array(
  3932 		$struct = array(
  3652 			'isAdmin'  => $is_admin,
  3933 			'isAdmin'  => $is_admin,
  3661 
  3942 
  3662 	/**
  3943 	/**
  3663 	 * Private function for retrieving a users blogs for multisite setups
  3944 	 * Private function for retrieving a users blogs for multisite setups
  3664 	 *
  3945 	 *
  3665 	 * @access protected
  3946 	 * @access protected
  3666 	 */
  3947 	 *
  3667 	function _multisite_getUsersBlogs($args) {
  3948 	 * @return array|IXR_Error
       
  3949 	 */
       
  3950 	protected function _multisite_getUsersBlogs($args) {
  3668 		$current_blog = get_blog_details();
  3951 		$current_blog = get_blog_details();
  3669 
  3952 
  3670 		$domain = $current_blog->domain;
  3953 		$domain = $current_blog->domain;
  3671 		$path = $current_blog->path . 'xmlrpc.php';
  3954 		$path = $current_blog->path . 'xmlrpc.php';
  3672 
  3955 
  3694 	 * Gives your client some info about you, so you don't have to.
  3977 	 * Gives your client some info about you, so you don't have to.
  3695 	 *
  3978 	 *
  3696 	 * @since 1.5.0
  3979 	 * @since 1.5.0
  3697 	 *
  3980 	 *
  3698 	 * @param array $args Method parameters.
  3981 	 * @param array $args Method parameters.
  3699 	 * @return array
  3982 	 * @return array|IXR_Error
  3700 	 */
  3983 	 */
  3701 	function blogger_getUserInfo($args) {
  3984 	public function blogger_getUserInfo($args) {
  3702 
  3985 
  3703 		$this->escape($args);
  3986 		$this->escape($args);
  3704 
  3987 
  3705 		$username = $args[1];
  3988 		$username = $args[1];
  3706 		$password  = $args[2];
  3989 		$password  = $args[2];
  3709 			return $this->error;
  3992 			return $this->error;
  3710 
  3993 
  3711 		if ( !current_user_can( 'edit_posts' ) )
  3994 		if ( !current_user_can( 'edit_posts' ) )
  3712 			return new IXR_Error( 401, __( 'Sorry, you do not have access to user data on this site.' ) );
  3995 			return new IXR_Error( 401, __( 'Sorry, you do not have access to user data on this site.' ) );
  3713 
  3996 
  3714 		do_action('xmlrpc_call', 'blogger.getUserInfo');
  3997 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  3998 		do_action( 'xmlrpc_call', 'blogger.getUserInfo' );
  3715 
  3999 
  3716 		$struct = array(
  4000 		$struct = array(
  3717 			'nickname'  => $user->nickname,
  4001 			'nickname'  => $user->nickname,
  3718 			'userid'    => $user->ID,
  4002 			'userid'    => $user->ID,
  3719 			'url'       => $user->user_url,
  4003 			'url'       => $user->user_url,
  3728 	 * Retrieve post.
  4012 	 * Retrieve post.
  3729 	 *
  4013 	 *
  3730 	 * @since 1.5.0
  4014 	 * @since 1.5.0
  3731 	 *
  4015 	 *
  3732 	 * @param array $args Method parameters.
  4016 	 * @param array $args Method parameters.
  3733 	 * @return array
  4017 	 * @return array|IXR_Error
  3734 	 */
  4018 	 */
  3735 	function blogger_getPost($args) {
  4019 	public function blogger_getPost($args) {
  3736 
  4020 
  3737 		$this->escape($args);
  4021 		$this->escape($args);
  3738 
  4022 
  3739 		$post_ID    = (int) $args[1];
  4023 		$post_ID    = (int) $args[1];
  3740 		$username = $args[2];
  4024 		$username = $args[2];
  3748 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  4032 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  3749 
  4033 
  3750 		if ( !current_user_can( 'edit_post', $post_ID ) )
  4034 		if ( !current_user_can( 'edit_post', $post_ID ) )
  3751 			return new IXR_Error( 401, __( 'Sorry, you cannot edit this post.' ) );
  4035 			return new IXR_Error( 401, __( 'Sorry, you cannot edit this post.' ) );
  3752 
  4036 
  3753 		do_action('xmlrpc_call', 'blogger.getPost');
  4037 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  4038 		do_action( 'xmlrpc_call', 'blogger.getPost' );
  3754 
  4039 
  3755 		$categories = implode(',', wp_get_post_categories($post_ID));
  4040 		$categories = implode(',', wp_get_post_categories($post_ID));
  3756 
  4041 
  3757 		$content  = '<title>'.wp_unslash($post_data['post_title']).'</title>';
  4042 		$content  = '<title>'.wp_unslash($post_data['post_title']).'</title>';
  3758 		$content .= '<category>'.$categories.'</category>';
  4043 		$content .= '<category>'.$categories.'</category>';
  3772 	 * Retrieve list of recent posts.
  4057 	 * Retrieve list of recent posts.
  3773 	 *
  4058 	 *
  3774 	 * @since 1.5.0
  4059 	 * @since 1.5.0
  3775 	 *
  4060 	 *
  3776 	 * @param array $args Method parameters.
  4061 	 * @param array $args Method parameters.
  3777 	 * @return array
  4062 	 * @return array|IXR_Error
  3778 	 */
  4063 	 */
  3779 	function blogger_getRecentPosts($args) {
  4064 	public function blogger_getRecentPosts($args) {
  3780 
  4065 
  3781 		$this->escape($args);
  4066 		$this->escape($args);
  3782 
  4067 
  3783 		// $args[0] = appkey - ignored
  4068 		// $args[0] = appkey - ignored
  3784 		$blog_ID    = (int) $args[1]; /* though we don't use it yet */
       
  3785 		$username = $args[2];
  4069 		$username = $args[2];
  3786 		$password  = $args[3];
  4070 		$password  = $args[3];
  3787 		if ( isset( $args[4] ) )
  4071 		if ( isset( $args[4] ) )
  3788 			$query = array( 'numberposts' => absint( $args[4] ) );
  4072 			$query = array( 'numberposts' => absint( $args[4] ) );
  3789 		else
  4073 		else
  3793 			return $this->error;
  4077 			return $this->error;
  3794 
  4078 
  3795 		if ( ! current_user_can( 'edit_posts' ) )
  4079 		if ( ! current_user_can( 'edit_posts' ) )
  3796 			return new IXR_Error( 401, __( 'Sorry, you cannot edit posts on this site.' ) );
  4080 			return new IXR_Error( 401, __( 'Sorry, you cannot edit posts on this site.' ) );
  3797 
  4081 
  3798 		do_action('xmlrpc_call', 'blogger.getRecentPosts');
  4082 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  4083 		do_action( 'xmlrpc_call', 'blogger.getRecentPosts' );
  3799 
  4084 
  3800 		$posts_list = wp_get_recent_posts( $query );
  4085 		$posts_list = wp_get_recent_posts( $query );
  3801 
  4086 
  3802 		if ( !$posts_list ) {
  4087 		if ( !$posts_list ) {
  3803 			$this->error = new IXR_Error(500, __('Either there are no posts, or something went wrong.'));
  4088 			$this->error = new IXR_Error(500, __('Either there are no posts, or something went wrong.'));
  3804 			return $this->error;
  4089 			return $this->error;
  3805 		}
  4090 		}
  3806 
  4091 
       
  4092 		$recent_posts = array();
  3807 		foreach ($posts_list as $entry) {
  4093 		foreach ($posts_list as $entry) {
  3808 			if ( !current_user_can( 'edit_post', $entry['ID'] ) )
  4094 			if ( !current_user_can( 'edit_post', $entry['ID'] ) )
  3809 				continue;
  4095 				continue;
  3810 
  4096 
  3811 			$post_date  = $this->_convert_date( $entry['post_date'] );
  4097 			$post_date  = $this->_convert_date( $entry['post_date'] );
  3813 
  4099 
  3814 			$content  = '<title>'.wp_unslash($entry['post_title']).'</title>';
  4100 			$content  = '<title>'.wp_unslash($entry['post_title']).'</title>';
  3815 			$content .= '<category>'.$categories.'</category>';
  4101 			$content .= '<category>'.$categories.'</category>';
  3816 			$content .= wp_unslash($entry['post_content']);
  4102 			$content .= wp_unslash($entry['post_content']);
  3817 
  4103 
  3818 			$struct[] = array(
  4104 			$recent_posts[] = array(
  3819 				'userid' => $entry['post_author'],
  4105 				'userid' => $entry['post_author'],
  3820 				'dateCreated' => $post_date,
  4106 				'dateCreated' => $post_date,
  3821 				'content' => $content,
  4107 				'content' => $content,
  3822 				'postid' => (string) $entry['ID'],
  4108 				'postid' => (string) $entry['ID'],
  3823 			);
  4109 			);
  3824 
       
  3825 		}
       
  3826 
       
  3827 		$recent_posts = array();
       
  3828 		for ( $j=0; $j<count($struct); $j++ ) {
       
  3829 			array_push($recent_posts, $struct[$j]);
       
  3830 		}
  4110 		}
  3831 
  4111 
  3832 		return $recent_posts;
  4112 		return $recent_posts;
  3833 	}
  4113 	}
  3834 
  4114 
  3835 	/**
  4115 	/**
  3836 	 * Deprecated.
  4116 	 * Deprecated.
  3837 	 *
  4117 	 *
  3838 	 * @since 1.5.0
  4118 	 * @since 1.5.0
  3839 	 * @deprecated 3.5.0
  4119 	 * @deprecated 3.5.0
  3840 	 */
  4120 	 * @return IXR_Error
  3841 	function blogger_getTemplate($args) {
  4121 	 */
       
  4122 	public function blogger_getTemplate($args) {
  3842 		return new IXR_Error( 403, __('Sorry, that file cannot be edited.' ) );
  4123 		return new IXR_Error( 403, __('Sorry, that file cannot be edited.' ) );
  3843 	}
  4124 	}
  3844 
  4125 
  3845 	/**
  4126 	/**
  3846 	 * Deprecated.
  4127 	 * Deprecated.
  3847 	 *
  4128 	 *
  3848 	 * @since 1.5.0
  4129 	 * @since 1.5.0
  3849 	 * @deprecated 3.5.0
  4130 	 * @deprecated 3.5.0
  3850 	 */
  4131 	 * @return IXR_Error
  3851 	function blogger_setTemplate($args) {
  4132 	 */
       
  4133 	public function blogger_setTemplate($args) {
  3852 		return new IXR_Error( 403, __('Sorry, that file cannot be edited.' ) );
  4134 		return new IXR_Error( 403, __('Sorry, that file cannot be edited.' ) );
  3853 	}
  4135 	}
  3854 
  4136 
  3855 	/**
  4137 	/**
  3856 	 * Create new post.
  4138 	 * Create new post.
  3857 	 *
  4139 	 *
  3858 	 * @since 1.5.0
  4140 	 * @since 1.5.0
  3859 	 *
  4141 	 *
  3860 	 * @param array $args Method parameters.
  4142 	 * @param array $args Method parameters.
  3861 	 * @return int
  4143 	 * @return int|IXR_Error
  3862 	 */
  4144 	 */
  3863 	function blogger_newPost($args) {
  4145 	public function blogger_newPost($args) {
  3864 
  4146 
  3865 		$this->escape($args);
  4147 		$this->escape($args);
  3866 
  4148 
  3867 		$blog_ID    = (int) $args[1]; /* though we don't use it yet */
       
  3868 		$username = $args[2];
  4149 		$username = $args[2];
  3869 		$password  = $args[3];
  4150 		$password  = $args[3];
  3870 		$content    = $args[4];
  4151 		$content    = $args[4];
  3871 		$publish    = $args[5];
  4152 		$publish    = $args[5];
  3872 
  4153 
  3873 		if ( !$user = $this->login($username, $password) )
  4154 		if ( !$user = $this->login($username, $password) )
  3874 			return $this->error;
  4155 			return $this->error;
  3875 
  4156 
  3876 		do_action('xmlrpc_call', 'blogger.newPost');
  4157 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  4158 		do_action( 'xmlrpc_call', 'blogger.newPost' );
  3877 
  4159 
  3878 		$cap = ($publish) ? 'publish_posts' : 'edit_posts';
  4160 		$cap = ($publish) ? 'publish_posts' : 'edit_posts';
  3879 		if ( ! current_user_can( get_post_type_object( 'post' )->cap->create_posts ) || !current_user_can($cap) )
  4161 		if ( ! current_user_can( get_post_type_object( 'post' )->cap->create_posts ) || !current_user_can($cap) )
  3880 			return new IXR_Error(401, __('Sorry, you are not allowed to post on this site.'));
  4162 			return new IXR_Error(401, __('Sorry, you are not allowed to post on this site.'));
  3881 
  4163 
  3888 		$post_content = xmlrpc_removepostdata($content);
  4170 		$post_content = xmlrpc_removepostdata($content);
  3889 
  4171 
  3890 		$post_date = current_time('mysql');
  4172 		$post_date = current_time('mysql');
  3891 		$post_date_gmt = current_time('mysql', 1);
  4173 		$post_date_gmt = current_time('mysql', 1);
  3892 
  4174 
  3893 		$post_data = compact('blog_ID', 'post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_title', 'post_category', 'post_status');
  4175 		$post_data = compact('post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_title', 'post_category', 'post_status');
  3894 
  4176 
  3895 		$post_ID = wp_insert_post($post_data);
  4177 		$post_ID = wp_insert_post($post_data);
  3896 		if ( is_wp_error( $post_ID ) )
  4178 		if ( is_wp_error( $post_ID ) )
  3897 			return new IXR_Error(500, $post_ID->get_error_message());
  4179 			return new IXR_Error(500, $post_ID->get_error_message());
  3898 
  4180 
  3899 		if ( !$post_ID )
  4181 		if ( !$post_ID )
  3900 			return new IXR_Error(500, __('Sorry, your entry could not be posted. Something wrong happened.'));
  4182 			return new IXR_Error(500, __('Sorry, your entry could not be posted. Something wrong happened.'));
  3901 
  4183 
  3902 		$this->attach_uploads( $post_ID, $post_content );
  4184 		$this->attach_uploads( $post_ID, $post_content );
  3903 
  4185 
       
  4186 		/**
       
  4187 		 * Fires after a new post has been successfully created via the XML-RPC Blogger API.
       
  4188 		 *
       
  4189 		 * @since 3.4.0
       
  4190 		 *
       
  4191 		 * @param int   $post_ID ID of the new post.
       
  4192 		 * @param array $args    An array of new post arguments.
       
  4193 		 */
  3904 		do_action( 'xmlrpc_call_success_blogger_newPost', $post_ID, $args );
  4194 		do_action( 'xmlrpc_call_success_blogger_newPost', $post_ID, $args );
  3905 
  4195 
  3906 		return $post_ID;
  4196 		return $post_ID;
  3907 	}
  4197 	}
  3908 
  4198 
  3910 	 * Edit a post.
  4200 	 * Edit a post.
  3911 	 *
  4201 	 *
  3912 	 * @since 1.5.0
  4202 	 * @since 1.5.0
  3913 	 *
  4203 	 *
  3914 	 * @param array $args Method parameters.
  4204 	 * @param array $args Method parameters.
  3915 	 * @return bool true when done.
  4205 	 * @return bool|IXR_Error true when done.
  3916 	 */
  4206 	 */
  3917 	function blogger_editPost($args) {
  4207 	public function blogger_editPost( $args ) {
  3918 
  4208 
  3919 		$this->escape($args);
  4209 		$this->escape($args);
  3920 
  4210 
  3921 		$post_ID     = (int) $args[1];
  4211 		$post_ID     = (int) $args[1];
  3922 		$username  = $args[2];
  4212 		$username  = $args[2];
  3923 		$password   = $args[3];
  4213 		$password   = $args[3];
  3924 		$content     = $args[4];
  4214 		$content     = $args[4];
  3925 		$publish     = $args[5];
  4215 
  3926 
  4216 		if ( ! $user = $this->login( $username, $password ) ) {
  3927 		if ( !$user = $this->login($username, $password) )
  4217 			return $this->error;
  3928 			return $this->error;
  4218 		}
  3929 
  4219 
  3930 		do_action('xmlrpc_call', 'blogger.editPost');
  4220 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3931 
  4221 		do_action( 'xmlrpc_call', 'blogger.editPost' );
  3932 		$actual_post = get_post($post_ID,ARRAY_A);
  4222 
  3933 
  4223 		$actual_post = get_post( $post_ID, ARRAY_A );
  3934 		if ( !$actual_post || $actual_post['post_type'] != 'post' )
  4224 
  3935 			return new IXR_Error(404, __('Sorry, no such post.'));
  4225 		if ( ! $actual_post || $actual_post['post_type'] != 'post' ) {
       
  4226 			return new IXR_Error( 404, __( 'Sorry, no such post.' ) );
       
  4227 		}
  3936 
  4228 
  3937 		$this->escape($actual_post);
  4229 		$this->escape($actual_post);
  3938 
  4230 
  3939 		if ( !current_user_can('edit_post', $post_ID) )
  4231 		if ( ! current_user_can( 'edit_post', $post_ID ) ) {
  3940 			return new IXR_Error(401, __('Sorry, you do not have the right to edit this post.'));
  4232 			return new IXR_Error(401, __('Sorry, you do not have the right to edit this post.'));
  3941 
  4233 		}
  3942 		extract($actual_post, EXTR_SKIP);
  4234 		if ( 'publish' == $actual_post['post_status'] && ! current_user_can( 'publish_posts' ) ) {
  3943 
  4235 			return new IXR_Error( 401, __( 'Sorry, you do not have the right to publish this post.' ) );
  3944 		if ( ('publish' == $post_status) && !current_user_can('publish_posts') )
  4236 		}
  3945 			return new IXR_Error(401, __('Sorry, you do not have the right to publish this post.'));
  4237 
  3946 
  4238 		$postdata = array();
  3947 		$post_title = xmlrpc_getposttitle($content);
  4239 		$postdata['ID'] = $actual_post['ID'];
  3948 		$post_category = xmlrpc_getpostcategory($content);
  4240 		$postdata['post_content'] = xmlrpc_removepostdata( $content );
  3949 		$post_content = xmlrpc_removepostdata($content);
  4241 		$postdata['post_title'] = xmlrpc_getposttitle( $content );
  3950 
  4242 		$postdata['post_category'] = xmlrpc_getpostcategory( $content );
  3951 		$postdata = compact('ID', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt');
  4243 		$postdata['post_status'] = $actual_post['post_status'];
  3952 
  4244 		$postdata['post_excerpt'] = $actual_post['post_excerpt'];
  3953 		$result = wp_update_post($postdata);
  4245 
  3954 
  4246 		$result = wp_update_post( $postdata );
  3955 		if ( !$result )
  4247 
       
  4248 		if ( ! $result ) {
  3956 			return new IXR_Error(500, __('For some strange yet very annoying reason, this post could not be edited.'));
  4249 			return new IXR_Error(500, __('For some strange yet very annoying reason, this post could not be edited.'));
  3957 
  4250 		}
  3958 		$this->attach_uploads( $ID, $post_content );
  4251 		$this->attach_uploads( $actual_post['ID'], $postdata['post_content'] );
  3959 
  4252 
       
  4253 		/**
       
  4254 		 * Fires after a post has been successfully updated via the XML-RPC Blogger API.
       
  4255 		 *
       
  4256 		 * @since 3.4.0
       
  4257 		 *
       
  4258 		 * @param int   $post_ID ID of the updated post.
       
  4259 		 * @param array $args    An array of arguments for the post to edit.
       
  4260 		 */
  3960 		do_action( 'xmlrpc_call_success_blogger_editPost', $post_ID, $args );
  4261 		do_action( 'xmlrpc_call_success_blogger_editPost', $post_ID, $args );
  3961 
  4262 
  3962 		return true;
  4263 		return true;
  3963 	}
  4264 	}
  3964 
  4265 
  3966 	 * Remove a post.
  4267 	 * Remove a post.
  3967 	 *
  4268 	 *
  3968 	 * @since 1.5.0
  4269 	 * @since 1.5.0
  3969 	 *
  4270 	 *
  3970 	 * @param array $args Method parameters.
  4271 	 * @param array $args Method parameters.
  3971 	 * @return bool True when post is deleted.
  4272 	 * @return bool|IXR_Error True when post is deleted.
  3972 	 */
  4273 	 */
  3973 	function blogger_deletePost($args) {
  4274 	public function blogger_deletePost($args) {
  3974 		$this->escape($args);
  4275 		$this->escape($args);
  3975 
  4276 
  3976 		$post_ID     = (int) $args[1];
  4277 		$post_ID     = (int) $args[1];
  3977 		$username  = $args[2];
  4278 		$username  = $args[2];
  3978 		$password   = $args[3];
  4279 		$password   = $args[3];
  3979 		$publish     = $args[4];
       
  3980 
  4280 
  3981 		if ( !$user = $this->login($username, $password) )
  4281 		if ( !$user = $this->login($username, $password) )
  3982 			return $this->error;
  4282 			return $this->error;
  3983 
  4283 
  3984 		do_action('xmlrpc_call', 'blogger.deletePost');
  4284 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  4285 		do_action( 'xmlrpc_call', 'blogger.deletePost' );
  3985 
  4286 
  3986 		$actual_post = get_post($post_ID,ARRAY_A);
  4287 		$actual_post = get_post($post_ID,ARRAY_A);
  3987 
  4288 
  3988 		if ( !$actual_post || $actual_post['post_type'] != 'post' )
  4289 		if ( !$actual_post || $actual_post['post_type'] != 'post' )
  3989 			return new IXR_Error(404, __('Sorry, no such post.'));
  4290 			return new IXR_Error(404, __('Sorry, no such post.'));
  3994 		$result = wp_delete_post($post_ID);
  4295 		$result = wp_delete_post($post_ID);
  3995 
  4296 
  3996 		if ( !$result )
  4297 		if ( !$result )
  3997 			return new IXR_Error(500, __('For some strange yet very annoying reason, this post could not be deleted.'));
  4298 			return new IXR_Error(500, __('For some strange yet very annoying reason, this post could not be deleted.'));
  3998 
  4299 
       
  4300 		/**
       
  4301 		 * Fires after a post has been successfully deleted via the XML-RPC Blogger API.
       
  4302 		 *
       
  4303 		 * @since 3.4.0
       
  4304 		 *
       
  4305 		 * @param int   $post_ID ID of the deleted post.
       
  4306 		 * @param array $args    An array of arguments to delete the post.
       
  4307 		 */
  3999 		do_action( 'xmlrpc_call_success_blogger_deletePost', $post_ID, $args );
  4308 		do_action( 'xmlrpc_call_success_blogger_deletePost', $post_ID, $args );
  4000 
  4309 
  4001 		return true;
  4310 		return true;
  4002 	}
  4311 	}
  4003 
  4312 
  4031 	 *  - wp_post_thumbnail
  4340 	 *  - wp_post_thumbnail
  4032 	 *
  4341 	 *
  4033 	 * @since 1.5.0
  4342 	 * @since 1.5.0
  4034 	 *
  4343 	 *
  4035 	 * @param array $args Method parameters. Contains:
  4344 	 * @param array $args Method parameters. Contains:
  4036 	 *  - blog_id
  4345 	 *  - blog_id (unused)
  4037 	 *  - username
  4346 	 *  - username
  4038 	 *  - password
  4347 	 *  - password
  4039 	 *  - content_struct
  4348 	 *  - content_struct
  4040 	 *  - publish
  4349 	 *  - publish
  4041 	 * @return int
  4350 	 * @return int|IXR_Error
  4042 	 */
  4351 	 */
  4043 	function mw_newPost($args) {
  4352 	public function mw_newPost($args) {
  4044 		$this->escape($args);
  4353 		$this->escape($args);
  4045 
  4354 
  4046 		$blog_ID     = (int) $args[0];
       
  4047 		$username  = $args[1];
  4355 		$username  = $args[1];
  4048 		$password   = $args[2];
  4356 		$password   = $args[2];
  4049 		$content_struct = $args[3];
  4357 		$content_struct = $args[3];
  4050 		$publish     = isset( $args[4] ) ? $args[4] : 0;
  4358 		$publish     = isset( $args[4] ) ? $args[4] : 0;
  4051 
  4359 
  4052 		if ( !$user = $this->login($username, $password) )
  4360 		if ( !$user = $this->login($username, $password) )
  4053 			return $this->error;
  4361 			return $this->error;
  4054 
  4362 
  4055 		do_action('xmlrpc_call', 'metaWeblog.newPost');
  4363 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  4364 		do_action( 'xmlrpc_call', 'metaWeblog.newPost' );
  4056 
  4365 
  4057 		$page_template = '';
  4366 		$page_template = '';
  4058 		if ( !empty( $content_struct['post_type'] ) ) {
  4367 		if ( !empty( $content_struct['post_type'] ) ) {
  4059 			if ( $content_struct['post_type'] == 'page' ) {
  4368 			if ( $content_struct['post_type'] == 'page' ) {
  4060 				if ( $publish )
  4369 				if ( $publish )
  4127 		// If an author id was provided then use it instead.
  4436 		// If an author id was provided then use it instead.
  4128 		if ( isset( $content_struct['wp_author_id'] ) && ( $user->ID != $content_struct['wp_author_id'] ) ) {
  4437 		if ( isset( $content_struct['wp_author_id'] ) && ( $user->ID != $content_struct['wp_author_id'] ) ) {
  4129 			switch ( $post_type ) {
  4438 			switch ( $post_type ) {
  4130 				case "post":
  4439 				case "post":
  4131 					if ( !current_user_can( 'edit_others_posts' ) )
  4440 					if ( !current_user_can( 'edit_others_posts' ) )
  4132 						return( new IXR_Error( 401, __( 'You are not allowed to create posts as this user.' ) ) );
  4441 						return new IXR_Error( 401, __( 'You are not allowed to create posts as this user.' ) );
  4133 					break;
  4442 					break;
  4134 				case "page":
  4443 				case "page":
  4135 					if ( !current_user_can( 'edit_others_pages' ) )
  4444 					if ( !current_user_can( 'edit_others_pages' ) )
  4136 						return( new IXR_Error( 401, __( 'You are not allowed to create pages as this user.' ) ) );
  4445 						return new IXR_Error( 401, __( 'You are not allowed to create pages as this user.' ) );
  4137 					break;
  4446 					break;
  4138 				default:
  4447 				default:
  4139 					return( new IXR_Error( 401, __( 'Invalid post type' ) ) );
  4448 					return new IXR_Error( 401, __( 'Invalid post type' ) );
  4140 					break;
       
  4141 			}
  4449 			}
  4142 			$author = get_userdata( $content_struct['wp_author_id'] );
  4450 			$author = get_userdata( $content_struct['wp_author_id'] );
  4143 			if ( ! $author )
  4451 			if ( ! $author )
  4144 				return new IXR_Error( 404, __( 'Invalid author ID.' ) );
  4452 				return new IXR_Error( 404, __( 'Invalid author ID.' ) );
  4145 			$post_author = $content_struct['wp_author_id'];
  4453 			$post_author = $content_struct['wp_author_id'];
  4304 			return new IXR_Error(500, $post_ID->get_error_message());
  4612 			return new IXR_Error(500, $post_ID->get_error_message());
  4305 
  4613 
  4306 		if ( !$post_ID )
  4614 		if ( !$post_ID )
  4307 			return new IXR_Error(500, __('Sorry, your entry could not be posted. Something wrong happened.'));
  4615 			return new IXR_Error(500, __('Sorry, your entry could not be posted. Something wrong happened.'));
  4308 
  4616 
       
  4617 		/**
       
  4618 		 * Fires after a new post has been successfully created via the XML-RPC MovableType API.
       
  4619 		 *
       
  4620 		 * @since 3.4.0
       
  4621 		 *
       
  4622 		 * @param int   $post_ID ID of the new post.
       
  4623 		 * @param array $args    An array of arguments to create the new post.
       
  4624 		 */
  4309 		do_action( 'xmlrpc_call_success_mw_newPost', $post_ID, $args );
  4625 		do_action( 'xmlrpc_call_success_mw_newPost', $post_ID, $args );
  4310 
  4626 
  4311 		return strval($post_ID);
  4627 		return strval($post_ID);
  4312 	}
  4628 	}
  4313 
  4629 
  4314 	function add_enclosure_if_new( $post_ID, $enclosure ) {
  4630 	/**
       
  4631 	 * @param integer $post_ID
       
  4632 	 * @param array   $enclosure
       
  4633 	 */
       
  4634 	public function add_enclosure_if_new( $post_ID, $enclosure ) {
  4315 		if ( is_array( $enclosure ) && isset( $enclosure['url'] ) && isset( $enclosure['length'] ) && isset( $enclosure['type'] ) ) {
  4635 		if ( is_array( $enclosure ) && isset( $enclosure['url'] ) && isset( $enclosure['length'] ) && isset( $enclosure['type'] ) ) {
  4316 			$encstring = $enclosure['url'] . "\n" . $enclosure['length'] . "\n" . $enclosure['type'] . "\n";
  4636 			$encstring = $enclosure['url'] . "\n" . $enclosure['length'] . "\n" . $enclosure['type'] . "\n";
  4317 			$found = false;
  4637 			$found = false;
  4318 			if ( $enclosures = get_post_meta( $post_ID, 'enclosure' ) ) {
  4638 			if ( $enclosures = get_post_meta( $post_ID, 'enclosure' ) ) {
  4319 				foreach ( $enclosures as $enc ) {
  4639 				foreach ( $enclosures as $enc ) {
  4335 	 * @since 2.1.0
  4655 	 * @since 2.1.0
  4336 	 *
  4656 	 *
  4337 	 * @param int $post_ID Post ID.
  4657 	 * @param int $post_ID Post ID.
  4338 	 * @param string $post_content Post Content for attachment.
  4658 	 * @param string $post_content Post Content for attachment.
  4339 	 */
  4659 	 */
  4340 	function attach_uploads( $post_ID, $post_content ) {
  4660 	public function attach_uploads( $post_ID, $post_content ) {
  4341 		global $wpdb;
  4661 		global $wpdb;
  4342 
  4662 
  4343 		// find any unattached files
  4663 		// find any unattached files
  4344 		$attachments = $wpdb->get_results( "SELECT ID, guid FROM {$wpdb->posts} WHERE post_parent = '0' AND post_type = 'attachment'" );
  4664 		$attachments = $wpdb->get_results( "SELECT ID, guid FROM {$wpdb->posts} WHERE post_parent = '0' AND post_type = 'attachment'" );
  4345 		if ( is_array( $attachments ) ) {
  4665 		if ( is_array( $attachments ) ) {
  4354 	 * Edit a post.
  4674 	 * Edit a post.
  4355 	 *
  4675 	 *
  4356 	 * @since 1.5.0
  4676 	 * @since 1.5.0
  4357 	 *
  4677 	 *
  4358 	 * @param array $args Method parameters.
  4678 	 * @param array $args Method parameters.
  4359 	 * @return bool True on success.
  4679 	 * @return bool|IXR_Error True on success.
  4360 	 */
  4680 	 */
  4361 	function mw_editPost($args) {
  4681 	public function mw_editPost($args) {
  4362 
  4682 
  4363 		$this->escape($args);
  4683 		$this->escape($args);
  4364 
  4684 
  4365 		$post_ID        = (int) $args[0];
  4685 		$post_ID        = (int) $args[0];
  4366 		$username       = $args[1];
  4686 		$username       = $args[1];
  4369 		$publish        = isset( $args[4] ) ? $args[4] : 0;
  4689 		$publish        = isset( $args[4] ) ? $args[4] : 0;
  4370 
  4690 
  4371 		if ( ! $user = $this->login($username, $password) )
  4691 		if ( ! $user = $this->login($username, $password) )
  4372 			return $this->error;
  4692 			return $this->error;
  4373 
  4693 
  4374 		do_action('xmlrpc_call', 'metaWeblog.editPost');
  4694 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  4695 		do_action( 'xmlrpc_call', 'metaWeblog.editPost' );
  4375 
  4696 
  4376 		$postdata = get_post( $post_ID, ARRAY_A );
  4697 		$postdata = get_post( $post_ID, ARRAY_A );
  4377 
  4698 
  4378 		// If there is no post data for the give post id, stop
  4699 		// If there is no post data for the give post id, stop
  4379 		// now and return an error. Other wise a new post will be
  4700 		// now and return an error. Other wise a new post will be
  4399 				return new IXR_Error( 404, __( 'Invalid post format' ) );
  4720 				return new IXR_Error( 404, __( 'Invalid post format' ) );
  4400 			}
  4721 			}
  4401 		}
  4722 		}
  4402 
  4723 
  4403 		$this->escape($postdata);
  4724 		$this->escape($postdata);
  4404 		extract($postdata, EXTR_SKIP);
  4725 
       
  4726 		$ID = $postdata['ID'];
       
  4727 		$post_content = $postdata['post_content'];
       
  4728 		$post_title = $postdata['post_title'];
       
  4729 		$post_excerpt = $postdata['post_excerpt'];
       
  4730 		$post_password = $postdata['post_password'];
       
  4731 		$post_parent = $postdata['post_parent'];
       
  4732 		$post_type = $postdata['post_type'];
       
  4733 		$menu_order = $postdata['menu_order'];
  4405 
  4734 
  4406 		// Let WordPress manage slug if none was provided.
  4735 		// Let WordPress manage slug if none was provided.
  4407 		$post_name = "";
       
  4408 		$post_name = $postdata['post_name'];
  4736 		$post_name = $postdata['post_name'];
  4409 		if ( isset($content_struct['wp_slug']) )
  4737 		if ( isset($content_struct['wp_slug']) )
  4410 			$post_name = $content_struct['wp_slug'];
  4738 			$post_name = $content_struct['wp_slug'];
  4411 
  4739 
  4412 		// Only use a password if one was given.
  4740 		// Only use a password if one was given.
  4419 
  4747 
  4420 		// Only set the menu_order if it was given.
  4748 		// Only set the menu_order if it was given.
  4421 		if ( isset($content_struct['wp_page_order']) )
  4749 		if ( isset($content_struct['wp_page_order']) )
  4422 			$menu_order = $content_struct['wp_page_order'];
  4750 			$menu_order = $content_struct['wp_page_order'];
  4423 
  4751 
       
  4752 		$page_template = null;
  4424 		if ( ! empty( $content_struct['wp_page_template'] ) && 'page' == $post_type )
  4753 		if ( ! empty( $content_struct['wp_page_template'] ) && 'page' == $post_type )
  4425 			$page_template = $content_struct['wp_page_template'];
  4754 			$page_template = $content_struct['wp_page_template'];
  4426 
  4755 
  4427 		$post_author = $postdata['post_author'];
  4756 		$post_author = $postdata['post_author'];
  4428 
  4757 
  4429 		// Only set the post_author if one is set.
  4758 		// Only set the post_author if one is set.
  4430 		if ( isset($content_struct['wp_author_id']) && ($user->ID != $content_struct['wp_author_id']) ) {
  4759 		if ( isset( $content_struct['wp_author_id'] ) ) {
  4431 			switch ( $post_type ) {
  4760 			// Check permissions if attempting to switch author to or from another user.
  4432 				case 'post':
  4761 			if ( $user->ID != $content_struct['wp_author_id'] || $user->ID != $post_author ) {
  4433 					if ( !current_user_can('edit_others_posts') )
  4762 				switch ( $post_type ) {
  4434 						return(new IXR_Error(401, __('You are not allowed to change the post author as this user.')));
  4763 					case 'post':
  4435 					break;
  4764 						if ( ! current_user_can( 'edit_others_posts' ) ) {
  4436 				case 'page':
  4765 							return new IXR_Error( 401, __( 'You are not allowed to change the post author as this user.' ) );
  4437 					if ( !current_user_can('edit_others_pages') )
  4766 						}
  4438 						return(new IXR_Error(401, __('You are not allowed to change the page author as this user.')));
  4767 						break;
  4439 					break;
  4768 					case 'page':
  4440 				default:
  4769 						if ( ! current_user_can( 'edit_others_pages' ) ) {
  4441 					return(new IXR_Error(401, __('Invalid post type')));
  4770 							return new IXR_Error( 401, __( 'You are not allowed to change the page author as this user.' ) );
  4442 					break;
  4771 						}
       
  4772 						break;
       
  4773 					default:
       
  4774 						return new IXR_Error( 401, __( 'Invalid post type' ) );
       
  4775 						break;
       
  4776 				}
       
  4777 				$post_author = $content_struct['wp_author_id'];
  4443 			}
  4778 			}
  4444 			$post_author = $content_struct['wp_author_id'];
       
  4445 		}
  4779 		}
  4446 
  4780 
  4447 		if ( isset($content_struct['mt_allow_comments']) ) {
  4781 		if ( isset($content_struct['mt_allow_comments']) ) {
  4448 			if ( !is_numeric($content_struct['mt_allow_comments']) ) {
  4782 			if ( !is_numeric($content_struct['mt_allow_comments']) ) {
  4449 				switch ( $content_struct['mt_allow_comments'] ) {
  4783 				switch ( $content_struct['mt_allow_comments'] ) {
  4538 		}
  4872 		}
  4539 
  4873 
  4540 		$tags_input = isset( $content_struct['mt_keywords'] ) ? $content_struct['mt_keywords'] : null;
  4874 		$tags_input = isset( $content_struct['mt_keywords'] ) ? $content_struct['mt_keywords'] : null;
  4541 
  4875 
  4542 		if ( ('publish' == $post_status) ) {
  4876 		if ( ('publish' == $post_status) ) {
  4543 			if ( ( 'page' == $post_type ) && !current_user_can('publish_pages') )
  4877 			if ( ( 'page' == $post_type ) && ! current_user_can( 'publish_pages' ) ) {
  4544 				return new IXR_Error(401, __('Sorry, you do not have the right to publish this page.'));
  4878 				return new IXR_Error( 401, __( 'Sorry, you do not have the right to publish this page.' ) );
  4545 			else if ( !current_user_can('publish_posts') )
  4879 			} elseif ( ! current_user_can( 'publish_posts' ) ) {
  4546 				return new IXR_Error(401, __('Sorry, you do not have the right to publish this post.'));
  4880 				return new IXR_Error( 401, __( 'Sorry, you do not have the right to publish this post.' ) );
       
  4881 			}
  4547 		}
  4882 		}
  4548 
  4883 
  4549 		if ( $post_more )
  4884 		if ( $post_more )
  4550 			$post_content = $post_content . "<!--more-->" . $post_more;
  4885 			$post_content = $post_content . "<!--more-->" . $post_more;
  4551 
  4886 
  4612 		// Handle post formats if assigned, validation is handled
  4947 		// Handle post formats if assigned, validation is handled
  4613 		// earlier in this function
  4948 		// earlier in this function
  4614 		if ( isset( $content_struct['wp_post_format'] ) )
  4949 		if ( isset( $content_struct['wp_post_format'] ) )
  4615 			set_post_format( $post_ID, $content_struct['wp_post_format'] );
  4950 			set_post_format( $post_ID, $content_struct['wp_post_format'] );
  4616 
  4951 
       
  4952 		/**
       
  4953 		 * Fires after a post has been successfully updated via the XML-RPC MovableType API.
       
  4954 		 *
       
  4955 		 * @since 3.4.0
       
  4956 		 *
       
  4957 		 * @param int   $post_ID ID of the updated post.
       
  4958 		 * @param array $args    An array of arguments to update the post.
       
  4959 		 */
  4617 		do_action( 'xmlrpc_call_success_mw_editPost', $post_ID, $args );
  4960 		do_action( 'xmlrpc_call_success_mw_editPost', $post_ID, $args );
  4618 
  4961 
  4619 		return true;
  4962 		return true;
  4620 	}
  4963 	}
  4621 
  4964 
  4623 	 * Retrieve post.
  4966 	 * Retrieve post.
  4624 	 *
  4967 	 *
  4625 	 * @since 1.5.0
  4968 	 * @since 1.5.0
  4626 	 *
  4969 	 *
  4627 	 * @param array $args Method parameters.
  4970 	 * @param array $args Method parameters.
  4628 	 * @return array
  4971 	 * @return array|IXR_Error
  4629 	 */
  4972 	 */
  4630 	function mw_getPost($args) {
  4973 	public function mw_getPost($args) {
  4631 
  4974 
  4632 		$this->escape($args);
  4975 		$this->escape($args);
  4633 
  4976 
  4634 		$post_ID     = (int) $args[0];
  4977 		$post_ID     = (int) $args[0];
  4635 		$username  = $args[1];
  4978 		$username  = $args[1];
  4643 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  4986 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  4644 
  4987 
  4645 		if ( !current_user_can( 'edit_post', $post_ID ) )
  4988 		if ( !current_user_can( 'edit_post', $post_ID ) )
  4646 			return new IXR_Error( 401, __( 'Sorry, you cannot edit this post.' ) );
  4989 			return new IXR_Error( 401, __( 'Sorry, you cannot edit this post.' ) );
  4647 
  4990 
  4648 		do_action('xmlrpc_call', 'metaWeblog.getPost');
  4991 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  4992 		do_action( 'xmlrpc_call', 'metaWeblog.getPost' );
  4649 
  4993 
  4650 		if ($postdata['post_date'] != '') {
  4994 		if ($postdata['post_date'] != '') {
  4651 			$post_date = $this->_convert_date( $postdata['post_date'] );
  4995 			$post_date = $this->_convert_date( $postdata['post_date'] );
  4652 			$post_date_gmt = $this->_convert_date_gmt( $postdata['post_date_gmt'],  $postdata['post_date'] );
  4996 			$post_date_gmt = $this->_convert_date_gmt( $postdata['post_date_gmt'],  $postdata['post_date'] );
  4653 			$post_modified = $this->_convert_date( $postdata['post_modified'] );
  4997 			$post_modified = $this->_convert_date( $postdata['post_modified'] );
  4747 	 * Retrieve list of recent posts.
  5091 	 * Retrieve list of recent posts.
  4748 	 *
  5092 	 *
  4749 	 * @since 1.5.0
  5093 	 * @since 1.5.0
  4750 	 *
  5094 	 *
  4751 	 * @param array $args Method parameters.
  5095 	 * @param array $args Method parameters.
  4752 	 * @return array
  5096 	 * @return array|IXR_Error
  4753 	 */
  5097 	 */
  4754 	function mw_getRecentPosts($args) {
  5098 	public function mw_getRecentPosts($args) {
  4755 
  5099 
  4756 		$this->escape($args);
  5100 		$this->escape($args);
  4757 
  5101 
  4758 		$blog_ID     = (int) $args[0];
       
  4759 		$username  = $args[1];
  5102 		$username  = $args[1];
  4760 		$password   = $args[2];
  5103 		$password   = $args[2];
  4761 		if ( isset( $args[3] ) )
  5104 		if ( isset( $args[3] ) )
  4762 			$query = array( 'numberposts' => absint( $args[3] ) );
  5105 			$query = array( 'numberposts' => absint( $args[3] ) );
  4763 		else
  5106 		else
  4767 			return $this->error;
  5110 			return $this->error;
  4768 
  5111 
  4769 		if ( ! current_user_can( 'edit_posts' ) )
  5112 		if ( ! current_user_can( 'edit_posts' ) )
  4770 			return new IXR_Error( 401, __( 'Sorry, you cannot edit posts on this site.' ) );
  5113 			return new IXR_Error( 401, __( 'Sorry, you cannot edit posts on this site.' ) );
  4771 
  5114 
  4772 		do_action('xmlrpc_call', 'metaWeblog.getRecentPosts');
  5115 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  5116 		do_action( 'xmlrpc_call', 'metaWeblog.getRecentPosts' );
  4773 
  5117 
  4774 		$posts_list = wp_get_recent_posts( $query );
  5118 		$posts_list = wp_get_recent_posts( $query );
  4775 
  5119 
  4776 		if ( !$posts_list )
  5120 		if ( !$posts_list )
  4777 			return array();
  5121 			return array();
  4778 
  5122 
  4779 		$struct = array();
  5123 		$recent_posts = array();
  4780 		foreach ($posts_list as $entry) {
  5124 		foreach ($posts_list as $entry) {
  4781 			if ( !current_user_can( 'edit_post', $entry['ID'] ) )
  5125 			if ( !current_user_can( 'edit_post', $entry['ID'] ) )
  4782 				continue;
  5126 				continue;
  4783 
  5127 
  4784 			$post_date = $this->_convert_date( $entry['post_date'] );
  5128 			$post_date = $this->_convert_date( $entry['post_date'] );
  4818 			// Get post format
  5162 			// Get post format
  4819 			$post_format = get_post_format( $entry['ID'] );
  5163 			$post_format = get_post_format( $entry['ID'] );
  4820 			if ( empty( $post_format ) )
  5164 			if ( empty( $post_format ) )
  4821 				$post_format = 'standard';
  5165 				$post_format = 'standard';
  4822 
  5166 
  4823 			$struct[] = array(
  5167 			$recent_posts[] = array(
  4824 				'dateCreated' => $post_date,
  5168 				'dateCreated' => $post_date,
  4825 				'userid' => $entry['post_author'],
  5169 				'userid' => $entry['post_author'],
  4826 				'postid' => (string) $entry['ID'],
  5170 				'postid' => (string) $entry['ID'],
  4827 				'description' => $post['main'],
  5171 				'description' => $post['main'],
  4828 				'title' => $entry['post_title'],
  5172 				'title' => $entry['post_title'],
  4844 				'date_created_gmt' => $post_date_gmt,
  5188 				'date_created_gmt' => $post_date_gmt,
  4845 				'post_status' => $entry['post_status'],
  5189 				'post_status' => $entry['post_status'],
  4846 				'custom_fields' => $this->get_custom_fields($entry['ID']),
  5190 				'custom_fields' => $this->get_custom_fields($entry['ID']),
  4847 				'wp_post_format' => $post_format,
  5191 				'wp_post_format' => $post_format,
  4848 				'date_modified' => $post_modified,
  5192 				'date_modified' => $post_modified,
  4849 				'date_modified_gmt' => $post_modified_gmt
  5193 				'date_modified_gmt' => $post_modified_gmt,
       
  5194 				'sticky' => ( $entry['post_type'] === 'post' && is_sticky( $entry['ID'] ) ),
       
  5195 				'wp_post_thumbnail' => get_post_thumbnail_id( $entry['ID'] )
  4850 			);
  5196 			);
  4851 
       
  4852 			$entry_index = count( $struct ) - 1;
       
  4853 			$struct[ $entry_index ][ 'wp_post_thumbnail' ] = get_post_thumbnail_id( $entry['ID'] );
       
  4854 		}
       
  4855 
       
  4856 		$recent_posts = array();
       
  4857 		for ( $j=0; $j<count($struct); $j++ ) {
       
  4858 			array_push($recent_posts, $struct[$j]);
       
  4859 		}
  5197 		}
  4860 
  5198 
  4861 		return $recent_posts;
  5199 		return $recent_posts;
  4862 	}
  5200 	}
  4863 
  5201 
  4865 	 * Retrieve the list of categories on a given blog.
  5203 	 * Retrieve the list of categories on a given blog.
  4866 	 *
  5204 	 *
  4867 	 * @since 1.5.0
  5205 	 * @since 1.5.0
  4868 	 *
  5206 	 *
  4869 	 * @param array $args Method parameters.
  5207 	 * @param array $args Method parameters.
  4870 	 * @return array
  5208 	 * @return array|IXR_Error
  4871 	 */
  5209 	 */
  4872 	function mw_getCategories($args) {
  5210 	public function mw_getCategories($args) {
  4873 
  5211 
  4874 		$this->escape($args);
  5212 		$this->escape($args);
  4875 
  5213 
  4876 		$blog_ID     = (int) $args[0];
       
  4877 		$username  = $args[1];
  5214 		$username  = $args[1];
  4878 		$password   = $args[2];
  5215 		$password   = $args[2];
  4879 
  5216 
  4880 		if ( !$user = $this->login($username, $password) )
  5217 		if ( !$user = $this->login($username, $password) )
  4881 			return $this->error;
  5218 			return $this->error;
  4882 
  5219 
  4883 		if ( !current_user_can( 'edit_posts' ) )
  5220 		if ( !current_user_can( 'edit_posts' ) )
  4884 			return new IXR_Error( 401, __( 'Sorry, you must be able to edit posts on this site in order to view categories.' ) );
  5221 			return new IXR_Error( 401, __( 'Sorry, you must be able to edit posts on this site in order to view categories.' ) );
  4885 
  5222 
  4886 		do_action('xmlrpc_call', 'metaWeblog.getCategories');
  5223 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  5224 		do_action( 'xmlrpc_call', 'metaWeblog.getCategories' );
  4887 
  5225 
  4888 		$categories_struct = array();
  5226 		$categories_struct = array();
  4889 
  5227 
  4890 		if ( $cats = get_categories(array('get' => 'all')) ) {
  5228 		if ( $cats = get_categories(array('get' => 'all')) ) {
  4891 			foreach ( $cats as $cat ) {
  5229 			foreach ( $cats as $cat ) {
       
  5230 				$struct = array();
  4892 				$struct['categoryId'] = $cat->term_id;
  5231 				$struct['categoryId'] = $cat->term_id;
  4893 				$struct['parentId'] = $cat->parent;
  5232 				$struct['parentId'] = $cat->parent;
  4894 				$struct['description'] = $cat->name;
  5233 				$struct['description'] = $cat->name;
  4895 				$struct['categoryDescription'] = $cat->description;
  5234 				$struct['categoryDescription'] = $cat->description;
  4896 				$struct['categoryName'] = $cat->name;
  5235 				$struct['categoryName'] = $cat->name;
  4912 	 * @link http://mycvs.org/archives/2004/06/30/file-upload-to-wordpress-in-ecto/
  5251 	 * @link http://mycvs.org/archives/2004/06/30/file-upload-to-wordpress-in-ecto/
  4913 	 *
  5252 	 *
  4914 	 * @since 1.5.0
  5253 	 * @since 1.5.0
  4915 	 *
  5254 	 *
  4916 	 * @param array $args Method parameters.
  5255 	 * @param array $args Method parameters.
  4917 	 * @return array
  5256 	 * @return array|IXR_Error
  4918 	 */
  5257 	 */
  4919 	function mw_newMediaObject($args) {
  5258 	public function mw_newMediaObject($args) {
  4920 		global $wpdb;
  5259 		global $wpdb;
  4921 
  5260 
  4922 		$blog_ID     = (int) $args[0];
       
  4923 		$username  = $this->escape($args[1]);
  5261 		$username  = $this->escape($args[1]);
  4924 		$password   = $this->escape($args[2]);
  5262 		$password   = $this->escape($args[2]);
  4925 		$data        = $args[3];
  5263 		$data        = $args[3];
  4926 
  5264 
  4927 		$name = sanitize_file_name( $data['name'] );
  5265 		$name = sanitize_file_name( $data['name'] );
  4929 		$bits = $data['bits'];
  5267 		$bits = $data['bits'];
  4930 
  5268 
  4931 		if ( !$user = $this->login($username, $password) )
  5269 		if ( !$user = $this->login($username, $password) )
  4932 			return $this->error;
  5270 			return $this->error;
  4933 
  5271 
  4934 		do_action('xmlrpc_call', 'metaWeblog.newMediaObject');
  5272 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  5273 		do_action( 'xmlrpc_call', 'metaWeblog.newMediaObject' );
  4935 
  5274 
  4936 		if ( !current_user_can('upload_files') ) {
  5275 		if ( !current_user_can('upload_files') ) {
  4937 			$this->error = new IXR_Error( 401, __( 'You do not have permission to upload files.' ) );
  5276 			$this->error = new IXR_Error( 401, __( 'You do not have permission to upload files.' ) );
  4938 			return $this->error;
  5277 			return $this->error;
  4939 		}
  5278 		}
  4940 
  5279 
  4941 		if ( $upload_err = apply_filters( 'pre_upload_error', false ) )
  5280 		/**
  4942 			return new IXR_Error(500, $upload_err);
  5281 		 * Filter whether to preempt the XML-RPC media upload.
       
  5282 		 *
       
  5283 		 * Passing a truthy value will effectively short-circuit the media upload,
       
  5284 		 * returning that value as a 500 error instead.
       
  5285 		 *
       
  5286 		 * @since 2.1.0
       
  5287 		 *
       
  5288 		 * @param bool $error Whether to pre-empt the media upload. Default false.
       
  5289 		 */
       
  5290 		if ( $upload_err = apply_filters( 'pre_upload_error', false ) ) {
       
  5291 			return new IXR_Error( 500, $upload_err );
       
  5292 		}
  4943 
  5293 
  4944 		if ( !empty($data['overwrite']) && ($data['overwrite'] == true) ) {
  5294 		if ( !empty($data['overwrite']) && ($data['overwrite'] == true) ) {
  4945 			// Get postmeta info on the object.
  5295 			// Get postmeta info on the object.
  4946 			$old_file = $wpdb->get_row("
  5296 			$old_file = $wpdb->get_row("
  4947 				SELECT ID
  5297 				SELECT ID
  4983 
  5333 
  4984 		// Save the data
  5334 		// Save the data
  4985 		$id = wp_insert_attachment( $attachment, $upload[ 'file' ], $post_id );
  5335 		$id = wp_insert_attachment( $attachment, $upload[ 'file' ], $post_id );
  4986 		wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $upload['file'] ) );
  5336 		wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $upload['file'] ) );
  4987 
  5337 
       
  5338 		/**
       
  5339 		 * Fires after a new attachment has been added via the XML-RPC MovableType API.
       
  5340 		 *
       
  5341 		 * @since 3.4.0
       
  5342 		 *
       
  5343 		 * @param int   $id   ID of the new attachment.
       
  5344 		 * @param array $args An array of arguments to add the attachment.
       
  5345 		 */
  4988 		do_action( 'xmlrpc_call_success_mw_newMediaObject', $id, $args );
  5346 		do_action( 'xmlrpc_call_success_mw_newMediaObject', $id, $args );
  4989 
  5347 
  4990 		$struct = array(
  5348 		$struct = array(
  4991 			'id'   => strval( $id ),
  5349 			'id'   => strval( $id ),
  4992 			'file' => $name,
  5350 			'file' => $name,
  4993 			'url'  => $upload[ 'url' ],
  5351 			'url'  => $upload[ 'url' ],
  4994 			'type' => $type
  5352 			'type' => $type
  4995 		);
  5353 		);
       
  5354 
       
  5355 		/** This filter is documented in wp-admin/includes/file.php */
  4996 		return apply_filters( 'wp_handle_upload', $struct, 'upload' );
  5356 		return apply_filters( 'wp_handle_upload', $struct, 'upload' );
  4997 	}
  5357 	}
  4998 
  5358 
  4999 	/* MovableType API functions
  5359 	/* MovableType API functions
  5000 	 * specs on http://www.movabletype.org/docs/mtmanual_programmatic.html
  5360 	 * specs on http://www.movabletype.org/docs/mtmanual_programmatic.html
  5004 	 * Retrieve the post titles of recent posts.
  5364 	 * Retrieve the post titles of recent posts.
  5005 	 *
  5365 	 *
  5006 	 * @since 1.5.0
  5366 	 * @since 1.5.0
  5007 	 *
  5367 	 *
  5008 	 * @param array $args Method parameters.
  5368 	 * @param array $args Method parameters.
  5009 	 * @return array
  5369 	 * @return array|IXR_Error
  5010 	 */
  5370 	 */
  5011 	function mt_getRecentPostTitles($args) {
  5371 	public function mt_getRecentPostTitles($args) {
  5012 
  5372 
  5013 		$this->escape($args);
  5373 		$this->escape($args);
  5014 
  5374 
  5015 		$blog_ID     = (int) $args[0];
       
  5016 		$username  = $args[1];
  5375 		$username  = $args[1];
  5017 		$password   = $args[2];
  5376 		$password   = $args[2];
  5018 		if ( isset( $args[3] ) )
  5377 		if ( isset( $args[3] ) )
  5019 			$query = array( 'numberposts' => absint( $args[3] ) );
  5378 			$query = array( 'numberposts' => absint( $args[3] ) );
  5020 		else
  5379 		else
  5021 			$query = array();
  5380 			$query = array();
  5022 
  5381 
  5023 		if ( !$user = $this->login($username, $password) )
  5382 		if ( !$user = $this->login($username, $password) )
  5024 			return $this->error;
  5383 			return $this->error;
  5025 
  5384 
  5026 		do_action('xmlrpc_call', 'mt.getRecentPostTitles');
  5385 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  5386 		do_action( 'xmlrpc_call', 'mt.getRecentPostTitles' );
  5027 
  5387 
  5028 		$posts_list = wp_get_recent_posts( $query );
  5388 		$posts_list = wp_get_recent_posts( $query );
  5029 
  5389 
  5030 		if ( !$posts_list ) {
  5390 		if ( !$posts_list ) {
  5031 			$this->error = new IXR_Error(500, __('Either there are no posts, or something went wrong.'));
  5391 			$this->error = new IXR_Error(500, __('Either there are no posts, or something went wrong.'));
  5032 			return $this->error;
  5392 			return $this->error;
  5033 		}
  5393 		}
  5034 
  5394 
  5035 		$struct = array();
  5395 		$recent_posts = array();
  5036 
  5396 
  5037 		foreach ($posts_list as $entry) {
  5397 		foreach ($posts_list as $entry) {
  5038 			if ( !current_user_can( 'edit_post', $entry['ID'] ) )
  5398 			if ( !current_user_can( 'edit_post', $entry['ID'] ) )
  5039 				continue;
  5399 				continue;
  5040 
  5400 
  5041 			$post_date = $this->_convert_date( $entry['post_date'] );
  5401 			$post_date = $this->_convert_date( $entry['post_date'] );
  5042 			$post_date_gmt = $this->_convert_date_gmt( $entry['post_date_gmt'], $entry['post_date'] );
  5402 			$post_date_gmt = $this->_convert_date_gmt( $entry['post_date_gmt'], $entry['post_date'] );
  5043 
  5403 
  5044 			$struct[] = array(
  5404 			$recent_posts[] = array(
  5045 				'dateCreated' => $post_date,
  5405 				'dateCreated' => $post_date,
  5046 				'userid' => $entry['post_author'],
  5406 				'userid' => $entry['post_author'],
  5047 				'postid' => (string) $entry['ID'],
  5407 				'postid' => (string) $entry['ID'],
  5048 				'title' => $entry['post_title'],
  5408 				'title' => $entry['post_title'],
  5049 				'post_status' => $entry['post_status'],
  5409 				'post_status' => $entry['post_status'],
  5050 				'date_created_gmt' => $post_date_gmt
  5410 				'date_created_gmt' => $post_date_gmt
  5051 			);
  5411 			);
  5052 
       
  5053 		}
       
  5054 
       
  5055 		$recent_posts = array();
       
  5056 		for ( $j=0; $j<count($struct); $j++ ) {
       
  5057 			array_push($recent_posts, $struct[$j]);
       
  5058 		}
  5412 		}
  5059 
  5413 
  5060 		return $recent_posts;
  5414 		return $recent_posts;
  5061 	}
  5415 	}
  5062 
  5416 
  5064 	 * Retrieve list of all categories on blog.
  5418 	 * Retrieve list of all categories on blog.
  5065 	 *
  5419 	 *
  5066 	 * @since 1.5.0
  5420 	 * @since 1.5.0
  5067 	 *
  5421 	 *
  5068 	 * @param array $args Method parameters.
  5422 	 * @param array $args Method parameters.
  5069 	 * @return array
  5423 	 * @return array|IXR_Error
  5070 	 */
  5424 	 */
  5071 	function mt_getCategoryList($args) {
  5425 	public function mt_getCategoryList($args) {
  5072 
  5426 
  5073 		$this->escape($args);
  5427 		$this->escape($args);
  5074 
  5428 
  5075 		$blog_ID     = (int) $args[0];
       
  5076 		$username  = $args[1];
  5429 		$username  = $args[1];
  5077 		$password   = $args[2];
  5430 		$password   = $args[2];
  5078 
  5431 
  5079 		if ( !$user = $this->login($username, $password) )
  5432 		if ( !$user = $this->login($username, $password) )
  5080 			return $this->error;
  5433 			return $this->error;
  5081 
  5434 
  5082 		if ( !current_user_can( 'edit_posts' ) )
  5435 		if ( !current_user_can( 'edit_posts' ) )
  5083 			return new IXR_Error( 401, __( 'Sorry, you must be able to edit posts on this site in order to view categories.' ) );
  5436 			return new IXR_Error( 401, __( 'Sorry, you must be able to edit posts on this site in order to view categories.' ) );
  5084 
  5437 
  5085 		do_action('xmlrpc_call', 'mt.getCategoryList');
  5438 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  5439 		do_action( 'xmlrpc_call', 'mt.getCategoryList' );
  5086 
  5440 
  5087 		$categories_struct = array();
  5441 		$categories_struct = array();
  5088 
  5442 
  5089 		if ( $cats = get_categories(array('hide_empty' => 0, 'hierarchical' => 0)) ) {
  5443 		if ( $cats = get_categories(array('hide_empty' => 0, 'hierarchical' => 0)) ) {
  5090 			foreach ( $cats as $cat ) {
  5444 			foreach ( $cats as $cat ) {
       
  5445 				$struct = array();
  5091 				$struct['categoryId'] = $cat->term_id;
  5446 				$struct['categoryId'] = $cat->term_id;
  5092 				$struct['categoryName'] = $cat->name;
  5447 				$struct['categoryName'] = $cat->name;
  5093 
  5448 
  5094 				$categories_struct[] = $struct;
  5449 				$categories_struct[] = $struct;
  5095 			}
  5450 			}
  5102 	 * Retrieve post categories.
  5457 	 * Retrieve post categories.
  5103 	 *
  5458 	 *
  5104 	 * @since 1.5.0
  5459 	 * @since 1.5.0
  5105 	 *
  5460 	 *
  5106 	 * @param array $args Method parameters.
  5461 	 * @param array $args Method parameters.
  5107 	 * @return array
  5462 	 * @return array|IXR_Error
  5108 	 */
  5463 	 */
  5109 	function mt_getPostCategories($args) {
  5464 	public function mt_getPostCategories($args) {
  5110 
  5465 
  5111 		$this->escape($args);
  5466 		$this->escape($args);
  5112 
  5467 
  5113 		$post_ID     = (int) $args[0];
  5468 		$post_ID     = (int) $args[0];
  5114 		$username  = $args[1];
  5469 		$username  = $args[1];
  5121 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  5476 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  5122 
  5477 
  5123 		if ( !current_user_can( 'edit_post', $post_ID ) )
  5478 		if ( !current_user_can( 'edit_post', $post_ID ) )
  5124 			return new IXR_Error( 401, __( 'Sorry, you can not edit this post.' ) );
  5479 			return new IXR_Error( 401, __( 'Sorry, you can not edit this post.' ) );
  5125 
  5480 
  5126 		do_action('xmlrpc_call', 'mt.getPostCategories');
  5481 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  5482 		do_action( 'xmlrpc_call', 'mt.getPostCategories' );
  5127 
  5483 
  5128 		$categories = array();
  5484 		$categories = array();
  5129 		$catids = wp_get_post_categories(intval($post_ID));
  5485 		$catids = wp_get_post_categories(intval($post_ID));
  5130 		// first listed category will be the primary category
  5486 		// first listed category will be the primary category
  5131 		$isPrimary = true;
  5487 		$isPrimary = true;
  5145 	 * Sets categories for a post.
  5501 	 * Sets categories for a post.
  5146 	 *
  5502 	 *
  5147 	 * @since 1.5.0
  5503 	 * @since 1.5.0
  5148 	 *
  5504 	 *
  5149 	 * @param array $args Method parameters.
  5505 	 * @param array $args Method parameters.
  5150 	 * @return bool True on success.
  5506 	 * @return bool|IXR_Error True on success.
  5151 	 */
  5507 	 */
  5152 	function mt_setPostCategories($args) {
  5508 	public function mt_setPostCategories($args) {
  5153 
  5509 
  5154 		$this->escape($args);
  5510 		$this->escape($args);
  5155 
  5511 
  5156 		$post_ID     = (int) $args[0];
  5512 		$post_ID     = (int) $args[0];
  5157 		$username  = $args[1];
  5513 		$username  = $args[1];
  5159 		$categories  = $args[3];
  5515 		$categories  = $args[3];
  5160 
  5516 
  5161 		if ( !$user = $this->login($username, $password) )
  5517 		if ( !$user = $this->login($username, $password) )
  5162 			return $this->error;
  5518 			return $this->error;
  5163 
  5519 
  5164 		do_action('xmlrpc_call', 'mt.setPostCategories');
  5520 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  5521 		do_action( 'xmlrpc_call', 'mt.setPostCategories' );
  5165 
  5522 
  5166 		if ( ! get_post( $post_ID ) )
  5523 		if ( ! get_post( $post_ID ) )
  5167 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  5524 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  5168 
  5525 
  5169 		if ( !current_user_can('edit_post', $post_ID) )
  5526 		if ( !current_user_can('edit_post', $post_ID) )
  5185 	 * @since 1.5.0
  5542 	 * @since 1.5.0
  5186 	 *
  5543 	 *
  5187 	 * @param array $args Method parameters.
  5544 	 * @param array $args Method parameters.
  5188 	 * @return array
  5545 	 * @return array
  5189 	 */
  5546 	 */
  5190 	function mt_supportedMethods($args) {
  5547 	public function mt_supportedMethods($args) {
  5191 
  5548 
  5192 		do_action('xmlrpc_call', 'mt.supportedMethods');
  5549 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  5550 		do_action( 'xmlrpc_call', 'mt.supportedMethods' );
  5193 
  5551 
  5194 		$supported_methods = array();
  5552 		$supported_methods = array();
  5195 		foreach ( $this->methods as $key => $value ) {
  5553 		foreach ( $this->methods as $key => $value ) {
  5196 			$supported_methods[] = $key;
  5554 			$supported_methods[] = $key;
  5197 		}
  5555 		}
  5204 	 *
  5562 	 *
  5205 	 * @since 1.5.0
  5563 	 * @since 1.5.0
  5206 	 *
  5564 	 *
  5207 	 * @param array $args Method parameters.
  5565 	 * @param array $args Method parameters.
  5208 	 */
  5566 	 */
  5209 	function mt_supportedTextFilters($args) {
  5567 	public function mt_supportedTextFilters($args) {
  5210 		do_action('xmlrpc_call', 'mt.supportedTextFilters');
  5568 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  5211 		return apply_filters('xmlrpc_text_filters', array());
  5569 		do_action( 'xmlrpc_call', 'mt.supportedTextFilters' );
       
  5570 
       
  5571 		/**
       
  5572 		 * Filter the MoveableType text filters list for XML-RPC.
       
  5573 		 *
       
  5574 		 * @since 2.2.0
       
  5575 		 *
       
  5576 		 * @param array $filters An array of text filters.
       
  5577 		 */
       
  5578 		return apply_filters( 'xmlrpc_text_filters', array() );
  5212 	}
  5579 	}
  5213 
  5580 
  5214 	/**
  5581 	/**
  5215 	 * Retrieve trackbacks sent to a given post.
  5582 	 * Retrieve trackbacks sent to a given post.
  5216 	 *
  5583 	 *
  5217 	 * @since 1.5.0
  5584 	 * @since 1.5.0
  5218 	 *
  5585 	 *
  5219 	 * @param array $args Method parameters.
  5586 	 * @param array $args Method parameters.
  5220 	 * @return mixed
  5587 	 * @return array|IXR_Error
  5221 	 */
  5588 	 */
  5222 	function mt_getTrackbackPings($args) {
  5589 	public function mt_getTrackbackPings($args) {
  5223 
  5590 
  5224 		global $wpdb;
  5591 		global $wpdb;
  5225 
  5592 
  5226 		$post_ID = intval($args);
  5593 		$post_ID = intval($args);
  5227 
  5594 
  5228 		do_action('xmlrpc_call', 'mt.getTrackbackPings');
  5595 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  5596 		do_action( 'xmlrpc_call', 'mt.getTrackbackPings' );
  5229 
  5597 
  5230 		$actual_post = get_post($post_ID, ARRAY_A);
  5598 		$actual_post = get_post($post_ID, ARRAY_A);
  5231 
  5599 
  5232 		if ( !$actual_post )
  5600 		if ( !$actual_post )
  5233 			return new IXR_Error(404, __('Sorry, no such post.'));
  5601 			return new IXR_Error(404, __('Sorry, no such post.'));
  5257 	 * Sets a post's publish status to 'publish'.
  5625 	 * Sets a post's publish status to 'publish'.
  5258 	 *
  5626 	 *
  5259 	 * @since 1.5.0
  5627 	 * @since 1.5.0
  5260 	 *
  5628 	 *
  5261 	 * @param array $args Method parameters.
  5629 	 * @param array $args Method parameters.
  5262 	 * @return int
  5630 	 * @return int|IXR_Error
  5263 	 */
  5631 	 */
  5264 	function mt_publishPost($args) {
  5632 	public function mt_publishPost($args) {
  5265 
  5633 
  5266 		$this->escape($args);
  5634 		$this->escape($args);
  5267 
  5635 
  5268 		$post_ID     = (int) $args[0];
  5636 		$post_ID     = (int) $args[0];
  5269 		$username  = $args[1];
  5637 		$username  = $args[1];
  5270 		$password   = $args[2];
  5638 		$password   = $args[2];
  5271 
  5639 
  5272 		if ( !$user = $this->login($username, $password) )
  5640 		if ( !$user = $this->login($username, $password) )
  5273 			return $this->error;
  5641 			return $this->error;
  5274 
  5642 
  5275 		do_action('xmlrpc_call', 'mt.publishPost');
  5643 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  5644 		do_action( 'xmlrpc_call', 'mt.publishPost' );
  5276 
  5645 
  5277 		$postdata = get_post($post_ID, ARRAY_A);
  5646 		$postdata = get_post($post_ID, ARRAY_A);
  5278 		if ( ! $postdata )
  5647 		if ( ! $postdata )
  5279 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  5648 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  5280 
  5649 
  5301 	 * Retrieves a pingback and registers it.
  5670 	 * Retrieves a pingback and registers it.
  5302 	 *
  5671 	 *
  5303 	 * @since 1.5.0
  5672 	 * @since 1.5.0
  5304 	 *
  5673 	 *
  5305 	 * @param array $args Method parameters.
  5674 	 * @param array $args Method parameters.
  5306 	 * @return array
  5675 	 * @return string|IXR_Error
  5307 	 */
  5676 	 */
  5308 	function pingback_ping($args) {
  5677 	public function pingback_ping($args) {
  5309 		global $wpdb;
  5678 		global $wpdb;
  5310 
  5679 
  5311 		do_action('xmlrpc_call', 'pingback.ping');
  5680 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  5681 		do_action( 'xmlrpc_call', 'pingback.ping' );
  5312 
  5682 
  5313 		$this->escape($args);
  5683 		$this->escape($args);
  5314 
  5684 
  5315 		$pagelinkedfrom = $args[0];
  5685 		$pagelinkedfrom = $args[0];
  5316 		$pagelinkedto   = $args[1];
  5686 		$pagelinkedto   = $args[1];
  5317 
       
  5318 		$title = '';
       
  5319 
  5687 
  5320 		$pagelinkedfrom = str_replace('&amp;', '&', $pagelinkedfrom);
  5688 		$pagelinkedfrom = str_replace('&amp;', '&', $pagelinkedfrom);
  5321 		$pagelinkedto = str_replace('&amp;', '&', $pagelinkedto);
  5689 		$pagelinkedto = str_replace('&amp;', '&', $pagelinkedto);
  5322 		$pagelinkedto = str_replace('&', '&amp;', $pagelinkedto);
  5690 		$pagelinkedto = str_replace('&', '&amp;', $pagelinkedto);
  5323 
  5691 
       
  5692 		/**
       
  5693 		 * Filter the pingback source URI.
       
  5694 		 *
       
  5695 		 * @since 3.6.0
       
  5696 		 *
       
  5697 		 * @param string $pagelinkedfrom URI of the page linked from.
       
  5698 		 * @param string $pagelinkedto   URI of the page linked to.
       
  5699 		 */
  5324 		$pagelinkedfrom = apply_filters( 'pingback_ping_source_uri', $pagelinkedfrom, $pagelinkedto );
  5700 		$pagelinkedfrom = apply_filters( 'pingback_ping_source_uri', $pagelinkedfrom, $pagelinkedto );
       
  5701 
  5325 		if ( ! $pagelinkedfrom )
  5702 		if ( ! $pagelinkedfrom )
  5326 			return $this->pingback_error( 0, __( 'A valid URL was not provided.' ) );
  5703 			return $this->pingback_error( 0, __( 'A valid URL was not provided.' ) );
  5327 
  5704 
  5328 		// Check if the page linked to is in our site
  5705 		// Check if the page linked to is in our site
  5329 		$pos1 = strpos($pagelinkedto, str_replace(array('http://www.','http://','https://www.','https://'), '', get_option('home')));
  5706 		$pos1 = strpos($pagelinkedto, str_replace(array('http://www.','http://','https://www.','https://'), '', get_option('home')));
  5333 		// let's find which post is linked to
  5710 		// let's find which post is linked to
  5334 		// FIXME: does url_to_postid() cover all these cases already?
  5711 		// FIXME: does url_to_postid() cover all these cases already?
  5335 		//        if so, then let's use it and drop the old code.
  5712 		//        if so, then let's use it and drop the old code.
  5336 		$urltest = parse_url($pagelinkedto);
  5713 		$urltest = parse_url($pagelinkedto);
  5337 		if ( $post_ID = url_to_postid($pagelinkedto) ) {
  5714 		if ( $post_ID = url_to_postid($pagelinkedto) ) {
  5338 			$way = 'url_to_postid()';
  5715 			// $way
  5339 		} elseif ( preg_match('#p/[0-9]{1,}#', $urltest['path'], $match) ) {
  5716 		} elseif ( isset( $urltest['path'] ) && preg_match('#p/[0-9]{1,}#', $urltest['path'], $match) ) {
  5340 			// the path defines the post_ID (archives/p/XXXX)
  5717 			// the path defines the post_ID (archives/p/XXXX)
  5341 			$blah = explode('/', $match[0]);
  5718 			$blah = explode('/', $match[0]);
  5342 			$post_ID = (int) $blah[1];
  5719 			$post_ID = (int) $blah[1];
  5343 			$way = 'from the path';
       
  5344 		} elseif ( isset( $urltest['query'] ) && preg_match('#p=[0-9]{1,}#', $urltest['query'], $match) ) {
  5720 		} elseif ( isset( $urltest['query'] ) && preg_match('#p=[0-9]{1,}#', $urltest['query'], $match) ) {
  5345 			// the querystring defines the post_ID (?p=XXXX)
  5721 			// the querystring defines the post_ID (?p=XXXX)
  5346 			$blah = explode('=', $match[0]);
  5722 			$blah = explode('=', $match[0]);
  5347 			$post_ID = (int) $blah[1];
  5723 			$post_ID = (int) $blah[1];
  5348 			$way = 'from the querystring';
       
  5349 		} elseif ( isset($urltest['fragment']) ) {
  5724 		} elseif ( isset($urltest['fragment']) ) {
  5350 			// an #anchor is there, it's either...
  5725 			// an #anchor is there, it's either...
  5351 			if ( intval($urltest['fragment']) ) {
  5726 			if ( intval($urltest['fragment']) ) {
  5352 				// ...an integer #XXXX (simplest case)
  5727 				// ...an integer #XXXX (simplest case)
  5353 				$post_ID = (int) $urltest['fragment'];
  5728 				$post_ID = (int) $urltest['fragment'];
  5354 				$way = 'from the fragment (numeric)';
       
  5355 			} elseif ( preg_match('/post-[0-9]+/',$urltest['fragment']) ) {
  5729 			} elseif ( preg_match('/post-[0-9]+/',$urltest['fragment']) ) {
  5356 				// ...a post id in the form 'post-###'
  5730 				// ...a post id in the form 'post-###'
  5357 				$post_ID = preg_replace('/[^0-9]+/', '', $urltest['fragment']);
  5731 				$post_ID = preg_replace('/[^0-9]+/', '', $urltest['fragment']);
  5358 				$way = 'from the fragment (post-###)';
       
  5359 			} elseif ( is_string($urltest['fragment']) ) {
  5732 			} elseif ( is_string($urltest['fragment']) ) {
  5360 				// ...or a string #title, a little more complicated
  5733 				// ...or a string #title, a little more complicated
  5361 				$title = preg_replace('/[^a-z0-9]/i', '.', $urltest['fragment']);
  5734 				$title = preg_replace('/[^a-z0-9]/i', '.', $urltest['fragment']);
  5362 				$sql = $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE post_title RLIKE %s", like_escape( $title ) );
  5735 				$sql = $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE post_title RLIKE %s", $title );
  5363 				if (! ($post_ID = $wpdb->get_var($sql)) ) {
  5736 				if (! ($post_ID = $wpdb->get_var($sql)) ) {
  5364 					// returning unknown error '0' is better than die()ing
  5737 					// returning unknown error '0' is better than die()ing
  5365 			  		return $this->pingback_error( 0, '' );
  5738 			  		return $this->pingback_error( 0, '' );
  5366 				}
  5739 				}
  5367 				$way = 'from the fragment (title)';
       
  5368 			}
  5740 			}
  5369 		} else {
  5741 		} else {
  5370 			// TODO: Attempt to extract a post ID from the given URL
  5742 			// TODO: Attempt to extract a post ID from the given URL
  5371 	  		return $this->pingback_error( 33, __('The specified target URL cannot be used as a target. It either doesn&#8217;t exist, or it is not a pingback-enabled resource.' ) );
  5743 	  		return $this->pingback_error( 33, __('The specified target URL cannot be used as a target. It either doesn&#8217;t exist, or it is not a pingback-enabled resource.' ) );
  5372 		}
  5744 		}
  5388 		if ( $wpdb->get_results( $wpdb->prepare("SELECT * FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_author_url = %s", $post_ID, $pagelinkedfrom) ) )
  5760 		if ( $wpdb->get_results( $wpdb->prepare("SELECT * FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_author_url = %s", $post_ID, $pagelinkedfrom) ) )
  5389 			return $this->pingback_error( 48, __( 'The pingback has already been registered.' ) );
  5761 			return $this->pingback_error( 48, __( 'The pingback has already been registered.' ) );
  5390 
  5762 
  5391 		// very stupid, but gives time to the 'from' server to publish !
  5763 		// very stupid, but gives time to the 'from' server to publish !
  5392 		sleep(1);
  5764 		sleep(1);
       
  5765 
       
  5766 		$remote_ip = preg_replace( '/[^0-9a-fA-F:., ]/', '', $_SERVER['REMOTE_ADDR'] );
       
  5767 
       
  5768 		/** This filter is documented in wp-includes/class-http.php */
       
  5769 		$user_agent = apply_filters( 'http_headers_useragent', 'WordPress/' . $GLOBALS['wp_version'] . '; ' . get_bloginfo( 'url' ) );
  5393 
  5770 
  5394 		// Let's check the remote site
  5771 		// Let's check the remote site
  5395 		$http_api_args = array(
  5772 		$http_api_args = array(
  5396 			'timeout' => 10,
  5773 			'timeout' => 10,
  5397 			'redirection' => 0,
  5774 			'redirection' => 0,
  5398 			'limit_response_size' => 153600, // 150 KB
  5775 			'limit_response_size' => 153600, // 150 KB
       
  5776 			'user-agent' => "$user_agent; verifying pingback from $remote_ip",
       
  5777 			'headers' => array(
       
  5778 				'X-Pingback-Forwarded-For' => $remote_ip,
       
  5779 			),
  5399 		);
  5780 		);
  5400 		$linea = wp_remote_retrieve_body( wp_safe_remote_get( $pagelinkedfrom, $http_api_args ) );
  5781 		$request = wp_safe_remote_get( $pagelinkedfrom, $http_api_args );
       
  5782 		$linea = wp_remote_retrieve_body( $request );
  5401 
  5783 
  5402 		if ( !$linea )
  5784 		if ( !$linea )
  5403 	  		return $this->pingback_error( 16, __( 'The source URL does not exist.' ) );
  5785 			return $this->pingback_error( 16, __( 'The source URL does not exist.' ) );
  5404 
  5786 
  5405 		$linea = apply_filters('pre_remote_source', $linea, $pagelinkedto);
  5787 		/**
       
  5788 		 * Filter the pingback remote source.
       
  5789 		 *
       
  5790 		 * @since 2.5.0
       
  5791 		 *
       
  5792 		 * @param string $linea        Response object for the page linked from.
       
  5793 		 * @param string $pagelinkedto URL of the page linked to.
       
  5794 		 */
       
  5795 		$linea = apply_filters( 'pre_remote_source', $linea, $pagelinkedto );
  5406 
  5796 
  5407 		// Work around bug in strip_tags():
  5797 		// Work around bug in strip_tags():
  5408 		$linea = str_replace('<!DOC', '<DOC', $linea);
  5798 		$linea = str_replace('<!DOC', '<DOC', $linea);
  5409 		$linea = preg_replace( '/[\r\n\t ]+/', ' ', $linea ); // normalize spaces
  5799 		$linea = preg_replace( '/[\r\n\t ]+/', ' ', $linea ); // normalize spaces
  5410 		$linea = preg_replace( "/<\/*(h1|h2|h3|h4|h5|h6|p|th|td|li|dt|dd|pre|caption|input|textarea|button|body)[^>]*>/", "\n\n", $linea );
  5800 		$linea = preg_replace( "/<\/*(h1|h2|h3|h4|h5|h6|p|th|td|li|dt|dd|pre|caption|input|textarea|button|body)[^>]*>/", "\n\n", $linea );
  5465 		$comment_type = 'pingback';
  5855 		$comment_type = 'pingback';
  5466 
  5856 
  5467 		$commentdata = compact('comment_post_ID', 'comment_author', 'comment_author_url', 'comment_author_email', 'comment_content', 'comment_type');
  5857 		$commentdata = compact('comment_post_ID', 'comment_author', 'comment_author_url', 'comment_author_email', 'comment_content', 'comment_type');
  5468 
  5858 
  5469 		$comment_ID = wp_new_comment($commentdata);
  5859 		$comment_ID = wp_new_comment($commentdata);
  5470 		do_action('pingback_post', $comment_ID);
  5860 
       
  5861 		/**
       
  5862 		 * Fires after a post pingback has been sent.
       
  5863 		 *
       
  5864 		 * @since 0.71
       
  5865 		 *
       
  5866 		 * @param int $comment_ID Comment ID.
       
  5867 		 */
       
  5868 		do_action( 'pingback_post', $comment_ID );
  5471 
  5869 
  5472 		return sprintf(__('Pingback from %1$s to %2$s registered. Keep the web talking! :-)'), $pagelinkedfrom, $pagelinkedto);
  5870 		return sprintf(__('Pingback from %1$s to %2$s registered. Keep the web talking! :-)'), $pagelinkedfrom, $pagelinkedto);
  5473 	}
  5871 	}
  5474 
  5872 
  5475 	/**
  5873 	/**
  5478 	 * Specs on http://www.aquarionics.com/misc/archives/blogite/0198.html
  5876 	 * Specs on http://www.aquarionics.com/misc/archives/blogite/0198.html
  5479 	 *
  5877 	 *
  5480 	 * @since 1.5.0
  5878 	 * @since 1.5.0
  5481 	 *
  5879 	 *
  5482 	 * @param array $args Method parameters.
  5880 	 * @param array $args Method parameters.
  5483 	 * @return array
  5881 	 * @return array|IXR_Error
  5484 	 */
  5882 	 */
  5485 	function pingback_extensions_getPingbacks($args) {
  5883 	public function pingback_extensions_getPingbacks($args) {
  5486 
  5884 
  5487 		global $wpdb;
  5885 		global $wpdb;
  5488 
  5886 
  5489 		do_action('xmlrpc_call', 'pingback.extensions.getPingbacks');
  5887 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
       
  5888 		do_action( 'xmlrpc_call', 'pingback.extensions.getPingbacks' );
  5490 
  5889 
  5491 		$this->escape($args);
  5890 		$this->escape($args);
  5492 
  5891 
  5493 		$url = $args;
  5892 		$url = $args;
  5494 
  5893 
  5517 		}
  5916 		}
  5518 
  5917 
  5519 		return $pingbacks;
  5918 		return $pingbacks;
  5520 	}
  5919 	}
  5521 
  5920 
       
  5921 	/**
       
  5922 	 * @param integer $code
       
  5923 	 * @param string $message
       
  5924 	 */
  5522 	protected function pingback_error( $code, $message ) {
  5925 	protected function pingback_error( $code, $message ) {
       
  5926 		/**
       
  5927 		 * Filter the XML-RPC pingback error return.
       
  5928 		 *
       
  5929 		 * @since 3.5.1
       
  5930 		 *
       
  5931 		 * @param IXR_Error $error An IXR_Error object containing the error code and message.
       
  5932 		 */
  5523 		return apply_filters( 'xmlrpc_pingback_error', new IXR_Error( $code, $message ) );
  5933 		return apply_filters( 'xmlrpc_pingback_error', new IXR_Error( $code, $message ) );
  5524 	}
  5934 	}
  5525 }
  5935 }