wp/wp-includes/class-wp-xmlrpc-server.php
changeset 9 177826044cd9
parent 7 cf61fcea0001
child 16 a86126ab1dd4
equal deleted inserted replaced
8:c7c34916027a 9:177826044cd9
    59 	 * @since 1.5.0
    59 	 * @since 1.5.0
    60 	 */
    60 	 */
    61 	public function __construct() {
    61 	public function __construct() {
    62 		$this->methods = array(
    62 		$this->methods = array(
    63 			// WordPress API
    63 			// WordPress API
    64 			'wp.getUsersBlogs'		=> 'this:wp_getUsersBlogs',
    64 			'wp.getUsersBlogs'                 => 'this:wp_getUsersBlogs',
    65 			'wp.newPost'			=> 'this:wp_newPost',
    65 			'wp.newPost'                       => 'this:wp_newPost',
    66 			'wp.editPost'			=> 'this:wp_editPost',
    66 			'wp.editPost'                      => 'this:wp_editPost',
    67 			'wp.deletePost'			=> 'this:wp_deletePost',
    67 			'wp.deletePost'                    => 'this:wp_deletePost',
    68 			'wp.getPost'			=> 'this:wp_getPost',
    68 			'wp.getPost'                       => 'this:wp_getPost',
    69 			'wp.getPosts'			=> 'this:wp_getPosts',
    69 			'wp.getPosts'                      => 'this:wp_getPosts',
    70 			'wp.newTerm'			=> 'this:wp_newTerm',
    70 			'wp.newTerm'                       => 'this:wp_newTerm',
    71 			'wp.editTerm'			=> 'this:wp_editTerm',
    71 			'wp.editTerm'                      => 'this:wp_editTerm',
    72 			'wp.deleteTerm'			=> 'this:wp_deleteTerm',
    72 			'wp.deleteTerm'                    => 'this:wp_deleteTerm',
    73 			'wp.getTerm'			=> 'this:wp_getTerm',
    73 			'wp.getTerm'                       => 'this:wp_getTerm',
    74 			'wp.getTerms'			=> 'this:wp_getTerms',
    74 			'wp.getTerms'                      => 'this:wp_getTerms',
    75 			'wp.getTaxonomy'		=> 'this:wp_getTaxonomy',
    75 			'wp.getTaxonomy'                   => 'this:wp_getTaxonomy',
    76 			'wp.getTaxonomies'		=> 'this:wp_getTaxonomies',
    76 			'wp.getTaxonomies'                 => 'this:wp_getTaxonomies',
    77 			'wp.getUser'			=> 'this:wp_getUser',
    77 			'wp.getUser'                       => 'this:wp_getUser',
    78 			'wp.getUsers'			=> 'this:wp_getUsers',
    78 			'wp.getUsers'                      => 'this:wp_getUsers',
    79 			'wp.getProfile'			=> 'this:wp_getProfile',
    79 			'wp.getProfile'                    => 'this:wp_getProfile',
    80 			'wp.editProfile'		=> 'this:wp_editProfile',
    80 			'wp.editProfile'                   => 'this:wp_editProfile',
    81 			'wp.getPage'			=> 'this:wp_getPage',
    81 			'wp.getPage'                       => 'this:wp_getPage',
    82 			'wp.getPages'			=> 'this:wp_getPages',
    82 			'wp.getPages'                      => 'this:wp_getPages',
    83 			'wp.newPage'			=> 'this:wp_newPage',
    83 			'wp.newPage'                       => 'this:wp_newPage',
    84 			'wp.deletePage'			=> 'this:wp_deletePage',
    84 			'wp.deletePage'                    => 'this:wp_deletePage',
    85 			'wp.editPage'			=> 'this:wp_editPage',
    85 			'wp.editPage'                      => 'this:wp_editPage',
    86 			'wp.getPageList'		=> 'this:wp_getPageList',
    86 			'wp.getPageList'                   => 'this:wp_getPageList',
    87 			'wp.getAuthors'			=> 'this:wp_getAuthors',
    87 			'wp.getAuthors'                    => 'this:wp_getAuthors',
    88 			'wp.getCategories'		=> 'this:mw_getCategories',		// Alias
    88 			'wp.getCategories'                 => 'this:mw_getCategories',     // Alias
    89 			'wp.getTags'			=> 'this:wp_getTags',
    89 			'wp.getTags'                       => 'this:wp_getTags',
    90 			'wp.newCategory'		=> 'this:wp_newCategory',
    90 			'wp.newCategory'                   => 'this:wp_newCategory',
    91 			'wp.deleteCategory'		=> 'this:wp_deleteCategory',
    91 			'wp.deleteCategory'                => 'this:wp_deleteCategory',
    92 			'wp.suggestCategories'	=> 'this:wp_suggestCategories',
    92 			'wp.suggestCategories'             => 'this:wp_suggestCategories',
    93 			'wp.uploadFile'			=> 'this:mw_newMediaObject',	// Alias
    93 			'wp.uploadFile'                    => 'this:mw_newMediaObject',    // Alias
    94 			'wp.deleteFile'			=> 'this:wp_deletePost',		// Alias
    94 			'wp.deleteFile'                    => 'this:wp_deletePost',        // Alias
    95 			'wp.getCommentCount'	=> 'this:wp_getCommentCount',
    95 			'wp.getCommentCount'               => 'this:wp_getCommentCount',
    96 			'wp.getPostStatusList'	=> 'this:wp_getPostStatusList',
    96 			'wp.getPostStatusList'             => 'this:wp_getPostStatusList',
    97 			'wp.getPageStatusList'	=> 'this:wp_getPageStatusList',
    97 			'wp.getPageStatusList'             => 'this:wp_getPageStatusList',
    98 			'wp.getPageTemplates'	=> 'this:wp_getPageTemplates',
    98 			'wp.getPageTemplates'              => 'this:wp_getPageTemplates',
    99 			'wp.getOptions'			=> 'this:wp_getOptions',
    99 			'wp.getOptions'                    => 'this:wp_getOptions',
   100 			'wp.setOptions'			=> 'this:wp_setOptions',
   100 			'wp.setOptions'                    => 'this:wp_setOptions',
   101 			'wp.getComment'			=> 'this:wp_getComment',
   101 			'wp.getComment'                    => 'this:wp_getComment',
   102 			'wp.getComments'		=> 'this:wp_getComments',
   102 			'wp.getComments'                   => 'this:wp_getComments',
   103 			'wp.deleteComment'		=> 'this:wp_deleteComment',
   103 			'wp.deleteComment'                 => 'this:wp_deleteComment',
   104 			'wp.editComment'		=> 'this:wp_editComment',
   104 			'wp.editComment'                   => 'this:wp_editComment',
   105 			'wp.newComment'			=> 'this:wp_newComment',
   105 			'wp.newComment'                    => 'this:wp_newComment',
   106 			'wp.getCommentStatusList' => 'this:wp_getCommentStatusList',
   106 			'wp.getCommentStatusList'          => 'this:wp_getCommentStatusList',
   107 			'wp.getMediaItem'		=> 'this:wp_getMediaItem',
   107 			'wp.getMediaItem'                  => 'this:wp_getMediaItem',
   108 			'wp.getMediaLibrary'	=> 'this:wp_getMediaLibrary',
   108 			'wp.getMediaLibrary'               => 'this:wp_getMediaLibrary',
   109 			'wp.getPostFormats'     => 'this:wp_getPostFormats',
   109 			'wp.getPostFormats'                => 'this:wp_getPostFormats',
   110 			'wp.getPostType'		=> 'this:wp_getPostType',
   110 			'wp.getPostType'                   => 'this:wp_getPostType',
   111 			'wp.getPostTypes'		=> 'this:wp_getPostTypes',
   111 			'wp.getPostTypes'                  => 'this:wp_getPostTypes',
   112 			'wp.getRevisions'		=> 'this:wp_getRevisions',
   112 			'wp.getRevisions'                  => 'this:wp_getRevisions',
   113 			'wp.restoreRevision'	=> 'this:wp_restoreRevision',
   113 			'wp.restoreRevision'               => 'this:wp_restoreRevision',
   114 
   114 
   115 			// Blogger API
   115 			// Blogger API
   116 			'blogger.getUsersBlogs' => 'this:blogger_getUsersBlogs',
   116 			'blogger.getUsersBlogs'            => 'this:blogger_getUsersBlogs',
   117 			'blogger.getUserInfo' => 'this:blogger_getUserInfo',
   117 			'blogger.getUserInfo'              => 'this:blogger_getUserInfo',
   118 			'blogger.getPost' => 'this:blogger_getPost',
   118 			'blogger.getPost'                  => 'this:blogger_getPost',
   119 			'blogger.getRecentPosts' => 'this:blogger_getRecentPosts',
   119 			'blogger.getRecentPosts'           => 'this:blogger_getRecentPosts',
   120 			'blogger.newPost' => 'this:blogger_newPost',
   120 			'blogger.newPost'                  => 'this:blogger_newPost',
   121 			'blogger.editPost' => 'this:blogger_editPost',
   121 			'blogger.editPost'                 => 'this:blogger_editPost',
   122 			'blogger.deletePost' => 'this:blogger_deletePost',
   122 			'blogger.deletePost'               => 'this:blogger_deletePost',
   123 
   123 
   124 			// MetaWeblog API (with MT extensions to structs)
   124 			// MetaWeblog API (with MT extensions to structs)
   125 			'metaWeblog.newPost' => 'this:mw_newPost',
   125 			'metaWeblog.newPost'               => 'this:mw_newPost',
   126 			'metaWeblog.editPost' => 'this:mw_editPost',
   126 			'metaWeblog.editPost'              => 'this:mw_editPost',
   127 			'metaWeblog.getPost' => 'this:mw_getPost',
   127 			'metaWeblog.getPost'               => 'this:mw_getPost',
   128 			'metaWeblog.getRecentPosts' => 'this:mw_getRecentPosts',
   128 			'metaWeblog.getRecentPosts'        => 'this:mw_getRecentPosts',
   129 			'metaWeblog.getCategories' => 'this:mw_getCategories',
   129 			'metaWeblog.getCategories'         => 'this:mw_getCategories',
   130 			'metaWeblog.newMediaObject' => 'this:mw_newMediaObject',
   130 			'metaWeblog.newMediaObject'        => 'this:mw_newMediaObject',
   131 
   131 
   132 			// MetaWeblog API aliases for Blogger API
   132 			// MetaWeblog API aliases for Blogger API
   133 			// see http://www.xmlrpc.com/stories/storyReader$2460
   133 			// see http://www.xmlrpc.com/stories/storyReader$2460
   134 			'metaWeblog.deletePost' => 'this:blogger_deletePost',
   134 			'metaWeblog.deletePost'            => 'this:blogger_deletePost',
   135 			'metaWeblog.getUsersBlogs' => 'this:blogger_getUsersBlogs',
   135 			'metaWeblog.getUsersBlogs'         => 'this:blogger_getUsersBlogs',
   136 
   136 
   137 			// MovableType API
   137 			// MovableType API
   138 			'mt.getCategoryList' => 'this:mt_getCategoryList',
   138 			'mt.getCategoryList'               => 'this:mt_getCategoryList',
   139 			'mt.getRecentPostTitles' => 'this:mt_getRecentPostTitles',
   139 			'mt.getRecentPostTitles'           => 'this:mt_getRecentPostTitles',
   140 			'mt.getPostCategories' => 'this:mt_getPostCategories',
   140 			'mt.getPostCategories'             => 'this:mt_getPostCategories',
   141 			'mt.setPostCategories' => 'this:mt_setPostCategories',
   141 			'mt.setPostCategories'             => 'this:mt_setPostCategories',
   142 			'mt.supportedMethods' => 'this:mt_supportedMethods',
   142 			'mt.supportedMethods'              => 'this:mt_supportedMethods',
   143 			'mt.supportedTextFilters' => 'this:mt_supportedTextFilters',
   143 			'mt.supportedTextFilters'          => 'this:mt_supportedTextFilters',
   144 			'mt.getTrackbackPings' => 'this:mt_getTrackbackPings',
   144 			'mt.getTrackbackPings'             => 'this:mt_getTrackbackPings',
   145 			'mt.publishPost' => 'this:mt_publishPost',
   145 			'mt.publishPost'                   => 'this:mt_publishPost',
   146 
   146 
   147 			// PingBack
   147 			// PingBack
   148 			'pingback.ping' => 'this:pingback_ping',
   148 			'pingback.ping'                    => 'this:pingback_ping',
   149 			'pingback.extensions.getPingbacks' => 'this:pingback_extensions_getPingbacks',
   149 			'pingback.extensions.getPingbacks' => 'this:pingback_extensions_getPingbacks',
   150 
   150 
   151 			'demo.sayHello' => 'this:sayHello',
   151 			'demo.sayHello'                    => 'this:sayHello',
   152 			'demo.addTwoNumbers' => 'this:addTwoNumbers'
   152 			'demo.addTwoNumbers'               => 'this:addTwoNumbers',
   153 		);
   153 		);
   154 
   154 
   155 		$this->initialise_blog_option_info();
   155 		$this->initialise_blog_option_info();
   156 
   156 
   157 		/**
   157 		/**
   169 	/**
   169 	/**
   170 	 * Make private/protected methods readable for backward compatibility.
   170 	 * Make private/protected methods readable for backward compatibility.
   171 	 *
   171 	 *
   172 	 * @since 4.0.0
   172 	 * @since 4.0.0
   173 	 *
   173 	 *
   174 	 * @param callable $name      Method to call.
   174 	 * @param string   $name      Method to call.
   175 	 * @param array    $arguments Arguments to pass when calling.
   175 	 * @param array    $arguments Arguments to pass when calling.
   176 	 * @return array|IXR_Error|false Return value of the callback, false otherwise.
   176 	 * @return array|IXR_Error|false Return value of the callback, false otherwise.
   177 	 */
   177 	 */
   178 	public function __call( $name, $arguments ) {
   178 	public function __call( $name, $arguments ) {
   179 		if ( '_multisite_getUsersBlogs' === $name ) {
   179 		if ( '_multisite_getUsersBlogs' === $name ) {
   186 	 * Serves the XML-RPC request.
   186 	 * Serves the XML-RPC request.
   187 	 *
   187 	 *
   188 	 * @since 2.9.0
   188 	 * @since 2.9.0
   189 	 */
   189 	 */
   190 	public function serve_request() {
   190 	public function serve_request() {
   191 		$this->IXR_Server($this->methods);
   191 		$this->IXR_Server( $this->methods );
   192 	}
   192 	}
   193 
   193 
   194 	/**
   194 	/**
   195 	 * Test XMLRPC API by saying, "Hello!" to client.
   195 	 * Test XMLRPC API by saying, "Hello!" to client.
   196 	 *
   196 	 *
   320 	 * @param string|array $data Escape single string or array of strings.
   320 	 * @param string|array $data Escape single string or array of strings.
   321 	 * @return string|void Returns with string is passed, alters by-reference
   321 	 * @return string|void Returns with string is passed, alters by-reference
   322 	 *                     when array is passed.
   322 	 *                     when array is passed.
   323 	 */
   323 	 */
   324 	public function escape( &$data ) {
   324 	public function escape( &$data ) {
   325 		if ( ! is_array( $data ) )
   325 		if ( ! is_array( $data ) ) {
   326 			return wp_slash( $data );
   326 			return wp_slash( $data );
       
   327 		}
   327 
   328 
   328 		foreach ( $data as &$v ) {
   329 		foreach ( $data as &$v ) {
   329 			if ( is_array( $v ) )
   330 			if ( is_array( $v ) ) {
   330 				$this->escape( $v );
   331 				$this->escape( $v );
   331 			elseif ( ! is_object( $v ) )
   332 			} elseif ( ! is_object( $v ) ) {
   332 				$v = wp_slash( $v );
   333 				$v = wp_slash( $v );
       
   334 			}
   333 		}
   335 		}
   334 	}
   336 	}
   335 
   337 
   336 	/**
   338 	/**
   337 	 * Retrieve custom fields for post.
   339 	 * Retrieve custom fields for post.
   339 	 * @since 2.5.0
   341 	 * @since 2.5.0
   340 	 *
   342 	 *
   341 	 * @param int $post_id Post ID.
   343 	 * @param int $post_id Post ID.
   342 	 * @return array Custom fields, if exist.
   344 	 * @return array Custom fields, if exist.
   343 	 */
   345 	 */
   344 	public function get_custom_fields($post_id) {
   346 	public function get_custom_fields( $post_id ) {
   345 		$post_id = (int) $post_id;
   347 		$post_id = (int) $post_id;
   346 
   348 
   347 		$custom_fields = array();
   349 		$custom_fields = array();
   348 
   350 
   349 		foreach ( (array) has_meta($post_id) as $meta ) {
   351 		foreach ( (array) has_meta( $post_id ) as $meta ) {
   350 			// Don't expose protected fields.
   352 			// Don't expose protected fields.
   351 			if ( ! current_user_can( 'edit_post_meta', $post_id , $meta['meta_key'] ) )
   353 			if ( ! current_user_can( 'edit_post_meta', $post_id, $meta['meta_key'] ) ) {
   352 				continue;
   354 				continue;
       
   355 			}
   353 
   356 
   354 			$custom_fields[] = array(
   357 			$custom_fields[] = array(
   355 				"id"    => $meta['meta_id'],
   358 				'id'    => $meta['meta_id'],
   356 				"key"   => $meta['meta_key'],
   359 				'key'   => $meta['meta_key'],
   357 				"value" => $meta['meta_value']
   360 				'value' => $meta['meta_value'],
   358 			);
   361 			);
   359 		}
   362 		}
   360 
   363 
   361 		return $custom_fields;
   364 		return $custom_fields;
   362 	}
   365 	}
   367 	 * @since 2.5.0
   370 	 * @since 2.5.0
   368 	 *
   371 	 *
   369 	 * @param int $post_id Post ID.
   372 	 * @param int $post_id Post ID.
   370 	 * @param array $fields Custom fields.
   373 	 * @param array $fields Custom fields.
   371 	 */
   374 	 */
   372 	public function set_custom_fields($post_id, $fields) {
   375 	public function set_custom_fields( $post_id, $fields ) {
   373 		$post_id = (int) $post_id;
   376 		$post_id = (int) $post_id;
   374 
   377 
   375 		foreach ( (array) $fields as $meta ) {
   378 		foreach ( (array) $fields as $meta ) {
   376 			if ( isset($meta['id']) ) {
   379 			if ( isset( $meta['id'] ) ) {
   377 				$meta['id'] = (int) $meta['id'];
   380 				$meta['id'] = (int) $meta['id'];
   378 				$pmeta = get_metadata_by_mid( 'post', $meta['id'] );
   381 				$pmeta      = get_metadata_by_mid( 'post', $meta['id'] );
   379 
   382 
   380 				if ( ! $pmeta || $pmeta->post_id != $post_id ) {
   383 				if ( ! $pmeta || $pmeta->post_id != $post_id ) {
   381 					continue;
   384 					continue;
   382 				}
   385 				}
   383 
   386 
   384 				if ( isset($meta['key']) ) {
   387 				if ( isset( $meta['key'] ) ) {
   385 					$meta['key'] = wp_unslash( $meta['key'] );
   388 					$meta['key'] = wp_unslash( $meta['key'] );
   386 					if ( $meta['key'] !== $pmeta->meta_key )
   389 					if ( $meta['key'] !== $pmeta->meta_key ) {
   387 						continue;
   390 						continue;
       
   391 					}
   388 					$meta['value'] = wp_unslash( $meta['value'] );
   392 					$meta['value'] = wp_unslash( $meta['value'] );
   389 					if ( current_user_can( 'edit_post_meta', $post_id, $meta['key'] ) )
   393 					if ( current_user_can( 'edit_post_meta', $post_id, $meta['key'] ) ) {
   390 						update_metadata_by_mid( 'post', $meta['id'], $meta['value'] );
   394 						update_metadata_by_mid( 'post', $meta['id'], $meta['value'] );
       
   395 					}
   391 				} elseif ( current_user_can( 'delete_post_meta', $post_id, $pmeta->meta_key ) ) {
   396 				} elseif ( current_user_can( 'delete_post_meta', $post_id, $pmeta->meta_key ) ) {
   392 					delete_metadata_by_mid( 'post', $meta['id'] );
   397 					delete_metadata_by_mid( 'post', $meta['id'] );
   393 				}
   398 				}
   394 			} elseif ( current_user_can( 'add_post_meta', $post_id, wp_unslash( $meta['key'] ) ) ) {
   399 			} elseif ( current_user_can( 'add_post_meta', $post_id, wp_unslash( $meta['key'] ) ) ) {
   395 				add_post_meta( $post_id, $meta['key'], $meta['value'] );
   400 				add_post_meta( $post_id, $meta['key'], $meta['value'] );
   438 		$term_id = (int) $term_id;
   443 		$term_id = (int) $term_id;
   439 
   444 
   440 		foreach ( (array) $fields as $meta ) {
   445 		foreach ( (array) $fields as $meta ) {
   441 			if ( isset( $meta['id'] ) ) {
   446 			if ( isset( $meta['id'] ) ) {
   442 				$meta['id'] = (int) $meta['id'];
   447 				$meta['id'] = (int) $meta['id'];
   443 				$pmeta = get_metadata_by_mid( 'term', $meta['id'] );
   448 				$pmeta      = get_metadata_by_mid( 'term', $meta['id'] );
   444 				if ( isset( $meta['key'] ) ) {
   449 				if ( isset( $meta['key'] ) ) {
   445 					$meta['key'] = wp_unslash( $meta['key'] );
   450 					$meta['key'] = wp_unslash( $meta['key'] );
   446 					if ( $meta['key'] !== $pmeta->meta_key ) {
   451 					if ( $meta['key'] !== $pmeta->meta_key ) {
   447 						continue;
   452 						continue;
   448 					}
   453 					}
   467 	 * @since 2.6.0
   472 	 * @since 2.6.0
   468 	 */
   473 	 */
   469 	public function initialise_blog_option_info() {
   474 	public function initialise_blog_option_info() {
   470 		$this->blog_options = array(
   475 		$this->blog_options = array(
   471 			// Read only options
   476 			// Read only options
   472 			'software_name'     => array(
   477 			'software_name'           => array(
   473 				'desc'          => __( 'Software Name' ),
   478 				'desc'     => __( 'Software Name' ),
   474 				'readonly'      => true,
   479 				'readonly' => true,
   475 				'value'         => 'WordPress'
   480 				'value'    => 'WordPress',
   476 			),
   481 			),
   477 			'software_version'  => array(
   482 			'software_version'        => array(
   478 				'desc'          => __( 'Software Version' ),
   483 				'desc'     => __( 'Software Version' ),
   479 				'readonly'      => true,
   484 				'readonly' => true,
   480 				'value'         => get_bloginfo( 'version' )
   485 				'value'    => get_bloginfo( 'version' ),
   481 			),
   486 			),
   482 			'blog_url'          => array(
   487 			'blog_url'                => array(
   483 				'desc'          => __( 'WordPress Address (URL)' ),
   488 				'desc'     => __( 'WordPress Address (URL)' ),
   484 				'readonly'      => true,
   489 				'readonly' => true,
   485 				'option'        => 'siteurl'
   490 				'option'   => 'siteurl',
   486 			),
   491 			),
   487 			'home_url'          => array(
   492 			'home_url'                => array(
   488 				'desc'          => __( 'Site Address (URL)' ),
   493 				'desc'     => __( 'Site Address (URL)' ),
   489 				'readonly'      => true,
   494 				'readonly' => true,
   490 				'option'        => 'home'
   495 				'option'   => 'home',
   491 			),
   496 			),
   492 			'login_url'          => array(
   497 			'login_url'               => array(
   493 				'desc'          => __( 'Login Address (URL)' ),
   498 				'desc'     => __( 'Login Address (URL)' ),
   494 				'readonly'      => true,
   499 				'readonly' => true,
   495 				'value'         => wp_login_url( )
   500 				'value'    => wp_login_url(),
   496 			),
   501 			),
   497 			'admin_url'          => array(
   502 			'admin_url'               => array(
   498 				'desc'          => __( 'The URL to the admin area' ),
   503 				'desc'     => __( 'The URL to the admin area' ),
   499 				'readonly'      => true,
   504 				'readonly' => true,
   500 				'value'         => get_admin_url( )
   505 				'value'    => get_admin_url(),
   501 			),
   506 			),
   502 			'image_default_link_type' => array(
   507 			'image_default_link_type' => array(
   503 				'desc'          => __( 'Image default link type' ),
   508 				'desc'     => __( 'Image default link type' ),
   504 				'readonly'      => true,
   509 				'readonly' => true,
   505 				'option'        => 'image_default_link_type'
   510 				'option'   => 'image_default_link_type',
   506 			),
   511 			),
   507 			'image_default_size' => array(
   512 			'image_default_size'      => array(
   508 				'desc'          => __( 'Image default size' ),
   513 				'desc'     => __( 'Image default size' ),
   509 				'readonly'      => true,
   514 				'readonly' => true,
   510 				'option'        => 'image_default_size'
   515 				'option'   => 'image_default_size',
   511 			),
   516 			),
   512 			'image_default_align' => array(
   517 			'image_default_align'     => array(
   513 				'desc'          => __( 'Image default align' ),
   518 				'desc'     => __( 'Image default align' ),
   514 				'readonly'      => true,
   519 				'readonly' => true,
   515 				'option'        => 'image_default_align'
   520 				'option'   => 'image_default_align',
   516 			),
   521 			),
   517 			'template'          => array(
   522 			'template'                => array(
   518 				'desc'          => __( 'Template' ),
   523 				'desc'     => __( 'Template' ),
   519 				'readonly'      => true,
   524 				'readonly' => true,
   520 				'option'        => 'template'
   525 				'option'   => 'template',
   521 			),
   526 			),
   522 			'stylesheet'        => array(
   527 			'stylesheet'              => array(
   523 				'desc'          => __( 'Stylesheet' ),
   528 				'desc'     => __( 'Stylesheet' ),
   524 				'readonly'      => true,
   529 				'readonly' => true,
   525 				'option'        => 'stylesheet'
   530 				'option'   => 'stylesheet',
   526 			),
   531 			),
   527 			'post_thumbnail'    => array(
   532 			'post_thumbnail'          => array(
   528 				'desc'          => __('Post Thumbnail'),
   533 				'desc'     => __( 'Post Thumbnail' ),
   529 				'readonly'      => true,
   534 				'readonly' => true,
   530 				'value'         => current_theme_supports( 'post-thumbnails' )
   535 				'value'    => current_theme_supports( 'post-thumbnails' ),
   531 			),
   536 			),
   532 
   537 
   533 			// Updatable options
   538 			// Updatable options
   534 			'time_zone'         => array(
   539 			'time_zone'               => array(
   535 				'desc'          => __( 'Time Zone' ),
   540 				'desc'     => __( 'Time Zone' ),
   536 				'readonly'      => false,
   541 				'readonly' => false,
   537 				'option'        => 'gmt_offset'
   542 				'option'   => 'gmt_offset',
   538 			),
   543 			),
   539 			'blog_title'        => array(
   544 			'blog_title'              => array(
   540 				'desc'          => __( 'Site Title' ),
   545 				'desc'     => __( 'Site Title' ),
   541 				'readonly'      => false,
   546 				'readonly' => false,
   542 				'option'        => 'blogname'
   547 				'option'   => 'blogname',
   543 			),
   548 			),
   544 			'blog_tagline'      => array(
   549 			'blog_tagline'            => array(
   545 				'desc'          => __( 'Site Tagline' ),
   550 				'desc'     => __( 'Site Tagline' ),
   546 				'readonly'      => false,
   551 				'readonly' => false,
   547 				'option'        => 'blogdescription'
   552 				'option'   => 'blogdescription',
   548 			),
   553 			),
   549 			'date_format'       => array(
   554 			'date_format'             => array(
   550 				'desc'          => __( 'Date Format' ),
   555 				'desc'     => __( 'Date Format' ),
   551 				'readonly'      => false,
   556 				'readonly' => false,
   552 				'option'        => 'date_format'
   557 				'option'   => 'date_format',
   553 			),
   558 			),
   554 			'time_format'       => array(
   559 			'time_format'             => array(
   555 				'desc'          => __( 'Time Format' ),
   560 				'desc'     => __( 'Time Format' ),
   556 				'readonly'      => false,
   561 				'readonly' => false,
   557 				'option'        => 'time_format'
   562 				'option'   => 'time_format',
   558 			),
   563 			),
   559 			'users_can_register' => array(
   564 			'users_can_register'      => array(
   560 				'desc'          => __( 'Allow new users to sign up' ),
   565 				'desc'     => __( 'Allow new users to sign up' ),
   561 				'readonly'      => false,
   566 				'readonly' => false,
   562 				'option'        => 'users_can_register'
   567 				'option'   => 'users_can_register',
   563 			),
   568 			),
   564 			'thumbnail_size_w'  => array(
   569 			'thumbnail_size_w'        => array(
   565 				'desc'          => __( 'Thumbnail Width' ),
   570 				'desc'     => __( 'Thumbnail Width' ),
   566 				'readonly'      => false,
   571 				'readonly' => false,
   567 				'option'        => 'thumbnail_size_w'
   572 				'option'   => 'thumbnail_size_w',
   568 			),
   573 			),
   569 			'thumbnail_size_h'  => array(
   574 			'thumbnail_size_h'        => array(
   570 				'desc'          => __( 'Thumbnail Height' ),
   575 				'desc'     => __( 'Thumbnail Height' ),
   571 				'readonly'      => false,
   576 				'readonly' => false,
   572 				'option'        => 'thumbnail_size_h'
   577 				'option'   => 'thumbnail_size_h',
   573 			),
   578 			),
   574 			'thumbnail_crop'    => array(
   579 			'thumbnail_crop'          => array(
   575 				'desc'          => __( 'Crop thumbnail to exact dimensions' ),
   580 				'desc'     => __( 'Crop thumbnail to exact dimensions' ),
   576 				'readonly'      => false,
   581 				'readonly' => false,
   577 				'option'        => 'thumbnail_crop'
   582 				'option'   => 'thumbnail_crop',
   578 			),
   583 			),
   579 			'medium_size_w'     => array(
   584 			'medium_size_w'           => array(
   580 				'desc'          => __( 'Medium size image width' ),
   585 				'desc'     => __( 'Medium size image width' ),
   581 				'readonly'      => false,
   586 				'readonly' => false,
   582 				'option'        => 'medium_size_w'
   587 				'option'   => 'medium_size_w',
   583 			),
   588 			),
   584 			'medium_size_h'     => array(
   589 			'medium_size_h'           => array(
   585 				'desc'          => __( 'Medium size image height' ),
   590 				'desc'     => __( 'Medium size image height' ),
   586 				'readonly'      => false,
   591 				'readonly' => false,
   587 				'option'        => 'medium_size_h'
   592 				'option'   => 'medium_size_h',
   588 			),
   593 			),
   589 			'medium_large_size_w'   => array(
   594 			'medium_large_size_w'     => array(
   590 				'desc'          => __( 'Medium-Large size image width' ),
   595 				'desc'     => __( 'Medium-Large size image width' ),
   591 				'readonly'      => false,
   596 				'readonly' => false,
   592 				'option'        => 'medium_large_size_w'
   597 				'option'   => 'medium_large_size_w',
   593 			),
   598 			),
   594 			'medium_large_size_h'   => array(
   599 			'medium_large_size_h'     => array(
   595 				'desc'          => __( 'Medium-Large size image height' ),
   600 				'desc'     => __( 'Medium-Large size image height' ),
   596 				'readonly'      => false,
   601 				'readonly' => false,
   597 				'option'        => 'medium_large_size_h'
   602 				'option'   => 'medium_large_size_h',
   598 			),
   603 			),
   599 			'large_size_w'      => array(
   604 			'large_size_w'            => array(
   600 				'desc'          => __( 'Large size image width' ),
   605 				'desc'     => __( 'Large size image width' ),
   601 				'readonly'      => false,
   606 				'readonly' => false,
   602 				'option'        => 'large_size_w'
   607 				'option'   => 'large_size_w',
   603 			),
   608 			),
   604 			'large_size_h'      => array(
   609 			'large_size_h'            => array(
   605 				'desc'          => __( 'Large size image height' ),
   610 				'desc'     => __( 'Large size image height' ),
   606 				'readonly'      => false,
   611 				'readonly' => false,
   607 				'option'        => 'large_size_h'
   612 				'option'   => 'large_size_h',
   608 			),
   613 			),
   609 			'default_comment_status' => array(
   614 			'default_comment_status'  => array(
   610 				'desc'          => __( 'Allow people to post comments on new articles' ),
   615 				'desc'     => __( 'Allow people to post comments on new articles' ),
   611 				'readonly'      => false,
   616 				'readonly' => false,
   612 				'option'        => 'default_comment_status'
   617 				'option'   => 'default_comment_status',
   613 			),
   618 			),
   614 			'default_ping_status' => array(
   619 			'default_ping_status'     => array(
   615 				'desc'          => __( 'Allow link notifications from other blogs (pingbacks and trackbacks) on new articles' ),
   620 				'desc'     => __( 'Allow link notifications from other blogs (pingbacks and trackbacks) on new articles' ),
   616 				'readonly'      => false,
   621 				'readonly' => false,
   617 				'option'        => 'default_ping_status'
   622 				'option'   => 'default_ping_status',
   618 			)
   623 			),
   619 		);
   624 		);
   620 
   625 
   621 		/**
   626 		/**
   622 		 * Filters the XML-RPC blog options property.
   627 		 * Filters the XML-RPC blog options property.
   623 		 *
   628 		 *
   651 		if ( ! $this->minimum_args( $args, 2 ) ) {
   656 		if ( ! $this->minimum_args( $args, 2 ) ) {
   652 			return $this->error;
   657 			return $this->error;
   653 		}
   658 		}
   654 
   659 
   655 		// If this isn't on WPMU then just use blogger_getUsersBlogs
   660 		// If this isn't on WPMU then just use blogger_getUsersBlogs
   656 		if ( !is_multisite() ) {
   661 		if ( ! is_multisite() ) {
   657 			array_unshift( $args, 1 );
   662 			array_unshift( $args, 1 );
   658 			return $this->blogger_getUsersBlogs( $args );
   663 			return $this->blogger_getUsersBlogs( $args );
   659 		}
   664 		}
   660 
   665 
   661 		$this->escape( $args );
   666 		$this->escape( $args );
   662 
   667 
   663 		$username = $args[0];
   668 		$username = $args[0];
   664 		$password = $args[1];
   669 		$password = $args[1];
   665 
   670 
   666 		if ( !$user = $this->login($username, $password) )
   671 		if ( ! $user = $this->login( $username, $password ) ) {
   667 			return $this->error;
   672 			return $this->error;
       
   673 		}
   668 
   674 
   669 		/**
   675 		/**
   670 		 * Fires after the XML-RPC user has been authenticated but before the rest of
   676 		 * Fires after the XML-RPC user has been authenticated but before the rest of
   671 		 * the method logic begins.
   677 		 * the method logic begins.
   672 		 *
   678 		 *
   677 		 *
   683 		 *
   678 		 * @param string $name The method name.
   684 		 * @param string $name The method name.
   679 		 */
   685 		 */
   680 		do_action( 'xmlrpc_call', 'wp.getUsersBlogs' );
   686 		do_action( 'xmlrpc_call', 'wp.getUsersBlogs' );
   681 
   687 
   682 		$blogs = (array) get_blogs_of_user( $user->ID );
   688 		$blogs           = (array) get_blogs_of_user( $user->ID );
   683 		$struct = array();
   689 		$struct          = array();
   684 		$primary_blog_id = 0;
   690 		$primary_blog_id = 0;
   685 		$active_blog = get_active_blog_for_user( $user->ID );
   691 		$active_blog     = get_active_blog_for_user( $user->ID );
   686 		if ( $active_blog ) {
   692 		if ( $active_blog ) {
   687 			$primary_blog_id = (int) $active_blog->blog_id;
   693 			$primary_blog_id = (int) $active_blog->blog_id;
   688 		}
   694 		}
   689 
   695 
   690 		foreach ( $blogs as $blog ) {
   696 		foreach ( $blogs as $blog ) {
   691 			// Don't include blogs that aren't hosted at this site.
   697 			// Don't include blogs that aren't hosted at this site.
   692 			if ( $blog->site_id != get_current_network_id() )
   698 			if ( $blog->site_id != get_current_network_id() ) {
   693 				continue;
   699 				continue;
       
   700 			}
   694 
   701 
   695 			$blog_id = $blog->userblog_id;
   702 			$blog_id = $blog->userblog_id;
   696 
   703 
   697 			switch_to_blog( $blog_id );
   704 			switch_to_blog( $blog_id );
   698 
   705 
   699 			$is_admin = current_user_can( 'manage_options' );
   706 			$is_admin   = current_user_can( 'manage_options' );
   700 			$is_primary = ( (int) $blog_id === $primary_blog_id );
   707 			$is_primary = ( (int) $blog_id === $primary_blog_id );
   701 
   708 
   702 			$struct[] = array(
   709 			$struct[] = array(
   703 				'isAdmin'   => $is_admin,
   710 				'isAdmin'   => $is_admin,
   704 				'isPrimary' => $is_primary,
   711 				'isPrimary' => $is_primary,
   733 	}
   740 	}
   734 
   741 
   735 	/**
   742 	/**
   736 	 * Prepares taxonomy data for return in an XML-RPC object.
   743 	 * Prepares taxonomy data for return in an XML-RPC object.
   737 	 *
   744 	 *
   738 	 *
       
   739 	 * @param object $taxonomy The unprepared taxonomy data.
   745 	 * @param object $taxonomy The unprepared taxonomy data.
   740 	 * @param array $fields    The subset of taxonomy fields to return.
   746 	 * @param array $fields    The subset of taxonomy fields to return.
   741 	 * @return array The prepared taxonomy data.
   747 	 * @return array The prepared taxonomy data.
   742 	 */
   748 	 */
   743 	protected function _prepare_taxonomy( $taxonomy, $fields ) {
   749 	protected function _prepare_taxonomy( $taxonomy, $fields ) {
   744 		$_taxonomy = array(
   750 		$_taxonomy = array(
   745 			'name' => $taxonomy->name,
   751 			'name'         => $taxonomy->name,
   746 			'label' => $taxonomy->label,
   752 			'label'        => $taxonomy->label,
   747 			'hierarchical' => (bool) $taxonomy->hierarchical,
   753 			'hierarchical' => (bool) $taxonomy->hierarchical,
   748 			'public' => (bool) $taxonomy->public,
   754 			'public'       => (bool) $taxonomy->public,
   749 			'show_ui' => (bool) $taxonomy->show_ui,
   755 			'show_ui'      => (bool) $taxonomy->show_ui,
   750 			'_builtin' => (bool) $taxonomy->_builtin,
   756 			'_builtin'     => (bool) $taxonomy->_builtin,
   751 		);
   757 		);
   752 
   758 
   753 		if ( in_array( 'labels', $fields ) )
   759 		if ( in_array( 'labels', $fields ) ) {
   754 			$_taxonomy['labels'] = (array) $taxonomy->labels;
   760 			$_taxonomy['labels'] = (array) $taxonomy->labels;
   755 
   761 		}
   756 		if ( in_array( 'cap', $fields ) )
   762 
       
   763 		if ( in_array( 'cap', $fields ) ) {
   757 			$_taxonomy['cap'] = (array) $taxonomy->cap;
   764 			$_taxonomy['cap'] = (array) $taxonomy->cap;
   758 
   765 		}
   759 		if ( in_array( 'menu', $fields ) )
   766 
       
   767 		if ( in_array( 'menu', $fields ) ) {
   760 			$_taxonomy['show_in_menu'] = (bool) $_taxonomy->show_in_menu;
   768 			$_taxonomy['show_in_menu'] = (bool) $_taxonomy->show_in_menu;
   761 
   769 		}
   762 		if ( in_array( 'object_type', $fields ) )
   770 
       
   771 		if ( in_array( 'object_type', $fields ) ) {
   763 			$_taxonomy['object_type'] = array_unique( (array) $taxonomy->object_type );
   772 			$_taxonomy['object_type'] = array_unique( (array) $taxonomy->object_type );
       
   773 		}
   764 
   774 
   765 		/**
   775 		/**
   766 		 * Filters XML-RPC-prepared data for the given taxonomy.
   776 		 * Filters XML-RPC-prepared data for the given taxonomy.
   767 		 *
   777 		 *
   768 		 * @since 3.4.0
   778 		 * @since 3.4.0
   775 	}
   785 	}
   776 
   786 
   777 	/**
   787 	/**
   778 	 * Prepares term data for return in an XML-RPC object.
   788 	 * Prepares term data for return in an XML-RPC object.
   779 	 *
   789 	 *
   780 	 *
       
   781 	 * @param array|object $term The unprepared term data.
   790 	 * @param array|object $term The unprepared term data.
   782 	 * @return array The prepared term data.
   791 	 * @return array The prepared term data.
   783 	 */
   792 	 */
   784 	protected function _prepare_term( $term ) {
   793 	protected function _prepare_term( $term ) {
   785 		$_term = $term;
   794 		$_term = $term;
   786 		if ( ! is_array( $_term ) )
   795 		if ( ! is_array( $_term ) ) {
   787 			$_term = get_object_vars( $_term );
   796 			$_term = get_object_vars( $_term );
       
   797 		}
   788 
   798 
   789 		// For integers which may be larger than XML-RPC supports ensure we return strings.
   799 		// For integers which may be larger than XML-RPC supports ensure we return strings.
   790 		$_term['term_id'] = strval( $_term['term_id'] );
   800 		$_term['term_id']          = strval( $_term['term_id'] );
   791 		$_term['term_group'] = strval( $_term['term_group'] );
   801 		$_term['term_group']       = strval( $_term['term_group'] );
   792 		$_term['term_taxonomy_id'] = strval( $_term['term_taxonomy_id'] );
   802 		$_term['term_taxonomy_id'] = strval( $_term['term_taxonomy_id'] );
   793 		$_term['parent'] = strval( $_term['parent'] );
   803 		$_term['parent']           = strval( $_term['parent'] );
   794 
   804 
   795 		// Count we are happy to return as an integer because people really shouldn't use terms that much.
   805 		// Count we are happy to return as an integer because people really shouldn't use terms that much.
   796 		$_term['count'] = intval( $_term['count'] );
   806 		$_term['count'] = intval( $_term['count'] );
   797 
   807 
   798 		// Get term meta.
   808 		// Get term meta.
   810 	}
   820 	}
   811 
   821 
   812 	/**
   822 	/**
   813 	 * Convert a WordPress date string to an IXR_Date object.
   823 	 * Convert a WordPress date string to an IXR_Date object.
   814 	 *
   824 	 *
   815 	 *
       
   816 	 * @param string $date Date string to convert.
   825 	 * @param string $date Date string to convert.
   817 	 * @return IXR_Date IXR_Date object.
   826 	 * @return IXR_Date IXR_Date object.
   818 	 */
   827 	 */
   819 	protected function _convert_date( $date ) {
   828 	protected function _convert_date( $date ) {
   820 		if ( $date === '0000-00-00 00:00:00' ) {
   829 		if ( $date === '0000-00-00 00:00:00' ) {
   824 	}
   833 	}
   825 
   834 
   826 	/**
   835 	/**
   827 	 * Convert a WordPress GMT date string to an IXR_Date object.
   836 	 * Convert a WordPress GMT date string to an IXR_Date object.
   828 	 *
   837 	 *
   829 	 *
       
   830 	 * @param string $date_gmt WordPress GMT date string.
   838 	 * @param string $date_gmt WordPress GMT date string.
   831 	 * @param string $date     Date string.
   839 	 * @param string $date     Date string.
   832 	 * @return IXR_Date IXR_Date object.
   840 	 * @return IXR_Date IXR_Date object.
   833 	 */
   841 	 */
   834 	protected function _convert_date_gmt( $date_gmt, $date ) {
   842 	protected function _convert_date_gmt( $date_gmt, $date ) {
   838 		return $this->_convert_date( $date_gmt );
   846 		return $this->_convert_date( $date_gmt );
   839 	}
   847 	}
   840 
   848 
   841 	/**
   849 	/**
   842 	 * Prepares post data for return in an XML-RPC object.
   850 	 * Prepares post data for return in an XML-RPC object.
   843 	 *
       
   844 	 *
   851 	 *
   845 	 * @param array $post   The unprepared post data.
   852 	 * @param array $post   The unprepared post data.
   846 	 * @param array $fields The subset of post type fields to return.
   853 	 * @param array $fields The subset of post type fields to return.
   847 	 * @return array The prepared post data.
   854 	 * @return array The prepared post data.
   848 	 */
   855 	 */
   874 			'sticky'            => ( $post['post_type'] === 'post' && is_sticky( $post['ID'] ) ),
   881 			'sticky'            => ( $post['post_type'] === 'post' && is_sticky( $post['ID'] ) ),
   875 		);
   882 		);
   876 
   883 
   877 		// Thumbnail.
   884 		// Thumbnail.
   878 		$post_fields['post_thumbnail'] = array();
   885 		$post_fields['post_thumbnail'] = array();
   879 		$thumbnail_id = get_post_thumbnail_id( $post['ID'] );
   886 		$thumbnail_id                  = get_post_thumbnail_id( $post['ID'] );
   880 		if ( $thumbnail_id ) {
   887 		if ( $thumbnail_id ) {
   881 			$thumbnail_size = current_theme_supports('post-thumbnail') ? 'post-thumbnail' : 'thumbnail';
   888 			$thumbnail_size                = current_theme_supports( 'post-thumbnail' ) ? 'post-thumbnail' : 'thumbnail';
   882 			$post_fields['post_thumbnail'] = $this->_prepare_media_item( get_post( $thumbnail_id ), $thumbnail_size );
   889 			$post_fields['post_thumbnail'] = $this->_prepare_media_item( get_post( $thumbnail_id ), $thumbnail_size );
   883 		}
   890 		}
   884 
   891 
   885 		// Consider future posts as published.
   892 		// Consider future posts as published.
   886 		if ( $post_fields['post_status'] === 'future' )
   893 		if ( $post_fields['post_status'] === 'future' ) {
   887 			$post_fields['post_status'] = 'publish';
   894 			$post_fields['post_status'] = 'publish';
       
   895 		}
   888 
   896 
   889 		// Fill in blank post format.
   897 		// Fill in blank post format.
   890 		$post_fields['post_format'] = get_post_format( $post['ID'] );
   898 		$post_fields['post_format'] = get_post_format( $post['ID'] );
   891 		if ( empty( $post_fields['post_format'] ) )
   899 		if ( empty( $post_fields['post_format'] ) ) {
   892 			$post_fields['post_format'] = 'standard';
   900 			$post_fields['post_format'] = 'standard';
       
   901 		}
   893 
   902 
   894 		// Merge requested $post_fields fields into $_post.
   903 		// Merge requested $post_fields fields into $_post.
   895 		if ( in_array( 'post', $fields ) ) {
   904 		if ( in_array( 'post', $fields ) ) {
   896 			$_post = array_merge( $_post, $post_fields );
   905 			$_post = array_merge( $_post, $post_fields );
   897 		} else {
   906 		} else {
   898 			$requested_fields = array_intersect_key( $post_fields, array_flip( $fields ) );
   907 			$requested_fields = array_intersect_key( $post_fields, array_flip( $fields ) );
   899 			$_post = array_merge( $_post, $requested_fields );
   908 			$_post            = array_merge( $_post, $requested_fields );
   900 		}
   909 		}
   901 
   910 
   902 		$all_taxonomy_fields = in_array( 'taxonomies', $fields );
   911 		$all_taxonomy_fields = in_array( 'taxonomies', $fields );
   903 
   912 
   904 		if ( $all_taxonomy_fields || in_array( 'terms', $fields ) ) {
   913 		if ( $all_taxonomy_fields || in_array( 'terms', $fields ) ) {
   905 			$post_type_taxonomies = get_object_taxonomies( $post['post_type'], 'names' );
   914 			$post_type_taxonomies = get_object_taxonomies( $post['post_type'], 'names' );
   906 			$terms = wp_get_object_terms( $post['ID'], $post_type_taxonomies );
   915 			$terms                = wp_get_object_terms( $post['ID'], $post_type_taxonomies );
   907 			$_post['terms'] = array();
   916 			$_post['terms']       = array();
   908 			foreach ( $terms as $term ) {
   917 			foreach ( $terms as $term ) {
   909 				$_post['terms'][] = $this->_prepare_term( $term );
   918 				$_post['terms'][] = $this->_prepare_term( $term );
   910 			}
   919 			}
   911 		}
   920 		}
   912 
   921 
   913 		if ( in_array( 'custom_fields', $fields ) )
   922 		if ( in_array( 'custom_fields', $fields ) ) {
   914 			$_post['custom_fields'] = $this->get_custom_fields( $post['ID'] );
   923 			$_post['custom_fields'] = $this->get_custom_fields( $post['ID'] );
       
   924 		}
   915 
   925 
   916 		if ( in_array( 'enclosure', $fields ) ) {
   926 		if ( in_array( 'enclosure', $fields ) ) {
   917 			$_post['enclosure'] = array();
   927 			$_post['enclosure'] = array();
   918 			$enclosures = (array) get_post_meta( $post['ID'], 'enclosure' );
   928 			$enclosures         = (array) get_post_meta( $post['ID'], 'enclosure' );
   919 			if ( ! empty( $enclosures ) ) {
   929 			if ( ! empty( $enclosures ) ) {
   920 				$encdata = explode( "\n", $enclosures[0] );
   930 				$encdata                      = explode( "\n", $enclosures[0] );
   921 				$_post['enclosure']['url'] = trim( htmlspecialchars( $encdata[0] ) );
   931 				$_post['enclosure']['url']    = trim( htmlspecialchars( $encdata[0] ) );
   922 				$_post['enclosure']['length'] = (int) trim( $encdata[1] );
   932 				$_post['enclosure']['length'] = (int) trim( $encdata[1] );
   923 				$_post['enclosure']['type'] = trim( $encdata[2] );
   933 				$_post['enclosure']['type']   = trim( $encdata[2] );
   924 			}
   934 			}
   925 		}
   935 		}
   926 
   936 
   927 		/**
   937 		/**
   928 		 * Filters XML-RPC-prepared date for the given post.
   938 		 * Filters XML-RPC-prepared date for the given post.
   946 	 * @param array        $fields    The subset of post fields to return.
   956 	 * @param array        $fields    The subset of post fields to return.
   947 	 * @return array The prepared post type data.
   957 	 * @return array The prepared post type data.
   948 	 */
   958 	 */
   949 	protected function _prepare_post_type( $post_type, $fields ) {
   959 	protected function _prepare_post_type( $post_type, $fields ) {
   950 		$_post_type = array(
   960 		$_post_type = array(
   951 			'name' => $post_type->name,
   961 			'name'         => $post_type->name,
   952 			'label' => $post_type->label,
   962 			'label'        => $post_type->label,
   953 			'hierarchical' => (bool) $post_type->hierarchical,
   963 			'hierarchical' => (bool) $post_type->hierarchical,
   954 			'public' => (bool) $post_type->public,
   964 			'public'       => (bool) $post_type->public,
   955 			'show_ui' => (bool) $post_type->show_ui,
   965 			'show_ui'      => (bool) $post_type->show_ui,
   956 			'_builtin' => (bool) $post_type->_builtin,
   966 			'_builtin'     => (bool) $post_type->_builtin,
   957 			'has_archive' => (bool) $post_type->has_archive,
   967 			'has_archive'  => (bool) $post_type->has_archive,
   958 			'supports' => get_all_post_type_supports( $post_type->name ),
   968 			'supports'     => get_all_post_type_supports( $post_type->name ),
   959 		);
   969 		);
   960 
   970 
   961 		if ( in_array( 'labels', $fields ) ) {
   971 		if ( in_array( 'labels', $fields ) ) {
   962 			$_post_type['labels'] = (array) $post_type->labels;
   972 			$_post_type['labels'] = (array) $post_type->labels;
   963 		}
   973 		}
   964 
   974 
   965 		if ( in_array( 'cap', $fields ) ) {
   975 		if ( in_array( 'cap', $fields ) ) {
   966 			$_post_type['cap'] = (array) $post_type->cap;
   976 			$_post_type['cap']          = (array) $post_type->cap;
   967 			$_post_type['map_meta_cap'] = (bool) $post_type->map_meta_cap;
   977 			$_post_type['map_meta_cap'] = (bool) $post_type->map_meta_cap;
   968 		}
   978 		}
   969 
   979 
   970 		if ( in_array( 'menu', $fields ) ) {
   980 		if ( in_array( 'menu', $fields ) ) {
   971 			$_post_type['menu_position'] = (int) $post_type->menu_position;
   981 			$_post_type['menu_position'] = (int) $post_type->menu_position;
   972 			$_post_type['menu_icon'] = $post_type->menu_icon;
   982 			$_post_type['menu_icon']     = $post_type->menu_icon;
   973 			$_post_type['show_in_menu'] = (bool) $post_type->show_in_menu;
   983 			$_post_type['show_in_menu']  = (bool) $post_type->show_in_menu;
   974 		}
   984 		}
   975 
   985 
   976 		if ( in_array( 'taxonomies', $fields ) )
   986 		if ( in_array( 'taxonomies', $fields ) ) {
   977 			$_post_type['taxonomies'] = get_object_taxonomies( $post_type->name, 'names' );
   987 			$_post_type['taxonomies'] = get_object_taxonomies( $post_type->name, 'names' );
       
   988 		}
   978 
   989 
   979 		/**
   990 		/**
   980 		 * Filters XML-RPC-prepared date for the given post type.
   991 		 * Filters XML-RPC-prepared date for the given post type.
   981 		 *
   992 		 *
   982 		 * @since 3.4.0
   993 		 * @since 3.4.0
   989 	}
  1000 	}
   990 
  1001 
   991 	/**
  1002 	/**
   992 	 * Prepares media item data for return in an XML-RPC object.
  1003 	 * Prepares media item data for return in an XML-RPC object.
   993 	 *
  1004 	 *
   994 	 *
       
   995 	 * @param object $media_item     The unprepared media item data.
  1005 	 * @param object $media_item     The unprepared media item data.
   996 	 * @param string $thumbnail_size The image size to use for the thumbnail URL.
  1006 	 * @param string $thumbnail_size The image size to use for the thumbnail URL.
   997 	 * @return array The prepared media item data.
  1007 	 * @return array The prepared media item data.
   998 	 */
  1008 	 */
   999 	protected function _prepare_media_item( $media_item, $thumbnail_size = 'thumbnail' ) {
  1009 	protected function _prepare_media_item( $media_item, $thumbnail_size = 'thumbnail' ) {
  1004 			'link'             => wp_get_attachment_url( $media_item->ID ),
  1014 			'link'             => wp_get_attachment_url( $media_item->ID ),
  1005 			'title'            => $media_item->post_title,
  1015 			'title'            => $media_item->post_title,
  1006 			'caption'          => $media_item->post_excerpt,
  1016 			'caption'          => $media_item->post_excerpt,
  1007 			'description'      => $media_item->post_content,
  1017 			'description'      => $media_item->post_content,
  1008 			'metadata'         => wp_get_attachment_metadata( $media_item->ID ),
  1018 			'metadata'         => wp_get_attachment_metadata( $media_item->ID ),
  1009 			'type'             => $media_item->post_mime_type
  1019 			'type'             => $media_item->post_mime_type,
  1010 		);
  1020 		);
  1011 
  1021 
  1012 		$thumbnail_src = image_downsize( $media_item->ID, $thumbnail_size );
  1022 		$thumbnail_src = image_downsize( $media_item->ID, $thumbnail_size );
  1013 		if ( $thumbnail_src )
  1023 		if ( $thumbnail_src ) {
  1014 			$_media_item['thumbnail'] = $thumbnail_src[0];
  1024 			$_media_item['thumbnail'] = $thumbnail_src[0];
  1015 		else
  1025 		} else {
  1016 			$_media_item['thumbnail'] = $_media_item['link'];
  1026 			$_media_item['thumbnail'] = $_media_item['link'];
       
  1027 		}
  1017 
  1028 
  1018 		/**
  1029 		/**
  1019 		 * Filters XML-RPC-prepared data for the given media item.
  1030 		 * Filters XML-RPC-prepared data for the given media item.
  1020 		 *
  1031 		 *
  1021 		 * @since 3.4.0
  1032 		 * @since 3.4.0
  1028 	}
  1039 	}
  1029 
  1040 
  1030 	/**
  1041 	/**
  1031 	 * Prepares page data for return in an XML-RPC object.
  1042 	 * Prepares page data for return in an XML-RPC object.
  1032 	 *
  1043 	 *
  1033 	 *
       
  1034 	 * @param object $page The unprepared page data.
  1044 	 * @param object $page The unprepared page data.
  1035 	 * @return array The prepared page data.
  1045 	 * @return array The prepared page data.
  1036 	 */
  1046 	 */
  1037 	protected function _prepare_page( $page ) {
  1047 	protected function _prepare_page( $page ) {
  1038 		// Get all of the page content and link.
  1048 		// Get all of the page content and link.
  1039 		$full_page = get_extended( $page->post_content );
  1049 		$full_page = get_extended( $page->post_content );
  1040 		$link = get_permalink( $page->ID );
  1050 		$link      = get_permalink( $page->ID );
  1041 
  1051 
  1042 		// Get info the page parent if there is one.
  1052 		// Get info the page parent if there is one.
  1043 		$parent_title = "";
  1053 		$parent_title = '';
  1044 		if ( ! empty( $page->post_parent ) ) {
  1054 		if ( ! empty( $page->post_parent ) ) {
  1045 			$parent = get_post( $page->post_parent );
  1055 			$parent       = get_post( $page->post_parent );
  1046 			$parent_title = $parent->post_title;
  1056 			$parent_title = $parent->post_title;
  1047 		}
  1057 		}
  1048 
  1058 
  1049 		// Determine comment and ping settings.
  1059 		// Determine comment and ping settings.
  1050 		$allow_comments = comments_open( $page->ID ) ? 1 : 0;
  1060 		$allow_comments = comments_open( $page->ID ) ? 1 : 0;
  1051 		$allow_pings = pings_open( $page->ID ) ? 1 : 0;
  1061 		$allow_pings    = pings_open( $page->ID ) ? 1 : 0;
  1052 
  1062 
  1053 		// Format page date.
  1063 		// Format page date.
  1054 		$page_date = $this->_convert_date( $page->post_date );
  1064 		$page_date     = $this->_convert_date( $page->post_date );
  1055 		$page_date_gmt = $this->_convert_date_gmt( $page->post_date_gmt, $page->post_date );
  1065 		$page_date_gmt = $this->_convert_date_gmt( $page->post_date_gmt, $page->post_date );
  1056 
  1066 
  1057 		// Pull the categories info together.
  1067 		// Pull the categories info together.
  1058 		$categories = array();
  1068 		$categories = array();
  1059 		if ( is_object_in_taxonomy( 'page', 'category' ) ) {
  1069 		if ( is_object_in_taxonomy( 'page', 'category' ) ) {
  1064 
  1074 
  1065 		// Get the author info.
  1075 		// Get the author info.
  1066 		$author = get_userdata( $page->post_author );
  1076 		$author = get_userdata( $page->post_author );
  1067 
  1077 
  1068 		$page_template = get_page_template_slug( $page->ID );
  1078 		$page_template = get_page_template_slug( $page->ID );
  1069 		if ( empty( $page_template ) )
  1079 		if ( empty( $page_template ) ) {
  1070 			$page_template = 'default';
  1080 			$page_template = 'default';
       
  1081 		}
  1071 
  1082 
  1072 		$_page = array(
  1083 		$_page = array(
  1073 			'dateCreated'            => $page_date,
  1084 			'dateCreated'            => $page_date,
  1074 			'userid'                 => $page->post_author,
  1085 			'userid'                 => $page->post_author,
  1075 			'page_id'                => $page->ID,
  1086 			'page_id'                => $page->ID,
  1091 			'wp_page_order'          => $page->menu_order,
  1102 			'wp_page_order'          => $page->menu_order,
  1092 			'wp_author_id'           => (string) $author->ID,
  1103 			'wp_author_id'           => (string) $author->ID,
  1093 			'wp_author_display_name' => $author->display_name,
  1104 			'wp_author_display_name' => $author->display_name,
  1094 			'date_created_gmt'       => $page_date_gmt,
  1105 			'date_created_gmt'       => $page_date_gmt,
  1095 			'custom_fields'          => $this->get_custom_fields( $page->ID ),
  1106 			'custom_fields'          => $this->get_custom_fields( $page->ID ),
  1096 			'wp_page_template'       => $page_template
  1107 			'wp_page_template'       => $page_template,
  1097 		);
  1108 		);
  1098 
  1109 
  1099 		/**
  1110 		/**
  1100 		 * Filters XML-RPC-prepared data for the given page.
  1111 		 * Filters XML-RPC-prepared data for the given page.
  1101 		 *
  1112 		 *
  1108 	}
  1119 	}
  1109 
  1120 
  1110 	/**
  1121 	/**
  1111 	 * Prepares comment data for return in an XML-RPC object.
  1122 	 * Prepares comment data for return in an XML-RPC object.
  1112 	 *
  1123 	 *
  1113 	 *
       
  1114 	 * @param object $comment The unprepared comment data.
  1124 	 * @param object $comment The unprepared comment data.
  1115 	 * @return array The prepared comment data.
  1125 	 * @return array The prepared comment data.
  1116 	 */
  1126 	 */
  1117 	protected function _prepare_comment( $comment ) {
  1127 	protected function _prepare_comment( $comment ) {
  1118 		// Format page date.
  1128 		// Format page date.
  1132 			'user_id'          => $comment->user_id,
  1142 			'user_id'          => $comment->user_id,
  1133 			'comment_id'       => $comment->comment_ID,
  1143 			'comment_id'       => $comment->comment_ID,
  1134 			'parent'           => $comment->comment_parent,
  1144 			'parent'           => $comment->comment_parent,
  1135 			'status'           => $comment_status,
  1145 			'status'           => $comment_status,
  1136 			'content'          => $comment->comment_content,
  1146 			'content'          => $comment->comment_content,
  1137 			'link'             => get_comment_link($comment),
  1147 			'link'             => get_comment_link( $comment ),
  1138 			'post_id'          => $comment->comment_post_ID,
  1148 			'post_id'          => $comment->comment_post_ID,
  1139 			'post_title'       => get_the_title($comment->comment_post_ID),
  1149 			'post_title'       => get_the_title( $comment->comment_post_ID ),
  1140 			'author'           => $comment->comment_author,
  1150 			'author'           => $comment->comment_author,
  1141 			'author_url'       => $comment->comment_author_url,
  1151 			'author_url'       => $comment->comment_author_url,
  1142 			'author_email'     => $comment->comment_author_email,
  1152 			'author_email'     => $comment->comment_author_email,
  1143 			'author_ip'        => $comment->comment_author_IP,
  1153 			'author_ip'        => $comment->comment_author_IP,
  1144 			'type'             => $comment->comment_type,
  1154 			'type'             => $comment->comment_type,
  1156 	}
  1166 	}
  1157 
  1167 
  1158 	/**
  1168 	/**
  1159 	 * Prepares user data for return in an XML-RPC object.
  1169 	 * Prepares user data for return in an XML-RPC object.
  1160 	 *
  1170 	 *
  1161 	 *
       
  1162 	 * @param WP_User $user   The unprepared user object.
  1171 	 * @param WP_User $user   The unprepared user object.
  1163 	 * @param array   $fields The subset of user fields to return.
  1172 	 * @param array   $fields The subset of user fields to return.
  1164 	 * @return array The prepared user data.
  1173 	 * @return array The prepared user data.
  1165 	 */
  1174 	 */
  1166 	protected function _prepare_user( $user, $fields ) {
  1175 	protected function _prepare_user( $user, $fields ) {
  1167 		$_user = array( 'user_id' => strval( $user->ID ) );
  1176 		$_user = array( 'user_id' => strval( $user->ID ) );
  1168 
  1177 
  1169 		$user_fields = array(
  1178 		$user_fields = array(
  1170 			'username'          => $user->user_login,
  1179 			'username'     => $user->user_login,
  1171 			'first_name'        => $user->user_firstname,
  1180 			'first_name'   => $user->user_firstname,
  1172 			'last_name'         => $user->user_lastname,
  1181 			'last_name'    => $user->user_lastname,
  1173 			'registered'        => $this->_convert_date( $user->user_registered ),
  1182 			'registered'   => $this->_convert_date( $user->user_registered ),
  1174 			'bio'               => $user->user_description,
  1183 			'bio'          => $user->user_description,
  1175 			'email'             => $user->user_email,
  1184 			'email'        => $user->user_email,
  1176 			'nickname'          => $user->nickname,
  1185 			'nickname'     => $user->nickname,
  1177 			'nicename'          => $user->user_nicename,
  1186 			'nicename'     => $user->user_nicename,
  1178 			'url'               => $user->user_url,
  1187 			'url'          => $user->user_url,
  1179 			'display_name'      => $user->display_name,
  1188 			'display_name' => $user->display_name,
  1180 			'roles'             => $user->roles,
  1189 			'roles'        => $user->roles,
  1181 		);
  1190 		);
  1182 
  1191 
  1183 		if ( in_array( 'all', $fields ) ) {
  1192 		if ( in_array( 'all', $fields ) ) {
  1184 			$_user = array_merge( $_user, $user_fields );
  1193 			$_user = array_merge( $_user, $user_fields );
  1185 		} else {
  1194 		} else {
  1186 			if ( in_array( 'basic', $fields ) ) {
  1195 			if ( in_array( 'basic', $fields ) ) {
  1187 				$basic_fields = array( 'username', 'email', 'registered', 'display_name', 'nicename' );
  1196 				$basic_fields = array( 'username', 'email', 'registered', 'display_name', 'nicename' );
  1188 				$fields = array_merge( $fields, $basic_fields );
  1197 				$fields       = array_merge( $fields, $basic_fields );
  1189 			}
  1198 			}
  1190 			$requested_fields = array_intersect_key( $user_fields, array_flip( $fields ) );
  1199 			$requested_fields = array_intersect_key( $user_fields, array_flip( $fields ) );
  1191 			$_user = array_merge( $_user, $requested_fields );
  1200 			$_user            = array_merge( $_user, $requested_fields );
  1192 		}
  1201 		}
  1193 
  1202 
  1194 		/**
  1203 		/**
  1195 		 * Filters XML-RPC-prepared data for the given user.
  1204 		 * Filters XML-RPC-prepared data for the given user.
  1196 		 *
  1205 		 *
  1249 	 *     }
  1258 	 *     }
  1250 	 * }
  1259 	 * }
  1251 	 * @return int|IXR_Error Post ID on success, IXR_Error instance otherwise.
  1260 	 * @return int|IXR_Error Post ID on success, IXR_Error instance otherwise.
  1252 	 */
  1261 	 */
  1253 	public function wp_newPost( $args ) {
  1262 	public function wp_newPost( $args ) {
  1254 		if ( ! $this->minimum_args( $args, 4 ) )
  1263 		if ( ! $this->minimum_args( $args, 4 ) ) {
  1255 			return $this->error;
  1264 			return $this->error;
       
  1265 		}
  1256 
  1266 
  1257 		$this->escape( $args );
  1267 		$this->escape( $args );
  1258 
  1268 
  1259 		$username       = $args[1];
  1269 		$username       = $args[1];
  1260 		$password       = $args[2];
  1270 		$password       = $args[2];
  1261 		$content_struct = $args[3];
  1271 		$content_struct = $args[3];
  1262 
  1272 
  1263 		if ( ! $user = $this->login( $username, $password ) )
  1273 		if ( ! $user = $this->login( $username, $password ) ) {
  1264 			return $this->error;
  1274 			return $this->error;
       
  1275 		}
  1265 
  1276 
  1266 		// convert the date field back to IXR form
  1277 		// convert the date field back to IXR form
  1267 		if ( isset( $content_struct['post_date'] ) && ! ( $content_struct['post_date'] instanceof IXR_Date ) ) {
  1278 		if ( isset( $content_struct['post_date'] ) && ! ( $content_struct['post_date'] instanceof IXR_Date ) ) {
  1268 			$content_struct['post_date'] = $this->_convert_date( $content_struct['post_date'] );
  1279 			$content_struct['post_date'] = $this->_convert_date( $content_struct['post_date'] );
  1269 		}
  1280 		}
  1318 			}
  1329 			}
  1319 
  1330 
  1320 			if ( $update ) {
  1331 			if ( $update ) {
  1321 				unstick_post( $post_data['ID'] );
  1332 				unstick_post( $post_data['ID'] );
  1322 			}
  1333 			}
  1323 		} elseif ( isset( $post_data['sticky'] ) )  {
  1334 		} elseif ( isset( $post_data['sticky'] ) ) {
  1324 			if ( ! current_user_can( $post_type->cap->edit_others_posts ) ) {
  1335 			if ( ! current_user_can( $post_type->cap->edit_others_posts ) ) {
  1325 				return new IXR_Error( 401, __( 'Sorry, you are not allowed to make posts sticky.' ) );
  1336 				return new IXR_Error( 401, __( 'Sorry, you are not allowed to make posts sticky.' ) );
  1326 			}
  1337 			}
  1327 
  1338 
  1328 			$sticky = wp_validate_boolean( $post_data['sticky'] );
  1339 			$sticky = wp_validate_boolean( $post_data['sticky'] );
  1371 		);
  1382 		);
  1372 
  1383 
  1373 		$post_data = wp_parse_args( array_intersect_key( $content_struct, $defaults ), $defaults );
  1384 		$post_data = wp_parse_args( array_intersect_key( $content_struct, $defaults ), $defaults );
  1374 
  1385 
  1375 		$post_type = get_post_type_object( $post_data['post_type'] );
  1386 		$post_type = get_post_type_object( $post_data['post_type'] );
  1376 		if ( ! $post_type )
  1387 		if ( ! $post_type ) {
  1377 			return new IXR_Error( 403, __( 'Invalid post type.' ) );
  1388 			return new IXR_Error( 403, __( 'Invalid post type.' ) );
       
  1389 		}
  1378 
  1390 
  1379 		$update = ! empty( $post_data['ID'] );
  1391 		$update = ! empty( $post_data['ID'] );
  1380 
  1392 
  1381 		if ( $update ) {
  1393 		if ( $update ) {
  1382 			if ( ! get_post( $post_data['ID'] ) )
  1394 			if ( ! get_post( $post_data['ID'] ) ) {
  1383 				return new IXR_Error( 401, __( 'Invalid post ID.' ) );
  1395 				return new IXR_Error( 401, __( 'Invalid post ID.' ) );
  1384 			if ( ! current_user_can( 'edit_post', $post_data['ID'] ) )
  1396 			}
       
  1397 			if ( ! current_user_can( 'edit_post', $post_data['ID'] ) ) {
  1385 				return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit this post.' ) );
  1398 				return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit this post.' ) );
  1386 			if ( $post_data['post_type'] != get_post_type( $post_data['ID'] ) )
  1399 			}
       
  1400 			if ( $post_data['post_type'] != get_post_type( $post_data['ID'] ) ) {
  1387 				return new IXR_Error( 401, __( 'The post type may not be changed.' ) );
  1401 				return new IXR_Error( 401, __( 'The post type may not be changed.' ) );
       
  1402 			}
  1388 		} else {
  1403 		} else {
  1389 			if ( ! current_user_can( $post_type->cap->create_posts ) || ! current_user_can( $post_type->cap->edit_posts ) )
  1404 			if ( ! current_user_can( $post_type->cap->create_posts ) || ! current_user_can( $post_type->cap->edit_posts ) ) {
  1390 				return new IXR_Error( 401, __( 'Sorry, you are not allowed to post on this site.' ) );
  1405 				return new IXR_Error( 401, __( 'Sorry, you are not allowed to post on this site.' ) );
       
  1406 			}
  1391 		}
  1407 		}
  1392 
  1408 
  1393 		switch ( $post_data['post_status'] ) {
  1409 		switch ( $post_data['post_status'] ) {
  1394 			case 'draft':
  1410 			case 'draft':
  1395 			case 'pending':
  1411 			case 'pending':
  1396 				break;
  1412 				break;
  1397 			case 'private':
  1413 			case 'private':
  1398 				if ( ! current_user_can( $post_type->cap->publish_posts ) )
  1414 				if ( ! current_user_can( $post_type->cap->publish_posts ) ) {
  1399 					return new IXR_Error( 401, __( 'Sorry, you are not allowed to create private posts in this post type.' ) );
  1415 					return new IXR_Error( 401, __( 'Sorry, you are not allowed to create private posts in this post type.' ) );
       
  1416 				}
  1400 				break;
  1417 				break;
  1401 			case 'publish':
  1418 			case 'publish':
  1402 			case 'future':
  1419 			case 'future':
  1403 				if ( ! current_user_can( $post_type->cap->publish_posts ) )
  1420 				if ( ! current_user_can( $post_type->cap->publish_posts ) ) {
  1404 					return new IXR_Error( 401, __( 'Sorry, you are not allowed to publish posts in this post type.' ) );
  1421 					return new IXR_Error( 401, __( 'Sorry, you are not allowed to publish posts in this post type.' ) );
       
  1422 				}
  1405 				break;
  1423 				break;
  1406 			default:
  1424 			default:
  1407 				if ( ! get_post_status_object( $post_data['post_status'] ) )
  1425 				if ( ! get_post_status_object( $post_data['post_status'] ) ) {
  1408 					$post_data['post_status'] = 'draft';
  1426 					$post_data['post_status'] = 'draft';
  1409 			break;
  1427 				}
  1410 		}
  1428 				break;
  1411 
  1429 		}
  1412 		if ( ! empty( $post_data['post_password'] ) && ! current_user_can( $post_type->cap->publish_posts ) )
  1430 
       
  1431 		if ( ! empty( $post_data['post_password'] ) && ! current_user_can( $post_type->cap->publish_posts ) ) {
  1413 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to create password protected posts in this post type.' ) );
  1432 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to create password protected posts in this post type.' ) );
       
  1433 		}
  1414 
  1434 
  1415 		$post_data['post_author'] = absint( $post_data['post_author'] );
  1435 		$post_data['post_author'] = absint( $post_data['post_author'] );
  1416 		if ( ! empty( $post_data['post_author'] ) && $post_data['post_author'] != $user->ID ) {
  1436 		if ( ! empty( $post_data['post_author'] ) && $post_data['post_author'] != $user->ID ) {
  1417 			if ( ! current_user_can( $post_type->cap->edit_others_posts ) )
  1437 			if ( ! current_user_can( $post_type->cap->edit_others_posts ) ) {
  1418 				return new IXR_Error( 401, __( 'Sorry, you are not allowed to create posts as this user.' ) );
  1438 				return new IXR_Error( 401, __( 'Sorry, you are not allowed to create posts as this user.' ) );
       
  1439 			}
  1419 
  1440 
  1420 			$author = get_userdata( $post_data['post_author'] );
  1441 			$author = get_userdata( $post_data['post_author'] );
  1421 
  1442 
  1422 			if ( ! $author )
  1443 			if ( ! $author ) {
  1423 				return new IXR_Error( 404, __( 'Invalid author ID.' ) );
  1444 				return new IXR_Error( 404, __( 'Invalid author ID.' ) );
       
  1445 			}
  1424 		} else {
  1446 		} else {
  1425 			$post_data['post_author'] = $user->ID;
  1447 			$post_data['post_author'] = $user->ID;
  1426 		}
  1448 		}
  1427 
  1449 
  1428 		if ( isset( $post_data['comment_status'] ) && $post_data['comment_status'] != 'open' && $post_data['comment_status'] != 'closed' )
  1450 		if ( isset( $post_data['comment_status'] ) && $post_data['comment_status'] != 'open' && $post_data['comment_status'] != 'closed' ) {
  1429 			unset( $post_data['comment_status'] );
  1451 			unset( $post_data['comment_status'] );
  1430 
  1452 		}
  1431 		if ( isset( $post_data['ping_status'] ) && $post_data['ping_status'] != 'open' && $post_data['ping_status'] != 'closed' )
  1453 
       
  1454 		if ( isset( $post_data['ping_status'] ) && $post_data['ping_status'] != 'open' && $post_data['ping_status'] != 'closed' ) {
  1432 			unset( $post_data['ping_status'] );
  1455 			unset( $post_data['ping_status'] );
       
  1456 		}
  1433 
  1457 
  1434 		// Do some timestamp voodoo.
  1458 		// Do some timestamp voodoo.
  1435 		if ( ! empty( $post_data['post_date_gmt'] ) ) {
  1459 		if ( ! empty( $post_data['post_date_gmt'] ) ) {
  1436 			// We know this is supposed to be GMT, so we're going to slap that Z on there by force.
  1460 			// We know this is supposed to be GMT, so we're going to slap that Z on there by force.
  1437 			$dateCreated = rtrim( $post_data['post_date_gmt']->getIso(), 'Z' ) . 'Z';
  1461 			$dateCreated = rtrim( $post_data['post_date_gmt']->getIso(), 'Z' ) . 'Z';
  1441 
  1465 
  1442 		// Default to not flagging the post date to be edited unless it's intentional.
  1466 		// Default to not flagging the post date to be edited unless it's intentional.
  1443 		$post_data['edit_date'] = false;
  1467 		$post_data['edit_date'] = false;
  1444 
  1468 
  1445 		if ( ! empty( $dateCreated ) ) {
  1469 		if ( ! empty( $dateCreated ) ) {
  1446 			$post_data['post_date'] = get_date_from_gmt( iso8601_to_datetime( $dateCreated ) );
  1470 			$post_data['post_date']     = get_date_from_gmt( iso8601_to_datetime( $dateCreated ) );
  1447 			$post_data['post_date_gmt'] = iso8601_to_datetime( $dateCreated, 'GMT' );
  1471 			$post_data['post_date_gmt'] = iso8601_to_datetime( $dateCreated, 'GMT' );
  1448 
  1472 
  1449 			// Flag the post date to be edited.
  1473 			// Flag the post date to be edited.
  1450 			$post_data['edit_date'] = true;
  1474 			$post_data['edit_date'] = true;
  1451 		}
  1475 		}
  1452 
  1476 
  1453 		if ( ! isset( $post_data['ID'] ) )
  1477 		if ( ! isset( $post_data['ID'] ) ) {
  1454 			$post_data['ID'] = get_default_post_to_edit( $post_data['post_type'], true )->ID;
  1478 			$post_data['ID'] = get_default_post_to_edit( $post_data['post_type'], true )->ID;
       
  1479 		}
  1455 		$post_ID = $post_data['ID'];
  1480 		$post_ID = $post_data['ID'];
  1456 
  1481 
  1457 		if ( $post_data['post_type'] == 'post' ) {
  1482 		if ( $post_data['post_type'] == 'post' ) {
  1458 			$error = $this->_toggle_sticky( $post_data, $update );
  1483 			$error = $this->_toggle_sticky( $post_data, $update );
  1459 			if ( $error ) {
  1484 			if ( $error ) {
  1461 			}
  1486 			}
  1462 		}
  1487 		}
  1463 
  1488 
  1464 		if ( isset( $post_data['post_thumbnail'] ) ) {
  1489 		if ( isset( $post_data['post_thumbnail'] ) ) {
  1465 			// empty value deletes, non-empty value adds/updates.
  1490 			// empty value deletes, non-empty value adds/updates.
  1466 			if ( ! $post_data['post_thumbnail'] )
  1491 			if ( ! $post_data['post_thumbnail'] ) {
  1467 				delete_post_thumbnail( $post_ID );
  1492 				delete_post_thumbnail( $post_ID );
  1468 			elseif ( ! get_post( absint( $post_data['post_thumbnail'] ) ) )
  1493 			} elseif ( ! get_post( absint( $post_data['post_thumbnail'] ) ) ) {
  1469 				return new IXR_Error( 404, __( 'Invalid attachment ID.' ) );
  1494 				return new IXR_Error( 404, __( 'Invalid attachment ID.' ) );
       
  1495 			}
  1470 			set_post_thumbnail( $post_ID, $post_data['post_thumbnail'] );
  1496 			set_post_thumbnail( $post_ID, $post_data['post_thumbnail'] );
  1471 			unset( $content_struct['post_thumbnail'] );
  1497 			unset( $content_struct['post_thumbnail'] );
  1472 		}
  1498 		}
  1473 
  1499 
  1474 		if ( isset( $post_data['custom_fields'] ) )
  1500 		if ( isset( $post_data['custom_fields'] ) ) {
  1475 			$this->set_custom_fields( $post_ID, $post_data['custom_fields'] );
  1501 			$this->set_custom_fields( $post_ID, $post_data['custom_fields'] );
       
  1502 		}
  1476 
  1503 
  1477 		if ( isset( $post_data['terms'] ) || isset( $post_data['terms_names'] ) ) {
  1504 		if ( isset( $post_data['terms'] ) || isset( $post_data['terms_names'] ) ) {
  1478 			$post_type_taxonomies = get_object_taxonomies( $post_data['post_type'], 'objects' );
  1505 			$post_type_taxonomies = get_object_taxonomies( $post_data['post_type'], 'objects' );
  1479 
  1506 
  1480 			// Accumulate term IDs from terms and terms_names.
  1507 			// Accumulate term IDs from terms and terms_names.
  1484 			if ( isset( $post_data['terms'] ) && is_array( $post_data['terms'] ) ) {
  1511 			if ( isset( $post_data['terms'] ) && is_array( $post_data['terms'] ) ) {
  1485 				$taxonomies = array_keys( $post_data['terms'] );
  1512 				$taxonomies = array_keys( $post_data['terms'] );
  1486 
  1513 
  1487 				// Validating term ids.
  1514 				// Validating term ids.
  1488 				foreach ( $taxonomies as $taxonomy ) {
  1515 				foreach ( $taxonomies as $taxonomy ) {
  1489 					if ( ! array_key_exists( $taxonomy , $post_type_taxonomies ) )
  1516 					if ( ! array_key_exists( $taxonomy, $post_type_taxonomies ) ) {
  1490 						return new IXR_Error( 401, __( 'Sorry, one of the given taxonomies is not supported by the post type.' ) );
  1517 						return new IXR_Error( 401, __( 'Sorry, one of the given taxonomies is not supported by the post type.' ) );
  1491 
  1518 					}
  1492 					if ( ! current_user_can( $post_type_taxonomies[$taxonomy]->cap->assign_terms ) )
  1519 
       
  1520 					if ( ! current_user_can( $post_type_taxonomies[ $taxonomy ]->cap->assign_terms ) ) {
  1493 						return new IXR_Error( 401, __( 'Sorry, you are not allowed to assign a term to one of the given taxonomies.' ) );
  1521 						return new IXR_Error( 401, __( 'Sorry, you are not allowed to assign a term to one of the given taxonomies.' ) );
  1494 
  1522 					}
  1495 					$term_ids = $post_data['terms'][$taxonomy];
  1523 
       
  1524 					$term_ids           = $post_data['terms'][ $taxonomy ];
  1496 					$terms[ $taxonomy ] = array();
  1525 					$terms[ $taxonomy ] = array();
  1497 					foreach ( $term_ids as $term_id ) {
  1526 					foreach ( $term_ids as $term_id ) {
  1498 						$term = get_term_by( 'id', $term_id, $taxonomy );
  1527 						$term = get_term_by( 'id', $term_id, $taxonomy );
  1499 
  1528 
  1500 						if ( ! $term )
  1529 						if ( ! $term ) {
  1501 							return new IXR_Error( 403, __( 'Invalid term ID.' ) );
  1530 							return new IXR_Error( 403, __( 'Invalid term ID.' ) );
  1502 
  1531 						}
  1503 						$terms[$taxonomy][] = (int) $term_id;
  1532 
       
  1533 						$terms[ $taxonomy ][] = (int) $term_id;
  1504 					}
  1534 					}
  1505 				}
  1535 				}
  1506 			}
  1536 			}
  1507 
  1537 
  1508 			// Now validate terms specified by name.
  1538 			// Now validate terms specified by name.
  1509 			if ( isset( $post_data['terms_names'] ) && is_array( $post_data['terms_names'] ) ) {
  1539 			if ( isset( $post_data['terms_names'] ) && is_array( $post_data['terms_names'] ) ) {
  1510 				$taxonomies = array_keys( $post_data['terms_names'] );
  1540 				$taxonomies = array_keys( $post_data['terms_names'] );
  1511 
  1541 
  1512 				foreach ( $taxonomies as $taxonomy ) {
  1542 				foreach ( $taxonomies as $taxonomy ) {
  1513 					if ( ! array_key_exists( $taxonomy , $post_type_taxonomies ) )
  1543 					if ( ! array_key_exists( $taxonomy, $post_type_taxonomies ) ) {
  1514 						return new IXR_Error( 401, __( 'Sorry, one of the given taxonomies is not supported by the post type.' ) );
  1544 						return new IXR_Error( 401, __( 'Sorry, one of the given taxonomies is not supported by the post type.' ) );
  1515 
  1545 					}
  1516 					if ( ! current_user_can( $post_type_taxonomies[$taxonomy]->cap->assign_terms ) )
  1546 
       
  1547 					if ( ! current_user_can( $post_type_taxonomies[ $taxonomy ]->cap->assign_terms ) ) {
  1517 						return new IXR_Error( 401, __( 'Sorry, you are not allowed to assign a term to one of the given taxonomies.' ) );
  1548 						return new IXR_Error( 401, __( 'Sorry, you are not allowed to assign a term to one of the given taxonomies.' ) );
       
  1549 					}
  1518 
  1550 
  1519 					/*
  1551 					/*
  1520 					 * For hierarchical taxonomies, we can't assign a term when multiple terms
  1552 					 * For hierarchical taxonomies, we can't assign a term when multiple terms
  1521 					 * in the hierarchy share the same name.
  1553 					 * in the hierarchy share the same name.
  1522 					 */
  1554 					 */
  1523 					$ambiguous_terms = array();
  1555 					$ambiguous_terms = array();
  1524 					if ( is_taxonomy_hierarchical( $taxonomy ) ) {
  1556 					if ( is_taxonomy_hierarchical( $taxonomy ) ) {
  1525 						$tax_term_names = get_terms( $taxonomy, array( 'fields' => 'names', 'hide_empty' => false ) );
  1557 						$tax_term_names = get_terms(
       
  1558 							$taxonomy,
       
  1559 							array(
       
  1560 								'fields'     => 'names',
       
  1561 								'hide_empty' => false,
       
  1562 							)
       
  1563 						);
  1526 
  1564 
  1527 						// Count the number of terms with the same name.
  1565 						// Count the number of terms with the same name.
  1528 						$tax_term_names_count = array_count_values( $tax_term_names );
  1566 						$tax_term_names_count = array_count_values( $tax_term_names );
  1529 
  1567 
  1530 						// Filter out non-ambiguous term names.
  1568 						// Filter out non-ambiguous term names.
  1531 						$ambiguous_tax_term_counts = array_filter( $tax_term_names_count, array( $this, '_is_greater_than_one') );
  1569 						$ambiguous_tax_term_counts = array_filter( $tax_term_names_count, array( $this, '_is_greater_than_one' ) );
  1532 
  1570 
  1533 						$ambiguous_terms = array_keys( $ambiguous_tax_term_counts );
  1571 						$ambiguous_terms = array_keys( $ambiguous_tax_term_counts );
  1534 					}
  1572 					}
  1535 
  1573 
  1536 					$term_names = $post_data['terms_names'][$taxonomy];
  1574 					$term_names = $post_data['terms_names'][ $taxonomy ];
  1537 					foreach ( $term_names as $term_name ) {
  1575 					foreach ( $term_names as $term_name ) {
  1538 						if ( in_array( $term_name, $ambiguous_terms ) )
  1576 						if ( in_array( $term_name, $ambiguous_terms ) ) {
  1539 							return new IXR_Error( 401, __( 'Ambiguous term name used in a hierarchical taxonomy. Please use term ID instead.' ) );
  1577 							return new IXR_Error( 401, __( 'Ambiguous term name used in a hierarchical taxonomy. Please use term ID instead.' ) );
       
  1578 						}
  1540 
  1579 
  1541 						$term = get_term_by( 'name', $term_name, $taxonomy );
  1580 						$term = get_term_by( 'name', $term_name, $taxonomy );
  1542 
  1581 
  1543 						if ( ! $term ) {
  1582 						if ( ! $term ) {
  1544 							// Term doesn't exist, so check that the user is allowed to create new terms.
  1583 							// Term doesn't exist, so check that the user is allowed to create new terms.
  1545 							if ( ! current_user_can( $post_type_taxonomies[$taxonomy]->cap->edit_terms ) )
  1584 							if ( ! current_user_can( $post_type_taxonomies[ $taxonomy ]->cap->edit_terms ) ) {
  1546 								return new IXR_Error( 401, __( 'Sorry, you are not allowed to add a term to one of the given taxonomies.' ) );
  1585 								return new IXR_Error( 401, __( 'Sorry, you are not allowed to add a term to one of the given taxonomies.' ) );
       
  1586 							}
  1547 
  1587 
  1548 							// Create the new term.
  1588 							// Create the new term.
  1549 							$term_info = wp_insert_term( $term_name, $taxonomy );
  1589 							$term_info = wp_insert_term( $term_name, $taxonomy );
  1550 							if ( is_wp_error( $term_info ) )
  1590 							if ( is_wp_error( $term_info ) ) {
  1551 								return new IXR_Error( 500, $term_info->get_error_message() );
  1591 								return new IXR_Error( 500, $term_info->get_error_message() );
  1552 
  1592 							}
  1553 							$terms[$taxonomy][] = (int) $term_info['term_id'];
  1593 
       
  1594 							$terms[ $taxonomy ][] = (int) $term_info['term_id'];
  1554 						} else {
  1595 						} else {
  1555 							$terms[$taxonomy][] = (int) $term->term_id;
  1596 							$terms[ $taxonomy ][] = (int) $term->term_id;
  1556 						}
  1597 						}
  1557 					}
  1598 					}
  1558 				}
  1599 				}
  1559 			}
  1600 			}
  1560 
  1601 
  1563 		}
  1604 		}
  1564 
  1605 
  1565 		if ( isset( $post_data['post_format'] ) ) {
  1606 		if ( isset( $post_data['post_format'] ) ) {
  1566 			$format = set_post_format( $post_ID, $post_data['post_format'] );
  1607 			$format = set_post_format( $post_ID, $post_data['post_format'] );
  1567 
  1608 
  1568 			if ( is_wp_error( $format ) )
  1609 			if ( is_wp_error( $format ) ) {
  1569 				return new IXR_Error( 500, $format->get_error_message() );
  1610 				return new IXR_Error( 500, $format->get_error_message() );
       
  1611 			}
  1570 
  1612 
  1571 			unset( $post_data['post_format'] );
  1613 			unset( $post_data['post_format'] );
  1572 		}
  1614 		}
  1573 
  1615 
  1574 		// Handle enclosures.
  1616 		// Handle enclosures.
  1586 		 * @param array $content_struct Post data array.
  1628 		 * @param array $content_struct Post data array.
  1587 		 */
  1629 		 */
  1588 		$post_data = apply_filters( 'xmlrpc_wp_insert_post_data', $post_data, $content_struct );
  1630 		$post_data = apply_filters( 'xmlrpc_wp_insert_post_data', $post_data, $content_struct );
  1589 
  1631 
  1590 		$post_ID = $update ? wp_update_post( $post_data, true ) : wp_insert_post( $post_data, true );
  1632 		$post_ID = $update ? wp_update_post( $post_data, true ) : wp_insert_post( $post_data, true );
  1591 		if ( is_wp_error( $post_ID ) )
  1633 		if ( is_wp_error( $post_ID ) ) {
  1592 			return new IXR_Error( 500, $post_ID->get_error_message() );
  1634 			return new IXR_Error( 500, $post_ID->get_error_message() );
  1593 
  1635 		}
  1594 		if ( ! $post_ID )
  1636 
       
  1637 		if ( ! $post_ID ) {
  1595 			return new IXR_Error( 401, __( 'Sorry, your entry could not be posted.' ) );
  1638 			return new IXR_Error( 401, __( 'Sorry, your entry could not be posted.' ) );
       
  1639 		}
  1596 
  1640 
  1597 		return strval( $post_ID );
  1641 		return strval( $post_ID );
  1598 	}
  1642 	}
  1599 
  1643 
  1600 	/**
  1644 	/**
  1615 	 *     @type array  $content_struct Extra content arguments.
  1659 	 *     @type array  $content_struct Extra content arguments.
  1616 	 * }
  1660 	 * }
  1617 	 * @return true|IXR_Error True on success, IXR_Error on failure.
  1661 	 * @return true|IXR_Error True on success, IXR_Error on failure.
  1618 	 */
  1662 	 */
  1619 	public function wp_editPost( $args ) {
  1663 	public function wp_editPost( $args ) {
  1620 		if ( ! $this->minimum_args( $args, 5 ) )
  1664 		if ( ! $this->minimum_args( $args, 5 ) ) {
  1621 			return $this->error;
  1665 			return $this->error;
       
  1666 		}
  1622 
  1667 
  1623 		$this->escape( $args );
  1668 		$this->escape( $args );
  1624 
  1669 
  1625 		$username       = $args[1];
  1670 		$username       = $args[1];
  1626 		$password       = $args[2];
  1671 		$password       = $args[2];
  1627 		$post_id        = (int) $args[3];
  1672 		$post_id        = (int) $args[3];
  1628 		$content_struct = $args[4];
  1673 		$content_struct = $args[4];
  1629 
  1674 
  1630 		if ( ! $user = $this->login( $username, $password ) )
  1675 		if ( ! $user = $this->login( $username, $password ) ) {
  1631 			return $this->error;
  1676 			return $this->error;
       
  1677 		}
  1632 
  1678 
  1633 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  1679 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  1634 		do_action( 'xmlrpc_call', 'wp.editPost' );
  1680 		do_action( 'xmlrpc_call', 'wp.editPost' );
  1635 
  1681 
  1636 		$post = get_post( $post_id, ARRAY_A );
  1682 		$post = get_post( $post_id, ARRAY_A );
  1637 
  1683 
  1638 		if ( empty( $post['ID'] ) )
  1684 		if ( empty( $post['ID'] ) ) {
  1639 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  1685 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
       
  1686 		}
  1640 
  1687 
  1641 		if ( isset( $content_struct['if_not_modified_since'] ) ) {
  1688 		if ( isset( $content_struct['if_not_modified_since'] ) ) {
  1642 			// If the post has been modified since the date provided, return an error.
  1689 			// If the post has been modified since the date provided, return an error.
  1643 			if ( mysql2date( 'U', $post['post_modified_gmt'] ) > $content_struct['if_not_modified_since']->getTimestamp() ) {
  1690 			if ( mysql2date( 'U', $post['post_modified_gmt'] ) > $content_struct['if_not_modified_since']->getTimestamp() ) {
  1644 				return new IXR_Error( 409, __( 'There is a revision of this post that is more recent.' ) );
  1691 				return new IXR_Error( 409, __( 'There is a revision of this post that is more recent.' ) );
  1650 
  1697 
  1651 		/*
  1698 		/*
  1652 		 * Ignore the existing GMT date if it is empty or a non-GMT date was supplied in $content_struct,
  1699 		 * Ignore the existing GMT date if it is empty or a non-GMT date was supplied in $content_struct,
  1653 		 * since _insert_post() will ignore the non-GMT date if the GMT date is set.
  1700 		 * since _insert_post() will ignore the non-GMT date if the GMT date is set.
  1654 		 */
  1701 		 */
  1655 		if ( $post['post_date_gmt'] == '0000-00-00 00:00:00' || isset( $content_struct['post_date'] ) )
  1702 		if ( $post['post_date_gmt'] == '0000-00-00 00:00:00' || isset( $content_struct['post_date'] ) ) {
  1656 			unset( $post['post_date_gmt'] );
  1703 			unset( $post['post_date_gmt'] );
  1657 		else
  1704 		} else {
  1658 			$post['post_date_gmt'] = $this->_convert_date( $post['post_date_gmt'] );
  1705 			$post['post_date_gmt'] = $this->_convert_date( $post['post_date_gmt'] );
       
  1706 		}
  1659 
  1707 
  1660 		$this->escape( $post );
  1708 		$this->escape( $post );
  1661 		$merged_content_struct = array_merge( $post, $content_struct );
  1709 		$merged_content_struct = array_merge( $post, $content_struct );
  1662 
  1710 
  1663 		$retval = $this->_insert_post( $user, $merged_content_struct );
  1711 		$retval = $this->_insert_post( $user, $merged_content_struct );
  1664 		if ( $retval instanceof IXR_Error )
  1712 		if ( $retval instanceof IXR_Error ) {
  1665 			return $retval;
  1713 			return $retval;
       
  1714 		}
  1666 
  1715 
  1667 		return true;
  1716 		return true;
  1668 	}
  1717 	}
  1669 
  1718 
  1670 	/**
  1719 	/**
  1683 	 *     @type int    $post_id  Post ID.
  1732 	 *     @type int    $post_id  Post ID.
  1684 	 * }
  1733 	 * }
  1685 	 * @return true|IXR_Error True on success, IXR_Error instance on failure.
  1734 	 * @return true|IXR_Error True on success, IXR_Error instance on failure.
  1686 	 */
  1735 	 */
  1687 	public function wp_deletePost( $args ) {
  1736 	public function wp_deletePost( $args ) {
  1688 		if ( ! $this->minimum_args( $args, 4 ) )
  1737 		if ( ! $this->minimum_args( $args, 4 ) ) {
  1689 			return $this->error;
  1738 			return $this->error;
       
  1739 		}
  1690 
  1740 
  1691 		$this->escape( $args );
  1741 		$this->escape( $args );
  1692 
  1742 
  1693 		$username   = $args[1];
  1743 		$username = $args[1];
  1694 		$password   = $args[2];
  1744 		$password = $args[2];
  1695 		$post_id    = (int) $args[3];
  1745 		$post_id  = (int) $args[3];
  1696 
  1746 
  1697 		if ( ! $user = $this->login( $username, $password ) )
  1747 		if ( ! $user = $this->login( $username, $password ) ) {
  1698 			return $this->error;
  1748 			return $this->error;
       
  1749 		}
  1699 
  1750 
  1700 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  1751 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  1701 		do_action( 'xmlrpc_call', 'wp.deletePost' );
  1752 		do_action( 'xmlrpc_call', 'wp.deletePost' );
  1702 
  1753 
  1703 		$post = get_post( $post_id, ARRAY_A );
  1754 		$post = get_post( $post_id, ARRAY_A );
  1766 	 *  - 'categories'
  1817 	 *  - 'categories'
  1767 	 *  - 'tags'
  1818 	 *  - 'tags'
  1768 	 *  - 'enclosure'
  1819 	 *  - 'enclosure'
  1769 	 */
  1820 	 */
  1770 	public function wp_getPost( $args ) {
  1821 	public function wp_getPost( $args ) {
  1771 		if ( ! $this->minimum_args( $args, 4 ) )
  1822 		if ( ! $this->minimum_args( $args, 4 ) ) {
  1772 			return $this->error;
  1823 			return $this->error;
       
  1824 		}
  1773 
  1825 
  1774 		$this->escape( $args );
  1826 		$this->escape( $args );
  1775 
  1827 
  1776 		$username = $args[1];
  1828 		$username = $args[1];
  1777 		$password = $args[2];
  1829 		$password = $args[2];
  1789 			 * @param string $method Method name.
  1841 			 * @param string $method Method name.
  1790 			 */
  1842 			 */
  1791 			$fields = apply_filters( 'xmlrpc_default_post_fields', array( 'post', 'terms', 'custom_fields' ), 'wp.getPost' );
  1843 			$fields = apply_filters( 'xmlrpc_default_post_fields', array( 'post', 'terms', 'custom_fields' ), 'wp.getPost' );
  1792 		}
  1844 		}
  1793 
  1845 
  1794 		if ( ! $user = $this->login( $username, $password ) )
  1846 		if ( ! $user = $this->login( $username, $password ) ) {
  1795 			return $this->error;
  1847 			return $this->error;
       
  1848 		}
  1796 
  1849 
  1797 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  1850 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  1798 		do_action( 'xmlrpc_call', 'wp.getPost' );
  1851 		do_action( 'xmlrpc_call', 'wp.getPost' );
  1799 
  1852 
  1800 		$post = get_post( $post_id, ARRAY_A );
  1853 		$post = get_post( $post_id, ARRAY_A );
  1801 
  1854 
  1802 		if ( empty( $post['ID'] ) )
  1855 		if ( empty( $post['ID'] ) ) {
  1803 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  1856 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  1804 
  1857 		}
  1805 		if ( ! current_user_can( 'edit_post', $post_id ) )
  1858 
       
  1859 		if ( ! current_user_can( 'edit_post', $post_id ) ) {
  1806 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit this post.' ) );
  1860 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit this post.' ) );
       
  1861 		}
  1807 
  1862 
  1808 		return $this->_prepare_post( $post, $fields );
  1863 		return $this->_prepare_post( $post, $fields );
  1809 	}
  1864 	}
  1810 
  1865 
  1811 	/**
  1866 	/**
  1829 	 *     @type array  $fields   Optional. The subset of post type fields to return in the response array.
  1884 	 *     @type array  $fields   Optional. The subset of post type fields to return in the response array.
  1830 	 * }
  1885 	 * }
  1831 	 * @return array|IXR_Error Array contains a collection of posts.
  1886 	 * @return array|IXR_Error Array contains a collection of posts.
  1832 	 */
  1887 	 */
  1833 	public function wp_getPosts( $args ) {
  1888 	public function wp_getPosts( $args ) {
  1834 		if ( ! $this->minimum_args( $args, 3 ) )
  1889 		if ( ! $this->minimum_args( $args, 3 ) ) {
  1835 			return $this->error;
  1890 			return $this->error;
       
  1891 		}
  1836 
  1892 
  1837 		$this->escape( $args );
  1893 		$this->escape( $args );
  1838 
  1894 
  1839 		$username = $args[1];
  1895 		$username = $args[1];
  1840 		$password = $args[2];
  1896 		$password = $args[2];
  1845 		} else {
  1901 		} else {
  1846 			/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  1902 			/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  1847 			$fields = apply_filters( 'xmlrpc_default_post_fields', array( 'post', 'terms', 'custom_fields' ), 'wp.getPosts' );
  1903 			$fields = apply_filters( 'xmlrpc_default_post_fields', array( 'post', 'terms', 'custom_fields' ), 'wp.getPosts' );
  1848 		}
  1904 		}
  1849 
  1905 
  1850 		if ( ! $user = $this->login( $username, $password ) )
  1906 		if ( ! $user = $this->login( $username, $password ) ) {
  1851 			return $this->error;
  1907 			return $this->error;
       
  1908 		}
  1852 
  1909 
  1853 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  1910 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  1854 		do_action( 'xmlrpc_call', 'wp.getPosts' );
  1911 		do_action( 'xmlrpc_call', 'wp.getPosts' );
  1855 
  1912 
  1856 		$query = array();
  1913 		$query = array();
  1857 
  1914 
  1858 		if ( isset( $filter['post_type'] ) ) {
  1915 		if ( isset( $filter['post_type'] ) ) {
  1859 			$post_type = get_post_type_object( $filter['post_type'] );
  1916 			$post_type = get_post_type_object( $filter['post_type'] );
  1860 			if ( ! ( (bool) $post_type ) )
  1917 			if ( ! ( (bool) $post_type ) ) {
  1861 				return new IXR_Error( 403, __( 'Invalid post type.' ) );
  1918 				return new IXR_Error( 403, __( 'Invalid post type.' ) );
       
  1919 			}
  1862 		} else {
  1920 		} else {
  1863 			$post_type = get_post_type_object( 'post' );
  1921 			$post_type = get_post_type_object( 'post' );
  1864 		}
  1922 		}
  1865 
  1923 
  1866 		if ( ! current_user_can( $post_type->cap->edit_posts ) )
  1924 		if ( ! current_user_can( $post_type->cap->edit_posts ) ) {
  1867 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit posts in this post type.' ) );
  1925 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit posts in this post type.' ) );
       
  1926 		}
  1868 
  1927 
  1869 		$query['post_type'] = $post_type->name;
  1928 		$query['post_type'] = $post_type->name;
  1870 
  1929 
  1871 		if ( isset( $filter['post_status'] ) )
  1930 		if ( isset( $filter['post_status'] ) ) {
  1872 			$query['post_status'] = $filter['post_status'];
  1931 			$query['post_status'] = $filter['post_status'];
  1873 
  1932 		}
  1874 		if ( isset( $filter['number'] ) )
  1933 
       
  1934 		if ( isset( $filter['number'] ) ) {
  1875 			$query['numberposts'] = absint( $filter['number'] );
  1935 			$query['numberposts'] = absint( $filter['number'] );
  1876 
  1936 		}
  1877 		if ( isset( $filter['offset'] ) )
  1937 
       
  1938 		if ( isset( $filter['offset'] ) ) {
  1878 			$query['offset'] = absint( $filter['offset'] );
  1939 			$query['offset'] = absint( $filter['offset'] );
       
  1940 		}
  1879 
  1941 
  1880 		if ( isset( $filter['orderby'] ) ) {
  1942 		if ( isset( $filter['orderby'] ) ) {
  1881 			$query['orderby'] = $filter['orderby'];
  1943 			$query['orderby'] = $filter['orderby'];
  1882 
  1944 
  1883 			if ( isset( $filter['order'] ) )
  1945 			if ( isset( $filter['order'] ) ) {
  1884 				$query['order'] = $filter['order'];
  1946 				$query['order'] = $filter['order'];
       
  1947 			}
  1885 		}
  1948 		}
  1886 
  1949 
  1887 		if ( isset( $filter['s'] ) ) {
  1950 		if ( isset( $filter['s'] ) ) {
  1888 			$query['s'] = $filter['s'];
  1951 			$query['s'] = $filter['s'];
  1889 		}
  1952 		}
  1890 
  1953 
  1891 		$posts_list = wp_get_recent_posts( $query );
  1954 		$posts_list = wp_get_recent_posts( $query );
  1892 
  1955 
  1893 		if ( ! $posts_list )
  1956 		if ( ! $posts_list ) {
  1894 			return array();
  1957 			return array();
       
  1958 		}
  1895 
  1959 
  1896 		// Holds all the posts data.
  1960 		// Holds all the posts data.
  1897 		$struct = array();
  1961 		$struct = array();
  1898 
  1962 
  1899 		foreach ( $posts_list as $post ) {
  1963 		foreach ( $posts_list as $post ) {
  1900 			if ( ! current_user_can( 'edit_post', $post['ID'] ) )
  1964 			if ( ! current_user_can( 'edit_post', $post['ID'] ) ) {
  1901 				continue;
  1965 				continue;
       
  1966 			}
  1902 
  1967 
  1903 			$struct[] = $this->_prepare_post( $post, $fields );
  1968 			$struct[] = $this->_prepare_post( $post, $fields );
  1904 		}
  1969 		}
  1905 
  1970 
  1906 		return $struct;
  1971 		return $struct;
  1924 	 *                                  'parent', 'description', and 'slug'.
  1989 	 *                                  'parent', 'description', and 'slug'.
  1925 	 * }
  1990 	 * }
  1926 	 * @return int|IXR_Error The term ID on success, or an IXR_Error object on failure.
  1991 	 * @return int|IXR_Error The term ID on success, or an IXR_Error object on failure.
  1927 	 */
  1992 	 */
  1928 	public function wp_newTerm( $args ) {
  1993 	public function wp_newTerm( $args ) {
  1929 		if ( ! $this->minimum_args( $args, 4 ) )
  1994 		if ( ! $this->minimum_args( $args, 4 ) ) {
  1930 			return $this->error;
  1995 			return $this->error;
       
  1996 		}
  1931 
  1997 
  1932 		$this->escape( $args );
  1998 		$this->escape( $args );
  1933 
  1999 
  1934 		$username       = $args[1];
  2000 		$username       = $args[1];
  1935 		$password       = $args[2];
  2001 		$password       = $args[2];
  1936 		$content_struct = $args[3];
  2002 		$content_struct = $args[3];
  1937 
  2003 
  1938 		if ( ! $user = $this->login( $username, $password ) )
  2004 		if ( ! $user = $this->login( $username, $password ) ) {
  1939 			return $this->error;
  2005 			return $this->error;
       
  2006 		}
  1940 
  2007 
  1941 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2008 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  1942 		do_action( 'xmlrpc_call', 'wp.newTerm' );
  2009 		do_action( 'xmlrpc_call', 'wp.newTerm' );
  1943 
  2010 
  1944 		if ( ! taxonomy_exists( $content_struct['taxonomy'] ) )
  2011 		if ( ! taxonomy_exists( $content_struct['taxonomy'] ) ) {
  1945 			return new IXR_Error( 403, __( 'Invalid taxonomy.' ) );
  2012 			return new IXR_Error( 403, __( 'Invalid taxonomy.' ) );
       
  2013 		}
  1946 
  2014 
  1947 		$taxonomy = get_taxonomy( $content_struct['taxonomy'] );
  2015 		$taxonomy = get_taxonomy( $content_struct['taxonomy'] );
  1948 
  2016 
  1949 		if ( ! current_user_can( $taxonomy->cap->edit_terms ) ) {
  2017 		if ( ! current_user_can( $taxonomy->cap->edit_terms ) ) {
  1950 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to create terms in this taxonomy.' ) );
  2018 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to create terms in this taxonomy.' ) );
  1954 
  2022 
  1955 		// hold the data of the term
  2023 		// hold the data of the term
  1956 		$term_data = array();
  2024 		$term_data = array();
  1957 
  2025 
  1958 		$term_data['name'] = trim( $content_struct['name'] );
  2026 		$term_data['name'] = trim( $content_struct['name'] );
  1959 		if ( empty( $term_data['name'] ) )
  2027 		if ( empty( $term_data['name'] ) ) {
  1960 			return new IXR_Error( 403, __( 'The term name cannot be empty.' ) );
  2028 			return new IXR_Error( 403, __( 'The term name cannot be empty.' ) );
       
  2029 		}
  1961 
  2030 
  1962 		if ( isset( $content_struct['parent'] ) ) {
  2031 		if ( isset( $content_struct['parent'] ) ) {
  1963 			if ( ! $taxonomy['hierarchical'] )
  2032 			if ( ! $taxonomy['hierarchical'] ) {
  1964 				return new IXR_Error( 403, __( 'This taxonomy is not hierarchical.' ) );
  2033 				return new IXR_Error( 403, __( 'This taxonomy is not hierarchical.' ) );
       
  2034 			}
  1965 
  2035 
  1966 			$parent_term_id = (int) $content_struct['parent'];
  2036 			$parent_term_id = (int) $content_struct['parent'];
  1967 			$parent_term = get_term( $parent_term_id , $taxonomy['name'] );
  2037 			$parent_term    = get_term( $parent_term_id, $taxonomy['name'] );
  1968 
  2038 
  1969 			if ( is_wp_error( $parent_term ) )
  2039 			if ( is_wp_error( $parent_term ) ) {
  1970 				return new IXR_Error( 500, $parent_term->get_error_message() );
  2040 				return new IXR_Error( 500, $parent_term->get_error_message() );
  1971 
  2041 			}
  1972 			if ( ! $parent_term )
  2042 
       
  2043 			if ( ! $parent_term ) {
  1973 				return new IXR_Error( 403, __( 'Parent term does not exist.' ) );
  2044 				return new IXR_Error( 403, __( 'Parent term does not exist.' ) );
       
  2045 			}
  1974 
  2046 
  1975 			$term_data['parent'] = $content_struct['parent'];
  2047 			$term_data['parent'] = $content_struct['parent'];
  1976 		}
  2048 		}
  1977 
  2049 
  1978 		if ( isset( $content_struct['description'] ) )
  2050 		if ( isset( $content_struct['description'] ) ) {
  1979 			$term_data['description'] = $content_struct['description'];
  2051 			$term_data['description'] = $content_struct['description'];
  1980 
  2052 		}
  1981 		if ( isset( $content_struct['slug'] ) )
  2053 
       
  2054 		if ( isset( $content_struct['slug'] ) ) {
  1982 			$term_data['slug'] = $content_struct['slug'];
  2055 			$term_data['slug'] = $content_struct['slug'];
  1983 
  2056 		}
  1984 		$term = wp_insert_term( $term_data['name'] , $taxonomy['name'] , $term_data );
  2057 
  1985 
  2058 		$term = wp_insert_term( $term_data['name'], $taxonomy['name'], $term_data );
  1986 		if ( is_wp_error( $term ) )
  2059 
       
  2060 		if ( is_wp_error( $term ) ) {
  1987 			return new IXR_Error( 500, $term->get_error_message() );
  2061 			return new IXR_Error( 500, $term->get_error_message() );
  1988 
  2062 		}
  1989 		if ( ! $term )
  2063 
       
  2064 		if ( ! $term ) {
  1990 			return new IXR_Error( 500, __( 'Sorry, your term could not be created.' ) );
  2065 			return new IXR_Error( 500, __( 'Sorry, your term could not be created.' ) );
       
  2066 		}
  1991 
  2067 
  1992 		// Add term meta.
  2068 		// Add term meta.
  1993 		if ( isset( $content_struct['custom_fields'] ) ) {
  2069 		if ( isset( $content_struct['custom_fields'] ) ) {
  1994 			$this->set_term_custom_fields( $term['term_id'], $content_struct['custom_fields'] );
  2070 			$this->set_term_custom_fields( $term['term_id'], $content_struct['custom_fields'] );
  1995 		}
  2071 		}
  2016 	 *                                  'description', and 'slug'.
  2092 	 *                                  'description', and 'slug'.
  2017 	 * }
  2093 	 * }
  2018 	 * @return true|IXR_Error True on success, IXR_Error instance on failure.
  2094 	 * @return true|IXR_Error True on success, IXR_Error instance on failure.
  2019 	 */
  2095 	 */
  2020 	public function wp_editTerm( $args ) {
  2096 	public function wp_editTerm( $args ) {
  2021 		if ( ! $this->minimum_args( $args, 5 ) )
  2097 		if ( ! $this->minimum_args( $args, 5 ) ) {
  2022 			return $this->error;
  2098 			return $this->error;
       
  2099 		}
  2023 
  2100 
  2024 		$this->escape( $args );
  2101 		$this->escape( $args );
  2025 
  2102 
  2026 		$username       = $args[1];
  2103 		$username       = $args[1];
  2027 		$password       = $args[2];
  2104 		$password       = $args[2];
  2028 		$term_id        = (int) $args[3];
  2105 		$term_id        = (int) $args[3];
  2029 		$content_struct = $args[4];
  2106 		$content_struct = $args[4];
  2030 
  2107 
  2031 		if ( ! $user = $this->login( $username, $password ) )
  2108 		if ( ! $user = $this->login( $username, $password ) ) {
  2032 			return $this->error;
  2109 			return $this->error;
       
  2110 		}
  2033 
  2111 
  2034 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2112 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2035 		do_action( 'xmlrpc_call', 'wp.editTerm' );
  2113 		do_action( 'xmlrpc_call', 'wp.editTerm' );
  2036 
  2114 
  2037 		if ( ! taxonomy_exists( $content_struct['taxonomy'] ) )
  2115 		if ( ! taxonomy_exists( $content_struct['taxonomy'] ) ) {
  2038 			return new IXR_Error( 403, __( 'Invalid taxonomy.' ) );
  2116 			return new IXR_Error( 403, __( 'Invalid taxonomy.' ) );
       
  2117 		}
  2039 
  2118 
  2040 		$taxonomy = get_taxonomy( $content_struct['taxonomy'] );
  2119 		$taxonomy = get_taxonomy( $content_struct['taxonomy'] );
  2041 
  2120 
  2042 		$taxonomy = (array) $taxonomy;
  2121 		$taxonomy = (array) $taxonomy;
  2043 
  2122 
  2044 		// hold the data of the term
  2123 		// hold the data of the term
  2045 		$term_data = array();
  2124 		$term_data = array();
  2046 
  2125 
  2047 		$term = get_term( $term_id , $content_struct['taxonomy'] );
  2126 		$term = get_term( $term_id, $content_struct['taxonomy'] );
  2048 
  2127 
  2049 		if ( is_wp_error( $term ) )
  2128 		if ( is_wp_error( $term ) ) {
  2050 			return new IXR_Error( 500, $term->get_error_message() );
  2129 			return new IXR_Error( 500, $term->get_error_message() );
  2051 
  2130 		}
  2052 		if ( ! $term )
  2131 
       
  2132 		if ( ! $term ) {
  2053 			return new IXR_Error( 404, __( 'Invalid term ID.' ) );
  2133 			return new IXR_Error( 404, __( 'Invalid term ID.' ) );
       
  2134 		}
  2054 
  2135 
  2055 		if ( ! current_user_can( 'edit_term', $term_id ) ) {
  2136 		if ( ! current_user_can( 'edit_term', $term_id ) ) {
  2056 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit this term.' ) );
  2137 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit this term.' ) );
  2057 		}
  2138 		}
  2058 
  2139 
  2059 		if ( isset( $content_struct['name'] ) ) {
  2140 		if ( isset( $content_struct['name'] ) ) {
  2060 			$term_data['name'] = trim( $content_struct['name'] );
  2141 			$term_data['name'] = trim( $content_struct['name'] );
  2061 
  2142 
  2062 			if ( empty( $term_data['name'] ) )
  2143 			if ( empty( $term_data['name'] ) ) {
  2063 				return new IXR_Error( 403, __( 'The term name cannot be empty.' ) );
  2144 				return new IXR_Error( 403, __( 'The term name cannot be empty.' ) );
       
  2145 			}
  2064 		}
  2146 		}
  2065 
  2147 
  2066 		if ( ! empty( $content_struct['parent'] ) ) {
  2148 		if ( ! empty( $content_struct['parent'] ) ) {
  2067 			if ( ! $taxonomy['hierarchical'] )
  2149 			if ( ! $taxonomy['hierarchical'] ) {
  2068 				return new IXR_Error( 403, __( 'Cannot set parent term, taxonomy is not hierarchical.' ) );
  2150 				return new IXR_Error( 403, __( 'Cannot set parent term, taxonomy is not hierarchical.' ) );
       
  2151 			}
  2069 
  2152 
  2070 			$parent_term_id = (int) $content_struct['parent'];
  2153 			$parent_term_id = (int) $content_struct['parent'];
  2071 			$parent_term = get_term( $parent_term_id , $taxonomy['name'] );
  2154 			$parent_term    = get_term( $parent_term_id, $taxonomy['name'] );
  2072 
  2155 
  2073 			if ( is_wp_error( $parent_term ) )
  2156 			if ( is_wp_error( $parent_term ) ) {
  2074 				return new IXR_Error( 500, $parent_term->get_error_message() );
  2157 				return new IXR_Error( 500, $parent_term->get_error_message() );
  2075 
  2158 			}
  2076 			if ( ! $parent_term )
  2159 
       
  2160 			if ( ! $parent_term ) {
  2077 				return new IXR_Error( 403, __( 'Parent term does not exist.' ) );
  2161 				return new IXR_Error( 403, __( 'Parent term does not exist.' ) );
       
  2162 			}
  2078 
  2163 
  2079 			$term_data['parent'] = $content_struct['parent'];
  2164 			$term_data['parent'] = $content_struct['parent'];
  2080 		}
  2165 		}
  2081 
  2166 
  2082 		if ( isset( $content_struct['description'] ) )
  2167 		if ( isset( $content_struct['description'] ) ) {
  2083 			$term_data['description'] = $content_struct['description'];
  2168 			$term_data['description'] = $content_struct['description'];
  2084 
  2169 		}
  2085 		if ( isset( $content_struct['slug'] ) )
  2170 
       
  2171 		if ( isset( $content_struct['slug'] ) ) {
  2086 			$term_data['slug'] = $content_struct['slug'];
  2172 			$term_data['slug'] = $content_struct['slug'];
  2087 
  2173 		}
  2088 		$term = wp_update_term( $term_id , $taxonomy['name'] , $term_data );
  2174 
  2089 
  2175 		$term = wp_update_term( $term_id, $taxonomy['name'], $term_data );
  2090 		if ( is_wp_error( $term ) )
  2176 
       
  2177 		if ( is_wp_error( $term ) ) {
  2091 			return new IXR_Error( 500, $term->get_error_message() );
  2178 			return new IXR_Error( 500, $term->get_error_message() );
  2092 
  2179 		}
  2093 		if ( ! $term )
  2180 
       
  2181 		if ( ! $term ) {
  2094 			return new IXR_Error( 500, __( 'Sorry, editing the term failed.' ) );
  2182 			return new IXR_Error( 500, __( 'Sorry, editing the term failed.' ) );
       
  2183 		}
  2095 
  2184 
  2096 		// Update term meta.
  2185 		// Update term meta.
  2097 		if ( isset( $content_struct['custom_fields'] ) ) {
  2186 		if ( isset( $content_struct['custom_fields'] ) ) {
  2098 			$this->set_term_custom_fields( $term_id, $content_struct['custom_fields'] );
  2187 			$this->set_term_custom_fields( $term_id, $content_struct['custom_fields'] );
  2099 		}
  2188 		}
  2118 	 *     @type int    $term_id      Term ID.
  2207 	 *     @type int    $term_id      Term ID.
  2119 	 * }
  2208 	 * }
  2120 	 * @return bool|IXR_Error True on success, IXR_Error instance on failure.
  2209 	 * @return bool|IXR_Error True on success, IXR_Error instance on failure.
  2121 	 */
  2210 	 */
  2122 	public function wp_deleteTerm( $args ) {
  2211 	public function wp_deleteTerm( $args ) {
  2123 		if ( ! $this->minimum_args( $args, 5 ) )
  2212 		if ( ! $this->minimum_args( $args, 5 ) ) {
  2124 			return $this->error;
  2213 			return $this->error;
       
  2214 		}
  2125 
  2215 
  2126 		$this->escape( $args );
  2216 		$this->escape( $args );
  2127 
  2217 
  2128 		$username           = $args[1];
  2218 		$username = $args[1];
  2129 		$password           = $args[2];
  2219 		$password = $args[2];
  2130 		$taxonomy           = $args[3];
  2220 		$taxonomy = $args[3];
  2131 		$term_id            = (int) $args[4];
  2221 		$term_id  = (int) $args[4];
  2132 
  2222 
  2133 		if ( ! $user = $this->login( $username, $password ) )
  2223 		if ( ! $user = $this->login( $username, $password ) ) {
  2134 			return $this->error;
  2224 			return $this->error;
       
  2225 		}
  2135 
  2226 
  2136 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2227 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2137 		do_action( 'xmlrpc_call', 'wp.deleteTerm' );
  2228 		do_action( 'xmlrpc_call', 'wp.deleteTerm' );
  2138 
  2229 
  2139 		if ( ! taxonomy_exists( $taxonomy ) )
  2230 		if ( ! taxonomy_exists( $taxonomy ) ) {
  2140 			return new IXR_Error( 403, __( 'Invalid taxonomy.' ) );
  2231 			return new IXR_Error( 403, __( 'Invalid taxonomy.' ) );
       
  2232 		}
  2141 
  2233 
  2142 		$taxonomy = get_taxonomy( $taxonomy );
  2234 		$taxonomy = get_taxonomy( $taxonomy );
  2143 		$term = get_term( $term_id, $taxonomy->name );
  2235 		$term     = get_term( $term_id, $taxonomy->name );
  2144 
  2236 
  2145 		if ( is_wp_error( $term ) )
  2237 		if ( is_wp_error( $term ) ) {
  2146 			return new IXR_Error( 500, $term->get_error_message() );
  2238 			return new IXR_Error( 500, $term->get_error_message() );
  2147 
  2239 		}
  2148 		if ( ! $term )
  2240 
       
  2241 		if ( ! $term ) {
  2149 			return new IXR_Error( 404, __( 'Invalid term ID.' ) );
  2242 			return new IXR_Error( 404, __( 'Invalid term ID.' ) );
       
  2243 		}
  2150 
  2244 
  2151 		if ( ! current_user_can( 'delete_term', $term_id ) ) {
  2245 		if ( ! current_user_can( 'delete_term', $term_id ) ) {
  2152 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to delete this term.' ) );
  2246 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to delete this term.' ) );
  2153 		}
  2247 		}
  2154 
  2248 
  2155 		$result = wp_delete_term( $term_id, $taxonomy->name );
  2249 		$result = wp_delete_term( $term_id, $taxonomy->name );
  2156 
  2250 
  2157 		if ( is_wp_error( $result ) )
  2251 		if ( is_wp_error( $result ) ) {
  2158 			return new IXR_Error( 500, $term->get_error_message() );
  2252 			return new IXR_Error( 500, $term->get_error_message() );
  2159 
  2253 		}
  2160 		if ( ! $result )
  2254 
       
  2255 		if ( ! $result ) {
  2161 			return new IXR_Error( 500, __( 'Sorry, deleting the term failed.' ) );
  2256 			return new IXR_Error( 500, __( 'Sorry, deleting the term failed.' ) );
       
  2257 		}
  2162 
  2258 
  2163 		return $result;
  2259 		return $result;
  2164 	}
  2260 	}
  2165 
  2261 
  2166 	/**
  2262 	/**
  2189 	 *  - 'description'
  2285 	 *  - 'description'
  2190 	 *  - 'parent'
  2286 	 *  - 'parent'
  2191 	 *  - 'count'
  2287 	 *  - 'count'
  2192 	 */
  2288 	 */
  2193 	public function wp_getTerm( $args ) {
  2289 	public function wp_getTerm( $args ) {
  2194 		if ( ! $this->minimum_args( $args, 5 ) )
  2290 		if ( ! $this->minimum_args( $args, 5 ) ) {
  2195 			return $this->error;
  2291 			return $this->error;
       
  2292 		}
  2196 
  2293 
  2197 		$this->escape( $args );
  2294 		$this->escape( $args );
  2198 
  2295 
  2199 		$username           = $args[1];
  2296 		$username = $args[1];
  2200 		$password           = $args[2];
  2297 		$password = $args[2];
  2201 		$taxonomy           = $args[3];
  2298 		$taxonomy = $args[3];
  2202 		$term_id            = (int) $args[4];
  2299 		$term_id  = (int) $args[4];
  2203 
  2300 
  2204 		if ( ! $user = $this->login( $username, $password ) )
  2301 		if ( ! $user = $this->login( $username, $password ) ) {
  2205 			return $this->error;
  2302 			return $this->error;
       
  2303 		}
  2206 
  2304 
  2207 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2305 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2208 		do_action( 'xmlrpc_call', 'wp.getTerm' );
  2306 		do_action( 'xmlrpc_call', 'wp.getTerm' );
  2209 
  2307 
  2210 		if ( ! taxonomy_exists( $taxonomy ) )
  2308 		if ( ! taxonomy_exists( $taxonomy ) ) {
  2211 			return new IXR_Error( 403, __( 'Invalid taxonomy.' ) );
  2309 			return new IXR_Error( 403, __( 'Invalid taxonomy.' ) );
       
  2310 		}
  2212 
  2311 
  2213 		$taxonomy = get_taxonomy( $taxonomy );
  2312 		$taxonomy = get_taxonomy( $taxonomy );
  2214 
  2313 
  2215 		$term = get_term( $term_id , $taxonomy->name, ARRAY_A );
  2314 		$term = get_term( $term_id, $taxonomy->name, ARRAY_A );
  2216 
  2315 
  2217 		if ( is_wp_error( $term ) )
  2316 		if ( is_wp_error( $term ) ) {
  2218 			return new IXR_Error( 500, $term->get_error_message() );
  2317 			return new IXR_Error( 500, $term->get_error_message() );
  2219 
  2318 		}
  2220 		if ( ! $term )
  2319 
       
  2320 		if ( ! $term ) {
  2221 			return new IXR_Error( 404, __( 'Invalid term ID.' ) );
  2321 			return new IXR_Error( 404, __( 'Invalid term ID.' ) );
       
  2322 		}
  2222 
  2323 
  2223 		if ( ! current_user_can( 'assign_term', $term_id ) ) {
  2324 		if ( ! current_user_can( 'assign_term', $term_id ) ) {
  2224 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to assign this term.' ) );
  2325 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to assign this term.' ) );
  2225 		}
  2326 		}
  2226 
  2327 
  2248 	 *                            'offset', 'orderby', 'order', 'hide_empty', and 'search'. Default empty array.
  2349 	 *                            'offset', 'orderby', 'order', 'hide_empty', and 'search'. Default empty array.
  2249 	 * }
  2350 	 * }
  2250 	 * @return array|IXR_Error An associative array of terms data on success, IXR_Error instance otherwise.
  2351 	 * @return array|IXR_Error An associative array of terms data on success, IXR_Error instance otherwise.
  2251 	 */
  2352 	 */
  2252 	public function wp_getTerms( $args ) {
  2353 	public function wp_getTerms( $args ) {
  2253 		if ( ! $this->minimum_args( $args, 4 ) )
  2354 		if ( ! $this->minimum_args( $args, 4 ) ) {
  2254 			return $this->error;
  2355 			return $this->error;
       
  2356 		}
  2255 
  2357 
  2256 		$this->escape( $args );
  2358 		$this->escape( $args );
  2257 
  2359 
  2258 		$username       = $args[1];
  2360 		$username = $args[1];
  2259 		$password       = $args[2];
  2361 		$password = $args[2];
  2260 		$taxonomy       = $args[3];
  2362 		$taxonomy = $args[3];
  2261 		$filter         = isset( $args[4] ) ? $args[4] : array();
  2363 		$filter   = isset( $args[4] ) ? $args[4] : array();
  2262 
  2364 
  2263 		if ( ! $user = $this->login( $username, $password ) )
  2365 		if ( ! $user = $this->login( $username, $password ) ) {
  2264 			return $this->error;
  2366 			return $this->error;
       
  2367 		}
  2265 
  2368 
  2266 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2369 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2267 		do_action( 'xmlrpc_call', 'wp.getTerms' );
  2370 		do_action( 'xmlrpc_call', 'wp.getTerms' );
  2268 
  2371 
  2269 		if ( ! taxonomy_exists( $taxonomy ) )
  2372 		if ( ! taxonomy_exists( $taxonomy ) ) {
  2270 			return new IXR_Error( 403, __( 'Invalid taxonomy.' ) );
  2373 			return new IXR_Error( 403, __( 'Invalid taxonomy.' ) );
       
  2374 		}
  2271 
  2375 
  2272 		$taxonomy = get_taxonomy( $taxonomy );
  2376 		$taxonomy = get_taxonomy( $taxonomy );
  2273 
  2377 
  2274 		if ( ! current_user_can( $taxonomy->cap->assign_terms ) )
  2378 		if ( ! current_user_can( $taxonomy->cap->assign_terms ) ) {
  2275 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to assign terms in this taxonomy.' ) );
  2379 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to assign terms in this taxonomy.' ) );
       
  2380 		}
  2276 
  2381 
  2277 		$query = array();
  2382 		$query = array();
  2278 
  2383 
  2279 		if ( isset( $filter['number'] ) )
  2384 		if ( isset( $filter['number'] ) ) {
  2280 			$query['number'] = absint( $filter['number'] );
  2385 			$query['number'] = absint( $filter['number'] );
  2281 
  2386 		}
  2282 		if ( isset( $filter['offset'] ) )
  2387 
       
  2388 		if ( isset( $filter['offset'] ) ) {
  2283 			$query['offset'] = absint( $filter['offset'] );
  2389 			$query['offset'] = absint( $filter['offset'] );
       
  2390 		}
  2284 
  2391 
  2285 		if ( isset( $filter['orderby'] ) ) {
  2392 		if ( isset( $filter['orderby'] ) ) {
  2286 			$query['orderby'] = $filter['orderby'];
  2393 			$query['orderby'] = $filter['orderby'];
  2287 
  2394 
  2288 			if ( isset( $filter['order'] ) )
  2395 			if ( isset( $filter['order'] ) ) {
  2289 				$query['order'] = $filter['order'];
  2396 				$query['order'] = $filter['order'];
  2290 		}
  2397 			}
  2291 
  2398 		}
  2292 		if ( isset( $filter['hide_empty'] ) )
  2399 
       
  2400 		if ( isset( $filter['hide_empty'] ) ) {
  2293 			$query['hide_empty'] = $filter['hide_empty'];
  2401 			$query['hide_empty'] = $filter['hide_empty'];
  2294 		else
  2402 		} else {
  2295 			$query['get'] = 'all';
  2403 			$query['get'] = 'all';
  2296 
  2404 		}
  2297 		if ( isset( $filter['search'] ) )
  2405 
       
  2406 		if ( isset( $filter['search'] ) ) {
  2298 			$query['search'] = $filter['search'];
  2407 			$query['search'] = $filter['search'];
       
  2408 		}
  2299 
  2409 
  2300 		$terms = get_terms( $taxonomy->name, $query );
  2410 		$terms = get_terms( $taxonomy->name, $query );
  2301 
  2411 
  2302 		if ( is_wp_error( $terms ) )
  2412 		if ( is_wp_error( $terms ) ) {
  2303 			return new IXR_Error( 500, $terms->get_error_message() );
  2413 			return new IXR_Error( 500, $terms->get_error_message() );
       
  2414 		}
  2304 
  2415 
  2305 		$struct = array();
  2416 		$struct = array();
  2306 
  2417 
  2307 		foreach ( $terms as $term ) {
  2418 		foreach ( $terms as $term ) {
  2308 			$struct[] = $this->_prepare_term( $term );
  2419 			$struct[] = $this->_prepare_term( $term );
  2330 	 *                            Default empty array.
  2441 	 *                            Default empty array.
  2331 	 * }
  2442 	 * }
  2332 	 * @return array|IXR_Error An array of taxonomy data on success, IXR_Error instance otherwise.
  2443 	 * @return array|IXR_Error An array of taxonomy data on success, IXR_Error instance otherwise.
  2333 	 */
  2444 	 */
  2334 	public function wp_getTaxonomy( $args ) {
  2445 	public function wp_getTaxonomy( $args ) {
  2335 		if ( ! $this->minimum_args( $args, 4 ) )
  2446 		if ( ! $this->minimum_args( $args, 4 ) ) {
  2336 			return $this->error;
  2447 			return $this->error;
       
  2448 		}
  2337 
  2449 
  2338 		$this->escape( $args );
  2450 		$this->escape( $args );
  2339 
  2451 
  2340 		$username = $args[1];
  2452 		$username = $args[1];
  2341 		$password = $args[2];
  2453 		$password = $args[2];
  2353 			 * @param string $method The method name.
  2465 			 * @param string $method The method name.
  2354 			 */
  2466 			 */
  2355 			$fields = apply_filters( 'xmlrpc_default_taxonomy_fields', array( 'labels', 'cap', 'object_type' ), 'wp.getTaxonomy' );
  2467 			$fields = apply_filters( 'xmlrpc_default_taxonomy_fields', array( 'labels', 'cap', 'object_type' ), 'wp.getTaxonomy' );
  2356 		}
  2468 		}
  2357 
  2469 
  2358 		if ( ! $user = $this->login( $username, $password ) )
  2470 		if ( ! $user = $this->login( $username, $password ) ) {
  2359 			return $this->error;
  2471 			return $this->error;
       
  2472 		}
  2360 
  2473 
  2361 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2474 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2362 		do_action( 'xmlrpc_call', 'wp.getTaxonomy' );
  2475 		do_action( 'xmlrpc_call', 'wp.getTaxonomy' );
  2363 
  2476 
  2364 		if ( ! taxonomy_exists( $taxonomy ) )
  2477 		if ( ! taxonomy_exists( $taxonomy ) ) {
  2365 			return new IXR_Error( 403, __( 'Invalid taxonomy.' ) );
  2478 			return new IXR_Error( 403, __( 'Invalid taxonomy.' ) );
       
  2479 		}
  2366 
  2480 
  2367 		$taxonomy = get_taxonomy( $taxonomy );
  2481 		$taxonomy = get_taxonomy( $taxonomy );
  2368 
  2482 
  2369 		if ( ! current_user_can( $taxonomy->cap->assign_terms ) )
  2483 		if ( ! current_user_can( $taxonomy->cap->assign_terms ) ) {
  2370 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to assign terms in this taxonomy.' ) );
  2484 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to assign terms in this taxonomy.' ) );
       
  2485 		}
  2371 
  2486 
  2372 		return $this->_prepare_taxonomy( $taxonomy, $fields );
  2487 		return $this->_prepare_taxonomy( $taxonomy, $fields );
  2373 	}
  2488 	}
  2374 
  2489 
  2375 	/**
  2490 	/**
  2390 	 * }
  2505 	 * }
  2391 	 * @return array|IXR_Error An associative array of taxonomy data with returned fields determined
  2506 	 * @return array|IXR_Error An associative array of taxonomy data with returned fields determined
  2392 	 *                         by `$fields`, or an IXR_Error instance on failure.
  2507 	 *                         by `$fields`, or an IXR_Error instance on failure.
  2393 	 */
  2508 	 */
  2394 	public function wp_getTaxonomies( $args ) {
  2509 	public function wp_getTaxonomies( $args ) {
  2395 		if ( ! $this->minimum_args( $args, 3 ) )
  2510 		if ( ! $this->minimum_args( $args, 3 ) ) {
  2396 			return $this->error;
  2511 			return $this->error;
       
  2512 		}
  2397 
  2513 
  2398 		$this->escape( $args );
  2514 		$this->escape( $args );
  2399 
  2515 
  2400 		$username = $args[1];
  2516 		$username = $args[1];
  2401 		$password = $args[2];
  2517 		$password = $args[2];
  2406 		} else {
  2522 		} else {
  2407 			/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2523 			/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2408 			$fields = apply_filters( 'xmlrpc_default_taxonomy_fields', array( 'labels', 'cap', 'object_type' ), 'wp.getTaxonomies' );
  2524 			$fields = apply_filters( 'xmlrpc_default_taxonomy_fields', array( 'labels', 'cap', 'object_type' ), 'wp.getTaxonomies' );
  2409 		}
  2525 		}
  2410 
  2526 
  2411 		if ( ! $user = $this->login( $username, $password ) )
  2527 		if ( ! $user = $this->login( $username, $password ) ) {
  2412 			return $this->error;
  2528 			return $this->error;
       
  2529 		}
  2413 
  2530 
  2414 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2531 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2415 		do_action( 'xmlrpc_call', 'wp.getTaxonomies' );
  2532 		do_action( 'xmlrpc_call', 'wp.getTaxonomies' );
  2416 
  2533 
  2417 		$taxonomies = get_taxonomies( $filter, 'objects' );
  2534 		$taxonomies = get_taxonomies( $filter, 'objects' );
  2419 		// holds all the taxonomy data
  2536 		// holds all the taxonomy data
  2420 		$struct = array();
  2537 		$struct = array();
  2421 
  2538 
  2422 		foreach ( $taxonomies as $taxonomy ) {
  2539 		foreach ( $taxonomies as $taxonomy ) {
  2423 			// capability check for post_types
  2540 			// capability check for post_types
  2424 			if ( ! current_user_can( $taxonomy->cap->assign_terms ) )
  2541 			if ( ! current_user_can( $taxonomy->cap->assign_terms ) ) {
  2425 				continue;
  2542 				continue;
       
  2543 			}
  2426 
  2544 
  2427 			$struct[] = $this->_prepare_taxonomy( $taxonomy, $fields );
  2545 			$struct[] = $this->_prepare_taxonomy( $taxonomy, $fields );
  2428 		}
  2546 		}
  2429 
  2547 
  2430 		return $struct;
  2548 		return $struct;
  2465 	 *  - 'url'
  2583 	 *  - 'url'
  2466 	 *  - 'display_name'
  2584 	 *  - 'display_name'
  2467 	 *  - 'roles'
  2585 	 *  - 'roles'
  2468 	 */
  2586 	 */
  2469 	public function wp_getUser( $args ) {
  2587 	public function wp_getUser( $args ) {
  2470 		if ( ! $this->minimum_args( $args, 4 ) )
  2588 		if ( ! $this->minimum_args( $args, 4 ) ) {
  2471 			return $this->error;
  2589 			return $this->error;
       
  2590 		}
  2472 
  2591 
  2473 		$this->escape( $args );
  2592 		$this->escape( $args );
  2474 
  2593 
  2475 		$username = $args[1];
  2594 		$username = $args[1];
  2476 		$password = $args[2];
  2595 		$password = $args[2];
  2488 			 * @param string $method The method name.
  2607 			 * @param string $method The method name.
  2489 			 */
  2608 			 */
  2490 			$fields = apply_filters( 'xmlrpc_default_user_fields', array( 'all' ), 'wp.getUser' );
  2609 			$fields = apply_filters( 'xmlrpc_default_user_fields', array( 'all' ), 'wp.getUser' );
  2491 		}
  2610 		}
  2492 
  2611 
  2493 		if ( ! $user = $this->login( $username, $password ) )
  2612 		if ( ! $user = $this->login( $username, $password ) ) {
  2494 			return $this->error;
  2613 			return $this->error;
       
  2614 		}
  2495 
  2615 
  2496 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2616 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2497 		do_action( 'xmlrpc_call', 'wp.getUser' );
  2617 		do_action( 'xmlrpc_call', 'wp.getUser' );
  2498 
  2618 
  2499 		if ( ! current_user_can( 'edit_user', $user_id ) )
  2619 		if ( ! current_user_can( 'edit_user', $user_id ) ) {
  2500 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit this user.' ) );
  2620 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit this user.' ) );
       
  2621 		}
  2501 
  2622 
  2502 		$user_data = get_userdata( $user_id );
  2623 		$user_data = get_userdata( $user_id );
  2503 
  2624 
  2504 		if ( ! $user_data )
  2625 		if ( ! $user_data ) {
  2505 			return new IXR_Error( 404, __( 'Invalid user ID.' ) );
  2626 			return new IXR_Error( 404, __( 'Invalid user ID.' ) );
       
  2627 		}
  2506 
  2628 
  2507 		return $this->_prepare_user( $user_data, $fields );
  2629 		return $this->_prepare_user( $user_data, $fields );
  2508 	}
  2630 	}
  2509 
  2631 
  2510 	/**
  2632 	/**
  2530 	 *     @type array  $fields (optional)
  2652 	 *     @type array  $fields (optional)
  2531 	 * }
  2653 	 * }
  2532 	 * @return array|IXR_Error users data
  2654 	 * @return array|IXR_Error users data
  2533 	 */
  2655 	 */
  2534 	public function wp_getUsers( $args ) {
  2656 	public function wp_getUsers( $args ) {
  2535 		if ( ! $this->minimum_args( $args, 3 ) )
  2657 		if ( ! $this->minimum_args( $args, 3 ) ) {
  2536 			return $this->error;
  2658 			return $this->error;
       
  2659 		}
  2537 
  2660 
  2538 		$this->escape( $args );
  2661 		$this->escape( $args );
  2539 
  2662 
  2540 		$username = $args[1];
  2663 		$username = $args[1];
  2541 		$password = $args[2];
  2664 		$password = $args[2];
  2546 		} else {
  2669 		} else {
  2547 			/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2670 			/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2548 			$fields = apply_filters( 'xmlrpc_default_user_fields', array( 'all' ), 'wp.getUsers' );
  2671 			$fields = apply_filters( 'xmlrpc_default_user_fields', array( 'all' ), 'wp.getUsers' );
  2549 		}
  2672 		}
  2550 
  2673 
  2551 		if ( ! $user = $this->login( $username, $password ) )
  2674 		if ( ! $user = $this->login( $username, $password ) ) {
  2552 			return $this->error;
  2675 			return $this->error;
       
  2676 		}
  2553 
  2677 
  2554 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2678 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2555 		do_action( 'xmlrpc_call', 'wp.getUsers' );
  2679 		do_action( 'xmlrpc_call', 'wp.getUsers' );
  2556 
  2680 
  2557 		if ( ! current_user_can( 'list_users' ) )
  2681 		if ( ! current_user_can( 'list_users' ) ) {
  2558 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to list users.' ) );
  2682 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to list users.' ) );
       
  2683 		}
  2559 
  2684 
  2560 		$query = array( 'fields' => 'all_with_meta' );
  2685 		$query = array( 'fields' => 'all_with_meta' );
  2561 
  2686 
  2562 		$query['number'] = ( isset( $filter['number'] ) ) ? absint( $filter['number'] ) : 50;
  2687 		$query['number'] = ( isset( $filter['number'] ) ) ? absint( $filter['number'] ) : 50;
  2563 		$query['offset'] = ( isset( $filter['offset'] ) ) ? absint( $filter['offset'] ) : 0;
  2688 		$query['offset'] = ( isset( $filter['offset'] ) ) ? absint( $filter['offset'] ) : 0;
  2564 
  2689 
  2565 		if ( isset( $filter['orderby'] ) ) {
  2690 		if ( isset( $filter['orderby'] ) ) {
  2566 			$query['orderby'] = $filter['orderby'];
  2691 			$query['orderby'] = $filter['orderby'];
  2567 
  2692 
  2568 			if ( isset( $filter['order'] ) )
  2693 			if ( isset( $filter['order'] ) ) {
  2569 				$query['order'] = $filter['order'];
  2694 				$query['order'] = $filter['order'];
       
  2695 			}
  2570 		}
  2696 		}
  2571 
  2697 
  2572 		if ( isset( $filter['role'] ) ) {
  2698 		if ( isset( $filter['role'] ) ) {
  2573 			if ( get_role( $filter['role'] ) === null )
  2699 			if ( get_role( $filter['role'] ) === null ) {
  2574 				return new IXR_Error( 403, __( 'Invalid role.' ) );
  2700 				return new IXR_Error( 403, __( 'Invalid role.' ) );
       
  2701 			}
  2575 
  2702 
  2576 			$query['role'] = $filter['role'];
  2703 			$query['role'] = $filter['role'];
  2577 		}
  2704 		}
  2578 
  2705 
  2579 		if ( isset( $filter['who'] ) ) {
  2706 		if ( isset( $filter['who'] ) ) {
  2582 
  2709 
  2583 		$users = get_users( $query );
  2710 		$users = get_users( $query );
  2584 
  2711 
  2585 		$_users = array();
  2712 		$_users = array();
  2586 		foreach ( $users as $user_data ) {
  2713 		foreach ( $users as $user_data ) {
  2587 			if ( current_user_can( 'edit_user', $user_data->ID ) )
  2714 			if ( current_user_can( 'edit_user', $user_data->ID ) ) {
  2588 				$_users[] = $this->_prepare_user( $user_data, $fields );
  2715 				$_users[] = $this->_prepare_user( $user_data, $fields );
       
  2716 			}
  2589 		}
  2717 		}
  2590 		return $_users;
  2718 		return $_users;
  2591 	}
  2719 	}
  2592 
  2720 
  2593 	/**
  2721 	/**
  2604 	 *     @type array  $fields (optional)
  2732 	 *     @type array  $fields (optional)
  2605 	 * }
  2733 	 * }
  2606 	 * @return array|IXR_Error (@see wp_getUser)
  2734 	 * @return array|IXR_Error (@see wp_getUser)
  2607 	 */
  2735 	 */
  2608 	public function wp_getProfile( $args ) {
  2736 	public function wp_getProfile( $args ) {
  2609 		if ( ! $this->minimum_args( $args, 3 ) )
  2737 		if ( ! $this->minimum_args( $args, 3 ) ) {
  2610 			return $this->error;
  2738 			return $this->error;
       
  2739 		}
  2611 
  2740 
  2612 		$this->escape( $args );
  2741 		$this->escape( $args );
  2613 
  2742 
  2614 		$username = $args[1];
  2743 		$username = $args[1];
  2615 		$password = $args[2];
  2744 		$password = $args[2];
  2619 		} else {
  2748 		} else {
  2620 			/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2749 			/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2621 			$fields = apply_filters( 'xmlrpc_default_user_fields', array( 'all' ), 'wp.getProfile' );
  2750 			$fields = apply_filters( 'xmlrpc_default_user_fields', array( 'all' ), 'wp.getProfile' );
  2622 		}
  2751 		}
  2623 
  2752 
  2624 		if ( ! $user = $this->login( $username, $password ) )
  2753 		if ( ! $user = $this->login( $username, $password ) ) {
  2625 			return $this->error;
  2754 			return $this->error;
       
  2755 		}
  2626 
  2756 
  2627 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2757 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2628 		do_action( 'xmlrpc_call', 'wp.getProfile' );
  2758 		do_action( 'xmlrpc_call', 'wp.getProfile' );
  2629 
  2759 
  2630 		if ( ! current_user_can( 'edit_user', $user->ID ) )
  2760 		if ( ! current_user_can( 'edit_user', $user->ID ) ) {
  2631 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit your profile.' ) );
  2761 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit your profile.' ) );
       
  2762 		}
  2632 
  2763 
  2633 		$user_data = get_userdata( $user->ID );
  2764 		$user_data = get_userdata( $user->ID );
  2634 
  2765 
  2635 		return $this->_prepare_user( $user_data, $fields );
  2766 		return $this->_prepare_user( $user_data, $fields );
  2636 	}
  2767 	}
  2656 	 *      - 'bio'
  2787 	 *      - 'bio'
  2657 	 * }
  2788 	 * }
  2658 	 * @return true|IXR_Error True, on success.
  2789 	 * @return true|IXR_Error True, on success.
  2659 	 */
  2790 	 */
  2660 	public function wp_editProfile( $args ) {
  2791 	public function wp_editProfile( $args ) {
  2661 		if ( ! $this->minimum_args( $args, 4 ) )
  2792 		if ( ! $this->minimum_args( $args, 4 ) ) {
  2662 			return $this->error;
  2793 			return $this->error;
       
  2794 		}
  2663 
  2795 
  2664 		$this->escape( $args );
  2796 		$this->escape( $args );
  2665 
  2797 
  2666 		$username       = $args[1];
  2798 		$username       = $args[1];
  2667 		$password       = $args[2];
  2799 		$password       = $args[2];
  2668 		$content_struct = $args[3];
  2800 		$content_struct = $args[3];
  2669 
  2801 
  2670 		if ( ! $user = $this->login( $username, $password ) )
  2802 		if ( ! $user = $this->login( $username, $password ) ) {
  2671 			return $this->error;
  2803 			return $this->error;
       
  2804 		}
  2672 
  2805 
  2673 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2806 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2674 		do_action( 'xmlrpc_call', 'wp.editProfile' );
  2807 		do_action( 'xmlrpc_call', 'wp.editProfile' );
  2675 
  2808 
  2676 		if ( ! current_user_can( 'edit_user', $user->ID ) )
  2809 		if ( ! current_user_can( 'edit_user', $user->ID ) ) {
  2677 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit your profile.' ) );
  2810 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit your profile.' ) );
       
  2811 		}
  2678 
  2812 
  2679 		// holds data of the user
  2813 		// holds data of the user
  2680 		$user_data = array();
  2814 		$user_data       = array();
  2681 		$user_data['ID'] = $user->ID;
  2815 		$user_data['ID'] = $user->ID;
  2682 
  2816 
  2683 		// only set the user details if it was given
  2817 		// only set the user details if it was given
  2684 		if ( isset( $content_struct['first_name'] ) )
  2818 		if ( isset( $content_struct['first_name'] ) ) {
  2685 			$user_data['first_name'] = $content_struct['first_name'];
  2819 			$user_data['first_name'] = $content_struct['first_name'];
  2686 
  2820 		}
  2687 		if ( isset( $content_struct['last_name'] ) )
  2821 
       
  2822 		if ( isset( $content_struct['last_name'] ) ) {
  2688 			$user_data['last_name'] = $content_struct['last_name'];
  2823 			$user_data['last_name'] = $content_struct['last_name'];
  2689 
  2824 		}
  2690 		if ( isset( $content_struct['url'] ) )
  2825 
       
  2826 		if ( isset( $content_struct['url'] ) ) {
  2691 			$user_data['user_url'] = $content_struct['url'];
  2827 			$user_data['user_url'] = $content_struct['url'];
  2692 
  2828 		}
  2693 		if ( isset( $content_struct['display_name'] ) )
  2829 
       
  2830 		if ( isset( $content_struct['display_name'] ) ) {
  2694 			$user_data['display_name'] = $content_struct['display_name'];
  2831 			$user_data['display_name'] = $content_struct['display_name'];
  2695 
  2832 		}
  2696 		if ( isset( $content_struct['nickname'] ) )
  2833 
       
  2834 		if ( isset( $content_struct['nickname'] ) ) {
  2697 			$user_data['nickname'] = $content_struct['nickname'];
  2835 			$user_data['nickname'] = $content_struct['nickname'];
  2698 
  2836 		}
  2699 		if ( isset( $content_struct['nicename'] ) )
  2837 
       
  2838 		if ( isset( $content_struct['nicename'] ) ) {
  2700 			$user_data['user_nicename'] = $content_struct['nicename'];
  2839 			$user_data['user_nicename'] = $content_struct['nicename'];
  2701 
  2840 		}
  2702 		if ( isset( $content_struct['bio'] ) )
  2841 
       
  2842 		if ( isset( $content_struct['bio'] ) ) {
  2703 			$user_data['description'] = $content_struct['bio'];
  2843 			$user_data['description'] = $content_struct['bio'];
       
  2844 		}
  2704 
  2845 
  2705 		$result = wp_update_user( $user_data );
  2846 		$result = wp_update_user( $user_data );
  2706 
  2847 
  2707 		if ( is_wp_error( $result ) )
  2848 		if ( is_wp_error( $result ) ) {
  2708 			return new IXR_Error( 500, $result->get_error_message() );
  2849 			return new IXR_Error( 500, $result->get_error_message() );
  2709 
  2850 		}
  2710 		if ( ! $result )
  2851 
       
  2852 		if ( ! $result ) {
  2711 			return new IXR_Error( 500, __( 'Sorry, the user cannot be updated.' ) );
  2853 			return new IXR_Error( 500, __( 'Sorry, the user cannot be updated.' ) );
       
  2854 		}
  2712 
  2855 
  2713 		return true;
  2856 		return true;
  2714 	}
  2857 	}
  2715 
  2858 
  2716 	/**
  2859 	/**
  2733 
  2876 
  2734 		$page_id  = (int) $args[1];
  2877 		$page_id  = (int) $args[1];
  2735 		$username = $args[2];
  2878 		$username = $args[2];
  2736 		$password = $args[3];
  2879 		$password = $args[3];
  2737 
  2880 
  2738 		if ( !$user = $this->login($username, $password) ) {
  2881 		if ( ! $user = $this->login( $username, $password ) ) {
  2739 			return $this->error;
  2882 			return $this->error;
  2740 		}
  2883 		}
  2741 
  2884 
  2742 		$page = get_post($page_id);
  2885 		$page = get_post( $page_id );
  2743 		if ( ! $page )
  2886 		if ( ! $page ) {
  2744 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  2887 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  2745 
  2888 		}
  2746 		if ( !current_user_can( 'edit_page', $page_id ) )
  2889 
       
  2890 		if ( ! current_user_can( 'edit_page', $page_id ) ) {
  2747 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit this page.' ) );
  2891 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit this page.' ) );
       
  2892 		}
  2748 
  2893 
  2749 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2894 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2750 		do_action( 'xmlrpc_call', 'wp.getPage' );
  2895 		do_action( 'xmlrpc_call', 'wp.getPage' );
  2751 
  2896 
  2752 		// If we found the page then format the data.
  2897 		// If we found the page then format the data.
  2753 		if ( $page->ID && ($page->post_type == 'page') ) {
  2898 		if ( $page->ID && ( $page->post_type == 'page' ) ) {
  2754 			return $this->_prepare_page( $page );
  2899 			return $this->_prepare_page( $page );
  2755 		}
  2900 		} else {
  2756 		// If the page doesn't exist indicate that.
  2901 			// If the page doesn't exist indicate that.
  2757 		else {
       
  2758 			return new IXR_Error( 404, __( 'Sorry, no such page.' ) );
  2902 			return new IXR_Error( 404, __( 'Sorry, no such page.' ) );
  2759 		}
  2903 		}
  2760 	}
  2904 	}
  2761 
  2905 
  2762 	/**
  2906 	/**
  2777 	public function wp_getPages( $args ) {
  2921 	public function wp_getPages( $args ) {
  2778 		$this->escape( $args );
  2922 		$this->escape( $args );
  2779 
  2923 
  2780 		$username  = $args[1];
  2924 		$username  = $args[1];
  2781 		$password  = $args[2];
  2925 		$password  = $args[2];
  2782 		$num_pages = isset($args[3]) ? (int) $args[3] : 10;
  2926 		$num_pages = isset( $args[3] ) ? (int) $args[3] : 10;
  2783 
  2927 
  2784 		if ( !$user = $this->login($username, $password) )
  2928 		if ( ! $user = $this->login( $username, $password ) ) {
  2785 			return $this->error;
  2929 			return $this->error;
  2786 
  2930 		}
  2787 		if ( !current_user_can( 'edit_pages' ) )
  2931 
       
  2932 		if ( ! current_user_can( 'edit_pages' ) ) {
  2788 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit pages.' ) );
  2933 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit pages.' ) );
       
  2934 		}
  2789 
  2935 
  2790 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2936 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2791 		do_action( 'xmlrpc_call', 'wp.getPages' );
  2937 		do_action( 'xmlrpc_call', 'wp.getPages' );
  2792 
  2938 
  2793 		$pages = get_posts( array('post_type' => 'page', 'post_status' => 'any', 'numberposts' => $num_pages) );
  2939 		$pages     = get_posts(
  2794 		$num_pages = count($pages);
  2940 			array(
       
  2941 				'post_type'   => 'page',
       
  2942 				'post_status' => 'any',
       
  2943 				'numberposts' => $num_pages,
       
  2944 			)
       
  2945 		);
       
  2946 		$num_pages = count( $pages );
  2795 
  2947 
  2796 		// If we have pages, put together their info.
  2948 		// If we have pages, put together their info.
  2797 		if ( $num_pages >= 1 ) {
  2949 		if ( $num_pages >= 1 ) {
  2798 			$pages_struct = array();
  2950 			$pages_struct = array();
  2799 
  2951 
  2800 			foreach ($pages as $page) {
  2952 			foreach ( $pages as $page ) {
  2801 				if ( current_user_can( 'edit_page', $page->ID ) )
  2953 				if ( current_user_can( 'edit_page', $page->ID ) ) {
  2802 					$pages_struct[] = $this->_prepare_page( $page );
  2954 					$pages_struct[] = $this->_prepare_page( $page );
       
  2955 				}
  2803 			}
  2956 			}
  2804 
  2957 
  2805 			return $pages_struct;
  2958 			return $pages_struct;
  2806 		}
  2959 		}
  2807 
  2960 
  2828 	public function wp_newPage( $args ) {
  2981 	public function wp_newPage( $args ) {
  2829 		// Items not escaped here will be escaped in newPost.
  2982 		// Items not escaped here will be escaped in newPost.
  2830 		$username = $this->escape( $args[1] );
  2983 		$username = $this->escape( $args[1] );
  2831 		$password = $this->escape( $args[2] );
  2984 		$password = $this->escape( $args[2] );
  2832 
  2985 
  2833 		if ( !$user = $this->login($username, $password) )
  2986 		if ( ! $user = $this->login( $username, $password ) ) {
  2834 			return $this->error;
  2987 			return $this->error;
       
  2988 		}
  2835 
  2989 
  2836 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2990 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2837 		do_action( 'xmlrpc_call', 'wp.newPage' );
  2991 		do_action( 'xmlrpc_call', 'wp.newPage' );
  2838 
  2992 
  2839 		// Mark this as content for a page.
  2993 		// Mark this as content for a page.
  2840 		$args[3]["post_type"] = 'page';
  2994 		$args[3]['post_type'] = 'page';
  2841 
  2995 
  2842 		// Let mw_newPost do all of the heavy lifting.
  2996 		// Let mw_newPost do all of the heavy lifting.
  2843 		return $this->mw_newPost( $args );
  2997 		return $this->mw_newPost( $args );
  2844 	}
  2998 	}
  2845 
  2999 
  2863 
  3017 
  2864 		$username = $args[1];
  3018 		$username = $args[1];
  2865 		$password = $args[2];
  3019 		$password = $args[2];
  2866 		$page_id  = (int) $args[3];
  3020 		$page_id  = (int) $args[3];
  2867 
  3021 
  2868 		if ( !$user = $this->login($username, $password) )
  3022 		if ( ! $user = $this->login( $username, $password ) ) {
  2869 			return $this->error;
  3023 			return $this->error;
       
  3024 		}
  2870 
  3025 
  2871 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3026 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2872 		do_action( 'xmlrpc_call', 'wp.deletePage' );
  3027 		do_action( 'xmlrpc_call', 'wp.deletePage' );
  2873 
  3028 
  2874 		// Get the current page based on the page_id and
  3029 		// Get the current page based on the page_id and
  2875 		// make sure it is a page and not a post.
  3030 		// make sure it is a page and not a post.
  2876 		$actual_page = get_post($page_id, ARRAY_A);
  3031 		$actual_page = get_post( $page_id, ARRAY_A );
  2877 		if ( !$actual_page || ($actual_page['post_type'] != 'page') )
  3032 		if ( ! $actual_page || ( $actual_page['post_type'] != 'page' ) ) {
  2878 			return new IXR_Error( 404, __( 'Sorry, no such page.' ) );
  3033 			return new IXR_Error( 404, __( 'Sorry, no such page.' ) );
       
  3034 		}
  2879 
  3035 
  2880 		// Make sure the user can delete pages.
  3036 		// Make sure the user can delete pages.
  2881 		if ( !current_user_can('delete_page', $page_id) )
  3037 		if ( ! current_user_can( 'delete_page', $page_id ) ) {
  2882 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to delete this page.' ) );
  3038 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to delete this page.' ) );
       
  3039 		}
  2883 
  3040 
  2884 		// Attempt to delete the page.
  3041 		// Attempt to delete the page.
  2885 		$result = wp_delete_post($page_id);
  3042 		$result = wp_delete_post( $page_id );
  2886 		if ( !$result )
  3043 		if ( ! $result ) {
  2887 			return new IXR_Error( 500, __( 'Failed to delete the page.' ) );
  3044 			return new IXR_Error( 500, __( 'Failed to delete the page.' ) );
       
  3045 		}
  2888 
  3046 
  2889 		/**
  3047 		/**
  2890 		 * Fires after a page has been successfully deleted via XML-RPC.
  3048 		 * Fires after a page has been successfully deleted via XML-RPC.
  2891 		 *
  3049 		 *
  2892 		 * @since 3.4.0
  3050 		 * @since 3.4.0
  2925 		$publish  = $args[5];
  3083 		$publish  = $args[5];
  2926 
  3084 
  2927 		$escaped_username = $this->escape( $username );
  3085 		$escaped_username = $this->escape( $username );
  2928 		$escaped_password = $this->escape( $password );
  3086 		$escaped_password = $this->escape( $password );
  2929 
  3087 
  2930 		if ( !$user = $this->login( $escaped_username, $escaped_password ) ) {
  3088 		if ( ! $user = $this->login( $escaped_username, $escaped_password ) ) {
  2931 			return $this->error;
  3089 			return $this->error;
  2932 		}
  3090 		}
  2933 
  3091 
  2934 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3092 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2935 		do_action( 'xmlrpc_call', 'wp.editPage' );
  3093 		do_action( 'xmlrpc_call', 'wp.editPage' );
  2936 
  3094 
  2937 		// Get the page data and make sure it is a page.
  3095 		// Get the page data and make sure it is a page.
  2938 		$actual_page = get_post($page_id, ARRAY_A);
  3096 		$actual_page = get_post( $page_id, ARRAY_A );
  2939 		if ( !$actual_page || ($actual_page['post_type'] != 'page') )
  3097 		if ( ! $actual_page || ( $actual_page['post_type'] != 'page' ) ) {
  2940 			return new IXR_Error( 404, __( 'Sorry, no such page.' ) );
  3098 			return new IXR_Error( 404, __( 'Sorry, no such page.' ) );
       
  3099 		}
  2941 
  3100 
  2942 		// Make sure the user is allowed to edit pages.
  3101 		// Make sure the user is allowed to edit pages.
  2943 		if ( !current_user_can('edit_page', $page_id) )
  3102 		if ( ! current_user_can( 'edit_page', $page_id ) ) {
  2944 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit this page.' ) );
  3103 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit this page.' ) );
       
  3104 		}
  2945 
  3105 
  2946 		// Mark this as content for a page.
  3106 		// Mark this as content for a page.
  2947 		$content['post_type'] = 'page';
  3107 		$content['post_type'] = 'page';
  2948 
  3108 
  2949 		// Arrange args in the way mw_editPost understands.
  3109 		// Arrange args in the way mw_editPost understands.
  2950 		$args = array(
  3110 		$args = array(
  2951 			$page_id,
  3111 			$page_id,
  2952 			$username,
  3112 			$username,
  2953 			$password,
  3113 			$password,
  2954 			$content,
  3114 			$content,
  2955 			$publish
  3115 			$publish,
  2956 		);
  3116 		);
  2957 
  3117 
  2958 		// Let mw_editPost do all of the heavy lifting.
  3118 		// Let mw_editPost do all of the heavy lifting.
  2959 		return $this->mw_editPost( $args );
  3119 		return $this->mw_editPost( $args );
  2960 	}
  3120 	}
  2981 		$this->escape( $args );
  3141 		$this->escape( $args );
  2982 
  3142 
  2983 		$username = $args[1];
  3143 		$username = $args[1];
  2984 		$password = $args[2];
  3144 		$password = $args[2];
  2985 
  3145 
  2986 		if ( !$user = $this->login($username, $password) )
  3146 		if ( ! $user = $this->login( $username, $password ) ) {
  2987 			return $this->error;
  3147 			return $this->error;
  2988 
  3148 		}
  2989 		if ( !current_user_can( 'edit_pages' ) )
  3149 
       
  3150 		if ( ! current_user_can( 'edit_pages' ) ) {
  2990 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit pages.' ) );
  3151 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit pages.' ) );
       
  3152 		}
  2991 
  3153 
  2992 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3154 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2993 		do_action( 'xmlrpc_call', 'wp.getPageList' );
  3155 		do_action( 'xmlrpc_call', 'wp.getPageList' );
  2994 
  3156 
  2995 		// Get list of pages ids and titles
  3157 		// Get list of pages ids and titles
  2996 		$page_list = $wpdb->get_results("
  3158 		$page_list = $wpdb->get_results(
       
  3159 			"
  2997 			SELECT ID page_id,
  3160 			SELECT ID page_id,
  2998 				post_title page_title,
  3161 				post_title page_title,
  2999 				post_parent page_parent_id,
  3162 				post_parent page_parent_id,
  3000 				post_date_gmt,
  3163 				post_date_gmt,
  3001 				post_date,
  3164 				post_date,
  3002 				post_status
  3165 				post_status
  3003 			FROM {$wpdb->posts}
  3166 			FROM {$wpdb->posts}
  3004 			WHERE post_type = 'page'
  3167 			WHERE post_type = 'page'
  3005 			ORDER BY ID
  3168 			ORDER BY ID
  3006 		");
  3169 		"
       
  3170 		);
  3007 
  3171 
  3008 		// The date needs to be formatted properly.
  3172 		// The date needs to be formatted properly.
  3009 		$num_pages = count($page_list);
  3173 		$num_pages = count( $page_list );
  3010 		for ( $i = 0; $i < $num_pages; $i++ ) {
  3174 		for ( $i = 0; $i < $num_pages; $i++ ) {
  3011 			$page_list[$i]->dateCreated = $this->_convert_date(  $page_list[$i]->post_date );
  3175 			$page_list[ $i ]->dateCreated      = $this->_convert_date( $page_list[ $i ]->post_date );
  3012 			$page_list[$i]->date_created_gmt = $this->_convert_date_gmt( $page_list[$i]->post_date_gmt, $page_list[$i]->post_date );
  3176 			$page_list[ $i ]->date_created_gmt = $this->_convert_date_gmt( $page_list[ $i ]->post_date_gmt, $page_list[ $i ]->post_date );
  3013 
  3177 
  3014 			unset($page_list[$i]->post_date_gmt);
  3178 			unset( $page_list[ $i ]->post_date_gmt );
  3015 			unset($page_list[$i]->post_date);
  3179 			unset( $page_list[ $i ]->post_date );
  3016 			unset($page_list[$i]->post_status);
  3180 			unset( $page_list[ $i ]->post_status );
  3017 		}
  3181 		}
  3018 
  3182 
  3019 		return $page_list;
  3183 		return $page_list;
  3020 	}
  3184 	}
  3021 
  3185 
  3037 		$this->escape( $args );
  3201 		$this->escape( $args );
  3038 
  3202 
  3039 		$username = $args[1];
  3203 		$username = $args[1];
  3040 		$password = $args[2];
  3204 		$password = $args[2];
  3041 
  3205 
  3042 		if ( !$user = $this->login($username, $password) )
  3206 		if ( ! $user = $this->login( $username, $password ) ) {
  3043 			return $this->error;
  3207 			return $this->error;
  3044 
  3208 		}
  3045 		if ( !current_user_can('edit_posts') )
  3209 
       
  3210 		if ( ! current_user_can( 'edit_posts' ) ) {
  3046 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit posts.' ) );
  3211 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit posts.' ) );
       
  3212 		}
  3047 
  3213 
  3048 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3214 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3049 		do_action( 'xmlrpc_call', 'wp.getAuthors' );
  3215 		do_action( 'xmlrpc_call', 'wp.getAuthors' );
  3050 
  3216 
  3051 		$authors = array();
  3217 		$authors = array();
  3052 		foreach ( get_users( array( 'fields' => array('ID','user_login','display_name') ) ) as $user ) {
  3218 		foreach ( get_users( array( 'fields' => array( 'ID', 'user_login', 'display_name' ) ) ) as $user ) {
  3053 			$authors[] = array(
  3219 			$authors[] = array(
  3054 				'user_id'       => $user->ID,
  3220 				'user_id'      => $user->ID,
  3055 				'user_login'    => $user->user_login,
  3221 				'user_login'   => $user->user_login,
  3056 				'display_name'  => $user->display_name
  3222 				'display_name' => $user->display_name,
  3057 			);
  3223 			);
  3058 		}
  3224 		}
  3059 
  3225 
  3060 		return $authors;
  3226 		return $authors;
  3061 	}
  3227 	}
  3078 		$this->escape( $args );
  3244 		$this->escape( $args );
  3079 
  3245 
  3080 		$username = $args[1];
  3246 		$username = $args[1];
  3081 		$password = $args[2];
  3247 		$password = $args[2];
  3082 
  3248 
  3083 		if ( !$user = $this->login($username, $password) )
  3249 		if ( ! $user = $this->login( $username, $password ) ) {
  3084 			return $this->error;
  3250 			return $this->error;
  3085 
  3251 		}
  3086 		if ( !current_user_can( 'edit_posts' ) )
  3252 
       
  3253 		if ( ! current_user_can( 'edit_posts' ) ) {
  3087 			return new IXR_Error( 401, __( 'Sorry, you must be able to edit posts on this site in order to view tags.' ) );
  3254 			return new IXR_Error( 401, __( 'Sorry, you must be able to edit posts on this site in order to view tags.' ) );
       
  3255 		}
  3088 
  3256 
  3089 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3257 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3090 		do_action( 'xmlrpc_call', 'wp.getKeywords' );
  3258 		do_action( 'xmlrpc_call', 'wp.getKeywords' );
  3091 
  3259 
  3092 		$tags = array();
  3260 		$tags = array();
  3093 
  3261 
  3094 		if ( $all_tags = get_tags() ) {
  3262 		if ( $all_tags = get_tags() ) {
  3095 			foreach ( (array) $all_tags as $tag ) {
  3263 			foreach ( (array) $all_tags as $tag ) {
  3096 				$struct = array();
  3264 				$struct             = array();
  3097 				$struct['tag_id']			= $tag->term_id;
  3265 				$struct['tag_id']   = $tag->term_id;
  3098 				$struct['name']				= $tag->name;
  3266 				$struct['name']     = $tag->name;
  3099 				$struct['count']			= $tag->count;
  3267 				$struct['count']    = $tag->count;
  3100 				$struct['slug']				= $tag->slug;
  3268 				$struct['slug']     = $tag->slug;
  3101 				$struct['html_url']			= esc_html( get_tag_link( $tag->term_id ) );
  3269 				$struct['html_url'] = esc_html( get_tag_link( $tag->term_id ) );
  3102 				$struct['rss_url']			= esc_html( get_tag_feed_link( $tag->term_id ) );
  3270 				$struct['rss_url']  = esc_html( get_tag_feed_link( $tag->term_id ) );
  3103 
  3271 
  3104 				$tags[] = $struct;
  3272 				$tags[] = $struct;
  3105 			}
  3273 			}
  3106 		}
  3274 		}
  3107 
  3275 
  3128 
  3296 
  3129 		$username = $args[1];
  3297 		$username = $args[1];
  3130 		$password = $args[2];
  3298 		$password = $args[2];
  3131 		$category = $args[3];
  3299 		$category = $args[3];
  3132 
  3300 
  3133 		if ( !$user = $this->login($username, $password) )
  3301 		if ( ! $user = $this->login( $username, $password ) ) {
  3134 			return $this->error;
  3302 			return $this->error;
       
  3303 		}
  3135 
  3304 
  3136 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3305 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3137 		do_action( 'xmlrpc_call', 'wp.newCategory' );
  3306 		do_action( 'xmlrpc_call', 'wp.newCategory' );
  3138 
  3307 
  3139 		// Make sure the user is allowed to add a category.
  3308 		// Make sure the user is allowed to add a category.
  3141 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to add a category.' ) );
  3310 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to add a category.' ) );
  3142 		}
  3311 		}
  3143 
  3312 
  3144 		// If no slug was provided make it empty so that
  3313 		// If no slug was provided make it empty so that
  3145 		// WordPress will generate one.
  3314 		// WordPress will generate one.
  3146 		if ( empty($category['slug']) )
  3315 		if ( empty( $category['slug'] ) ) {
  3147 			$category['slug'] = '';
  3316 			$category['slug'] = '';
       
  3317 		}
  3148 
  3318 
  3149 		// If no parent_id was provided make it empty
  3319 		// If no parent_id was provided make it empty
  3150 		// so that it will be a top level page (no parent).
  3320 		// so that it will be a top level page (no parent).
  3151 		if ( !isset($category['parent_id']) )
  3321 		if ( ! isset( $category['parent_id'] ) ) {
  3152 			$category['parent_id'] = '';
  3322 			$category['parent_id'] = '';
       
  3323 		}
  3153 
  3324 
  3154 		// If no description was provided make it empty.
  3325 		// If no description was provided make it empty.
  3155 		if ( empty($category["description"]) )
  3326 		if ( empty( $category['description'] ) ) {
  3156 			$category["description"] = "";
  3327 			$category['description'] = '';
       
  3328 		}
  3157 
  3329 
  3158 		$new_category = array(
  3330 		$new_category = array(
  3159 			'cat_name'				=> $category['name'],
  3331 			'cat_name'             => $category['name'],
  3160 			'category_nicename'		=> $category['slug'],
  3332 			'category_nicename'    => $category['slug'],
  3161 			'category_parent'		=> $category['parent_id'],
  3333 			'category_parent'      => $category['parent_id'],
  3162 			'category_description'	=> $category['description']
  3334 			'category_description' => $category['description'],
  3163 		);
  3335 		);
  3164 
  3336 
  3165 		$cat_id = wp_insert_category($new_category, true);
  3337 		$cat_id = wp_insert_category( $new_category, true );
  3166 		if ( is_wp_error( $cat_id ) ) {
  3338 		if ( is_wp_error( $cat_id ) ) {
  3167 			if ( 'term_exists' == $cat_id->get_error_code() )
  3339 			if ( 'term_exists' == $cat_id->get_error_code() ) {
  3168 				return (int) $cat_id->get_error_data();
  3340 				return (int) $cat_id->get_error_data();
  3169 			else
  3341 			} else {
  3170 				return new IXR_Error(500, __('Sorry, the new category failed.'));
  3342 				return new IXR_Error( 500, __( 'Sorry, the new category failed.' ) );
       
  3343 			}
  3171 		} elseif ( ! $cat_id ) {
  3344 		} elseif ( ! $cat_id ) {
  3172 			return new IXR_Error(500, __('Sorry, the new category failed.'));
  3345 			return new IXR_Error( 500, __( 'Sorry, the new category failed.' ) );
  3173 		}
  3346 		}
  3174 
  3347 
  3175 		/**
  3348 		/**
  3176 		 * Fires after a new category has been successfully created via XML-RPC.
  3349 		 * Fires after a new category has been successfully created via XML-RPC.
  3177 		 *
  3350 		 *
  3205 
  3378 
  3206 		$username    = $args[1];
  3379 		$username    = $args[1];
  3207 		$password    = $args[2];
  3380 		$password    = $args[2];
  3208 		$category_id = (int) $args[3];
  3381 		$category_id = (int) $args[3];
  3209 
  3382 
  3210 		if ( !$user = $this->login($username, $password) )
  3383 		if ( ! $user = $this->login( $username, $password ) ) {
  3211 			return $this->error;
  3384 			return $this->error;
       
  3385 		}
  3212 
  3386 
  3213 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3387 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3214 		do_action( 'xmlrpc_call', 'wp.deleteCategory' );
  3388 		do_action( 'xmlrpc_call', 'wp.deleteCategory' );
  3215 
  3389 
  3216 		if ( ! current_user_can( 'delete_term', $category_id ) ) {
  3390 		if ( ! current_user_can( 'delete_term', $category_id ) ) {
  3256 		$username    = $args[1];
  3430 		$username    = $args[1];
  3257 		$password    = $args[2];
  3431 		$password    = $args[2];
  3258 		$category    = $args[3];
  3432 		$category    = $args[3];
  3259 		$max_results = (int) $args[4];
  3433 		$max_results = (int) $args[4];
  3260 
  3434 
  3261 		if ( !$user = $this->login($username, $password) )
  3435 		if ( ! $user = $this->login( $username, $password ) ) {
  3262 			return $this->error;
  3436 			return $this->error;
  3263 
  3437 		}
  3264 		if ( !current_user_can( 'edit_posts' ) )
  3438 
       
  3439 		if ( ! current_user_can( 'edit_posts' ) ) {
  3265 			return new IXR_Error( 401, __( 'Sorry, you must be able to edit posts on this site in order to view categories.' ) );
  3440 			return new IXR_Error( 401, __( 'Sorry, you must be able to edit posts on this site in order to view categories.' ) );
       
  3441 		}
  3266 
  3442 
  3267 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3443 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3268 		do_action( 'xmlrpc_call', 'wp.suggestCategories' );
  3444 		do_action( 'xmlrpc_call', 'wp.suggestCategories' );
  3269 
  3445 
  3270 		$category_suggestions = array();
  3446 		$category_suggestions = array();
  3271 		$args = array('get' => 'all', 'number' => $max_results, 'name__like' => $category);
  3447 		$args                 = array(
  3272 		foreach ( (array) get_categories($args) as $cat ) {
  3448 			'get'        => 'all',
       
  3449 			'number'     => $max_results,
       
  3450 			'name__like' => $category,
       
  3451 		);
       
  3452 		foreach ( (array) get_categories( $args ) as $cat ) {
  3273 			$category_suggestions[] = array(
  3453 			$category_suggestions[] = array(
  3274 				'category_id'	=> $cat->term_id,
  3454 				'category_id'   => $cat->term_id,
  3275 				'category_name'	=> $cat->name
  3455 				'category_name' => $cat->name,
  3276 			);
  3456 			);
  3277 		}
  3457 		}
  3278 
  3458 
  3279 		return $category_suggestions;
  3459 		return $category_suggestions;
  3280 	}
  3460 	}
  3292 	 *     @type string $password
  3472 	 *     @type string $password
  3293 	 *     @type int    $comment_id
  3473 	 *     @type int    $comment_id
  3294 	 * }
  3474 	 * }
  3295 	 * @return array|IXR_Error
  3475 	 * @return array|IXR_Error
  3296 	 */
  3476 	 */
  3297 	public function wp_getComment($args) {
  3477 	public function wp_getComment( $args ) {
  3298 		$this->escape($args);
  3478 		$this->escape( $args );
  3299 
  3479 
  3300 		$username	= $args[1];
  3480 		$username   = $args[1];
  3301 		$password	= $args[2];
  3481 		$password   = $args[2];
  3302 		$comment_id	= (int) $args[3];
  3482 		$comment_id = (int) $args[3];
  3303 
  3483 
  3304 		if ( ! $user = $this->login( $username, $password ) ) {
  3484 		if ( ! $user = $this->login( $username, $password ) ) {
  3305 			return $this->error;
  3485 			return $this->error;
  3306 		}
  3486 		}
  3307 
  3487 
  3348 	public function wp_getComments( $args ) {
  3528 	public function wp_getComments( $args ) {
  3349 		$this->escape( $args );
  3529 		$this->escape( $args );
  3350 
  3530 
  3351 		$username = $args[1];
  3531 		$username = $args[1];
  3352 		$password = $args[2];
  3532 		$password = $args[2];
  3353 		$struct	  = isset( $args[3] ) ? $args[3] : array();
  3533 		$struct   = isset( $args[3] ) ? $args[3] : array();
  3354 
  3534 
  3355 		if ( ! $user = $this->login( $username, $password ) ) {
  3535 		if ( ! $user = $this->login( $username, $password ) ) {
  3356 			return $this->error;
  3536 			return $this->error;
  3357 		}
  3537 		}
  3358 
  3538 
  3391 		$number = 10;
  3571 		$number = 10;
  3392 		if ( isset( $struct['number'] ) ) {
  3572 		if ( isset( $struct['number'] ) ) {
  3393 			$number = absint( $struct['number'] );
  3573 			$number = absint( $struct['number'] );
  3394 		}
  3574 		}
  3395 
  3575 
  3396 		$comments = get_comments( array(
  3576 		$comments = get_comments(
  3397 			'status' => $status,
  3577 			array(
  3398 			'post_id' => $post_id,
  3578 				'status'    => $status,
  3399 			'offset' => $offset,
  3579 				'post_id'   => $post_id,
  3400 			'number' => $number,
  3580 				'offset'    => $offset,
  3401 			'post_type' => $post_type,
  3581 				'number'    => $number,
  3402 		) );
  3582 				'post_type' => $post_type,
       
  3583 			)
       
  3584 		);
  3403 
  3585 
  3404 		$comments_struct = array();
  3586 		$comments_struct = array();
  3405 		if ( is_array( $comments ) ) {
  3587 		if ( is_array( $comments ) ) {
  3406 			foreach ( $comments as $comment ) {
  3588 			foreach ( $comments as $comment ) {
  3407 				$comments_struct[] = $this->_prepare_comment( $comment );
  3589 				$comments_struct[] = $this->_prepare_comment( $comment );
  3428 	 *     @type int    $comment_ID
  3610 	 *     @type int    $comment_ID
  3429 	 * }
  3611 	 * }
  3430 	 * @return bool|IXR_Error See wp_delete_comment().
  3612 	 * @return bool|IXR_Error See wp_delete_comment().
  3431 	 */
  3613 	 */
  3432 	public function wp_deleteComment( $args ) {
  3614 	public function wp_deleteComment( $args ) {
  3433 		$this->escape($args);
  3615 		$this->escape( $args );
  3434 
  3616 
  3435 		$username	= $args[1];
  3617 		$username   = $args[1];
  3436 		$password	= $args[2];
  3618 		$password   = $args[2];
  3437 		$comment_ID	= (int) $args[3];
  3619 		$comment_ID = (int) $args[3];
  3438 
  3620 
  3439 		if ( ! $user = $this->login( $username, $password ) ) {
  3621 		if ( ! $user = $this->login( $username, $password ) ) {
  3440 			return $this->error;
  3622 			return $this->error;
  3441 		}
  3623 		}
  3442 
  3624 
  3496 	 * @return true|IXR_Error True, on success.
  3678 	 * @return true|IXR_Error True, on success.
  3497 	 */
  3679 	 */
  3498 	public function wp_editComment( $args ) {
  3680 	public function wp_editComment( $args ) {
  3499 		$this->escape( $args );
  3681 		$this->escape( $args );
  3500 
  3682 
  3501 		$username	= $args[1];
  3683 		$username       = $args[1];
  3502 		$password	= $args[2];
  3684 		$password       = $args[2];
  3503 		$comment_ID	= (int) $args[3];
  3685 		$comment_ID     = (int) $args[3];
  3504 		$content_struct = $args[4];
  3686 		$content_struct = $args[4];
  3505 
  3687 
  3506 		if ( !$user = $this->login( $username, $password ) ) {
  3688 		if ( ! $user = $this->login( $username, $password ) ) {
  3507 			return $this->error;
  3689 			return $this->error;
  3508 		}
  3690 		}
  3509 
  3691 
  3510 		if ( ! get_comment( $comment_ID ) ) {
  3692 		if ( ! get_comment( $comment_ID ) ) {
  3511 			return new IXR_Error( 404, __( 'Invalid comment ID.' ) );
  3693 			return new IXR_Error( 404, __( 'Invalid comment ID.' ) );
  3515 			return new IXR_Error( 403, __( 'Sorry, you are not allowed to moderate or edit this comment.' ) );
  3697 			return new IXR_Error( 403, __( 'Sorry, you are not allowed to moderate or edit this comment.' ) );
  3516 		}
  3698 		}
  3517 
  3699 
  3518 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3700 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3519 		do_action( 'xmlrpc_call', 'wp.editComment' );
  3701 		do_action( 'xmlrpc_call', 'wp.editComment' );
  3520 
  3702 		$comment = array(
  3521 		if ( isset($content_struct['status']) ) {
  3703 			'comment_ID' => $comment_ID,
       
  3704 		);
       
  3705 
       
  3706 		if ( isset( $content_struct['status'] ) ) {
  3522 			$statuses = get_comment_statuses();
  3707 			$statuses = get_comment_statuses();
  3523 			$statuses = array_keys($statuses);
  3708 			$statuses = array_keys( $statuses );
  3524 
  3709 
  3525 			if ( ! in_array($content_struct['status'], $statuses) )
  3710 			if ( ! in_array( $content_struct['status'], $statuses ) ) {
  3526 				return new IXR_Error( 401, __( 'Invalid comment status.' ) );
  3711 				return new IXR_Error( 401, __( 'Invalid comment status.' ) );
  3527 			$comment_approved = $content_struct['status'];
  3712 			}
       
  3713 
       
  3714 			$comment['comment_approved'] = $content_struct['status'];
  3528 		}
  3715 		}
  3529 
  3716 
  3530 		// Do some timestamp voodoo
  3717 		// Do some timestamp voodoo
  3531 		if ( !empty( $content_struct['date_created_gmt'] ) ) {
  3718 		if ( ! empty( $content_struct['date_created_gmt'] ) ) {
  3532 			// We know this is supposed to be GMT, so we're going to slap that Z on there by force
  3719 			// We know this is supposed to be GMT, so we're going to slap that Z on there by force
  3533 			$dateCreated = rtrim( $content_struct['date_created_gmt']->getIso(), 'Z' ) . 'Z';
  3720 			$dateCreated                 = rtrim( $content_struct['date_created_gmt']->getIso(), 'Z' ) . 'Z';
  3534 			$comment_date = get_date_from_gmt(iso8601_to_datetime($dateCreated));
  3721 			$comment['comment_date']     = get_date_from_gmt( iso8601_to_datetime( $dateCreated ) );
  3535 			$comment_date_gmt = iso8601_to_datetime($dateCreated, 'GMT');
  3722 			$comment['comment_date_gmt'] = iso8601_to_datetime( $dateCreated, 'GMT' );
  3536 		}
  3723 		}
  3537 
  3724 
  3538 		if ( isset($content_struct['content']) )
  3725 		if ( isset( $content_struct['content'] ) ) {
  3539 			$comment_content = $content_struct['content'];
  3726 			$comment['comment_content'] = $content_struct['content'];
  3540 
  3727 		}
  3541 		if ( isset($content_struct['author']) )
  3728 
  3542 			$comment_author = $content_struct['author'];
  3729 		if ( isset( $content_struct['author'] ) ) {
  3543 
  3730 			$comment['comment_author'] = $content_struct['author'];
  3544 		if ( isset($content_struct['author_url']) )
  3731 		}
  3545 			$comment_author_url = $content_struct['author_url'];
  3732 
  3546 
  3733 		if ( isset( $content_struct['author_url'] ) ) {
  3547 		if ( isset($content_struct['author_email']) )
  3734 			$comment['comment_author_url'] = $content_struct['author_url'];
  3548 			$comment_author_email = $content_struct['author_email'];
  3735 		}
  3549 
  3736 
  3550 		// We've got all the data -- post it:
  3737 		if ( isset( $content_struct['author_email'] ) ) {
  3551 		$comment = compact('comment_ID', 'comment_content', 'comment_approved', 'comment_date', 'comment_date_gmt', 'comment_author', 'comment_author_email', 'comment_author_url');
  3738 			$comment['comment_author_email'] = $content_struct['author_email'];
  3552 
  3739 		}
  3553 		$result = wp_update_comment($comment);
  3740 
  3554 		if ( is_wp_error( $result ) )
  3741 		$result = wp_update_comment( $comment );
  3555 			return new IXR_Error(500, $result->get_error_message());
  3742 		if ( is_wp_error( $result ) ) {
  3556 
  3743 			return new IXR_Error( 500, $result->get_error_message() );
  3557 		if ( !$result )
  3744 		}
  3558 			return new IXR_Error(500, __('Sorry, the comment could not be edited.'));
  3745 
       
  3746 		if ( ! $result ) {
       
  3747 			return new IXR_Error( 500, __( 'Sorry, the comment could not be edited.' ) );
       
  3748 		}
  3559 
  3749 
  3560 		/**
  3750 		/**
  3561 		 * Fires after a comment has been successfully updated via XML-RPC.
  3751 		 * Fires after a comment has been successfully updated via XML-RPC.
  3562 		 *
  3752 		 *
  3563 		 * @since 3.4.0
  3753 		 * @since 3.4.0
  3584 	 *     @type string|int $post
  3774 	 *     @type string|int $post
  3585 	 *     @type array      $content_struct
  3775 	 *     @type array      $content_struct
  3586 	 * }
  3776 	 * }
  3587 	 * @return int|IXR_Error See wp_new_comment().
  3777 	 * @return int|IXR_Error See wp_new_comment().
  3588 	 */
  3778 	 */
  3589 	public function wp_newComment($args) {
  3779 	public function wp_newComment( $args ) {
  3590 		$this->escape($args);
  3780 		$this->escape( $args );
  3591 
  3781 
  3592 		$username       = $args[1];
  3782 		$username       = $args[1];
  3593 		$password       = $args[2];
  3783 		$password       = $args[2];
  3594 		$post           = $args[3];
  3784 		$post           = $args[3];
  3595 		$content_struct = $args[4];
  3785 		$content_struct = $args[4];
  3602 		 * @param bool $allow Whether to allow anonymous commenting via XML-RPC.
  3792 		 * @param bool $allow Whether to allow anonymous commenting via XML-RPC.
  3603 		 *                    Default false.
  3793 		 *                    Default false.
  3604 		 */
  3794 		 */
  3605 		$allow_anon = apply_filters( 'xmlrpc_allow_anonymous_comments', false );
  3795 		$allow_anon = apply_filters( 'xmlrpc_allow_anonymous_comments', false );
  3606 
  3796 
  3607 		$user = $this->login($username, $password);
  3797 		$user = $this->login( $username, $password );
  3608 
  3798 
  3609 		if ( !$user ) {
  3799 		if ( ! $user ) {
  3610 			$logged_in = false;
  3800 			$logged_in = false;
  3611 			if ( $allow_anon && get_option('comment_registration') ) {
  3801 			if ( $allow_anon && get_option( 'comment_registration' ) ) {
  3612 				return new IXR_Error( 403, __( 'You must be registered to comment.' ) );
  3802 				return new IXR_Error( 403, __( 'You must be registered to comment.' ) );
  3613 			} elseif ( ! $allow_anon ) {
  3803 			} elseif ( ! $allow_anon ) {
  3614 				return $this->error;
  3804 				return $this->error;
  3615 			}
  3805 			}
  3616 		} else {
  3806 		} else {
  3617 			$logged_in = true;
  3807 			$logged_in = true;
  3618 		}
  3808 		}
  3619 
  3809 
  3620 		if ( is_numeric($post) )
  3810 		if ( is_numeric( $post ) ) {
  3621 			$post_id = absint($post);
  3811 			$post_id = absint( $post );
  3622 		else
  3812 		} else {
  3623 			$post_id = url_to_postid($post);
  3813 			$post_id = url_to_postid( $post );
       
  3814 		}
  3624 
  3815 
  3625 		if ( ! $post_id ) {
  3816 		if ( ! $post_id ) {
  3626 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  3817 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  3627 		}
  3818 		}
  3628 
  3819 
  3643 			'comment_content' => $content_struct['content'],
  3834 			'comment_content' => $content_struct['content'],
  3644 		);
  3835 		);
  3645 
  3836 
  3646 		if ( $logged_in ) {
  3837 		if ( $logged_in ) {
  3647 			$display_name = $user->display_name;
  3838 			$display_name = $user->display_name;
  3648 			$user_email = $user->user_email;
  3839 			$user_email   = $user->user_email;
  3649 			$user_url = $user->user_url;
  3840 			$user_url     = $user->user_url;
  3650 
  3841 
  3651 			$comment['comment_author'] = $this->escape( $display_name );
  3842 			$comment['comment_author']       = $this->escape( $display_name );
  3652 			$comment['comment_author_email'] = $this->escape( $user_email );
  3843 			$comment['comment_author_email'] = $this->escape( $user_email );
  3653 			$comment['comment_author_url'] = $this->escape( $user_url );
  3844 			$comment['comment_author_url']   = $this->escape( $user_url );
  3654 			$comment['user_ID'] = $user->ID;
  3845 			$comment['user_ID']              = $user->ID;
  3655 		} else {
  3846 		} else {
  3656 			$comment['comment_author'] = '';
  3847 			$comment['comment_author'] = '';
  3657 			if ( isset($content_struct['author']) )
  3848 			if ( isset( $content_struct['author'] ) ) {
  3658 				$comment['comment_author'] = $content_struct['author'];
  3849 				$comment['comment_author'] = $content_struct['author'];
       
  3850 			}
  3659 
  3851 
  3660 			$comment['comment_author_email'] = '';
  3852 			$comment['comment_author_email'] = '';
  3661 			if ( isset($content_struct['author_email']) )
  3853 			if ( isset( $content_struct['author_email'] ) ) {
  3662 				$comment['comment_author_email'] = $content_struct['author_email'];
  3854 				$comment['comment_author_email'] = $content_struct['author_email'];
       
  3855 			}
  3663 
  3856 
  3664 			$comment['comment_author_url'] = '';
  3857 			$comment['comment_author_url'] = '';
  3665 			if ( isset($content_struct['author_url']) )
  3858 			if ( isset( $content_struct['author_url'] ) ) {
  3666 				$comment['comment_author_url'] = $content_struct['author_url'];
  3859 				$comment['comment_author_url'] = $content_struct['author_url'];
       
  3860 			}
  3667 
  3861 
  3668 			$comment['user_ID'] = 0;
  3862 			$comment['user_ID'] = 0;
  3669 
  3863 
  3670 			if ( get_option('require_name_email') ) {
  3864 			if ( get_option( 'require_name_email' ) ) {
  3671 				if ( 6 > strlen($comment['comment_author_email']) || '' == $comment['comment_author'] )
  3865 				if ( 6 > strlen( $comment['comment_author_email'] ) || '' == $comment['comment_author'] ) {
  3672 					return new IXR_Error( 403, __( 'Comment author name and email are required.' ) );
  3866 					return new IXR_Error( 403, __( 'Comment author name and email are required.' ) );
  3673 				elseif ( !is_email($comment['comment_author_email']) )
  3867 				} elseif ( ! is_email( $comment['comment_author_email'] ) ) {
  3674 					return new IXR_Error( 403, __( 'A valid email address is required.' ) );
  3868 					return new IXR_Error( 403, __( 'A valid email address is required.' ) );
  3675 			}
  3869 				}
  3676 		}
  3870 			}
  3677 
  3871 		}
  3678 		$comment['comment_parent'] = isset($content_struct['comment_parent']) ? absint($content_struct['comment_parent']) : 0;
  3872 
       
  3873 		$comment['comment_parent'] = isset( $content_struct['comment_parent'] ) ? absint( $content_struct['comment_parent'] ) : 0;
  3679 
  3874 
  3680 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3875 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3681 		do_action( 'xmlrpc_call', 'wp.newComment' );
  3876 		do_action( 'xmlrpc_call', 'wp.newComment' );
  3682 
  3877 
  3683 		$comment_ID = wp_new_comment( $comment, true );
  3878 		$comment_ID = wp_new_comment( $comment, true );
  3725 		if ( ! $user = $this->login( $username, $password ) ) {
  3920 		if ( ! $user = $this->login( $username, $password ) ) {
  3726 			return $this->error;
  3921 			return $this->error;
  3727 		}
  3922 		}
  3728 
  3923 
  3729 		if ( ! current_user_can( 'publish_posts' ) ) {
  3924 		if ( ! current_user_can( 'publish_posts' ) ) {
  3730 			return new IXR_Error( 403, __( 'Sorry, you are not allowed access to details about this site.' ) );
  3925 			return new IXR_Error( 403, __( 'Sorry, you are not allowed to access details about this site.' ) );
  3731 		}
  3926 		}
  3732 
  3927 
  3733 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3928 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3734 		do_action( 'xmlrpc_call', 'wp.getCommentStatusList' );
  3929 		do_action( 'xmlrpc_call', 'wp.getCommentStatusList' );
  3735 
  3930 
  3752 	 * @return array|IXR_Error
  3947 	 * @return array|IXR_Error
  3753 	 */
  3948 	 */
  3754 	public function wp_getCommentCount( $args ) {
  3949 	public function wp_getCommentCount( $args ) {
  3755 		$this->escape( $args );
  3950 		$this->escape( $args );
  3756 
  3951 
  3757 		$username	= $args[1];
  3952 		$username = $args[1];
  3758 		$password	= $args[2];
  3953 		$password = $args[2];
  3759 		$post_id	= (int) $args[3];
  3954 		$post_id  = (int) $args[3];
  3760 
  3955 
  3761 		if ( ! $user = $this->login( $username, $password ) ) {
  3956 		if ( ! $user = $this->login( $username, $password ) ) {
  3762 			return $this->error;
  3957 			return $this->error;
  3763 		}
  3958 		}
  3764 
  3959 
  3766 		if ( empty( $post['ID'] ) ) {
  3961 		if ( empty( $post['ID'] ) ) {
  3767 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  3962 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  3768 		}
  3963 		}
  3769 
  3964 
  3770 		if ( ! current_user_can( 'edit_post', $post_id ) ) {
  3965 		if ( ! current_user_can( 'edit_post', $post_id ) ) {
  3771 			return new IXR_Error( 403, __( 'Sorry, you are not allowed access to details of this post.' ) );
  3966 			return new IXR_Error( 403, __( 'Sorry, you are not allowed to access details of this post.' ) );
  3772 		}
  3967 		}
  3773 
  3968 
  3774 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3969 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3775 		do_action( 'xmlrpc_call', 'wp.getCommentCount' );
  3970 		do_action( 'xmlrpc_call', 'wp.getCommentCount' );
  3776 
  3971 
  3777 		$count = wp_count_comments( $post_id );
  3972 		$count = wp_count_comments( $post_id );
  3778 
  3973 
  3779 		return array(
  3974 		return array(
  3780 			'approved' => $count->approved,
  3975 			'approved'            => $count->approved,
  3781 			'awaiting_moderation' => $count->moderated,
  3976 			'awaiting_moderation' => $count->moderated,
  3782 			'spam' => $count->spam,
  3977 			'spam'                => $count->spam,
  3783 			'total_comments' => $count->total_comments
  3978 			'total_comments'      => $count->total_comments,
  3784 		);
  3979 		);
  3785 	}
  3980 	}
  3786 
  3981 
  3787 	/**
  3982 	/**
  3788 	 * Retrieve post statuses.
  3983 	 * Retrieve post statuses.
  3802 		$this->escape( $args );
  3997 		$this->escape( $args );
  3803 
  3998 
  3804 		$username = $args[1];
  3999 		$username = $args[1];
  3805 		$password = $args[2];
  4000 		$password = $args[2];
  3806 
  4001 
  3807 		if ( !$user = $this->login($username, $password) )
  4002 		if ( ! $user = $this->login( $username, $password ) ) {
  3808 			return $this->error;
  4003 			return $this->error;
  3809 
  4004 		}
  3810 		if ( !current_user_can( 'edit_posts' ) )
  4005 
  3811 			return new IXR_Error( 403, __( 'Sorry, you are not allowed access to details about this site.' ) );
  4006 		if ( ! current_user_can( 'edit_posts' ) ) {
       
  4007 			return new IXR_Error( 403, __( 'Sorry, you are not allowed to access details about this site.' ) );
       
  4008 		}
  3812 
  4009 
  3813 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4010 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3814 		do_action( 'xmlrpc_call', 'wp.getPostStatusList' );
  4011 		do_action( 'xmlrpc_call', 'wp.getPostStatusList' );
  3815 
  4012 
  3816 		return get_post_statuses();
  4013 		return get_post_statuses();
  3834 		$this->escape( $args );
  4031 		$this->escape( $args );
  3835 
  4032 
  3836 		$username = $args[1];
  4033 		$username = $args[1];
  3837 		$password = $args[2];
  4034 		$password = $args[2];
  3838 
  4035 
  3839 		if ( !$user = $this->login($username, $password) )
  4036 		if ( ! $user = $this->login( $username, $password ) ) {
  3840 			return $this->error;
  4037 			return $this->error;
  3841 
  4038 		}
  3842 		if ( !current_user_can( 'edit_pages' ) )
  4039 
  3843 			return new IXR_Error( 403, __( 'Sorry, you are not allowed access to details about this site.' ) );
  4040 		if ( ! current_user_can( 'edit_pages' ) ) {
       
  4041 			return new IXR_Error( 403, __( 'Sorry, you are not allowed to access details about this site.' ) );
       
  4042 		}
  3844 
  4043 
  3845 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4044 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3846 		do_action( 'xmlrpc_call', 'wp.getPageStatusList' );
  4045 		do_action( 'xmlrpc_call', 'wp.getPageStatusList' );
  3847 
  4046 
  3848 		return get_page_statuses();
  4047 		return get_page_statuses();
  3866 		$this->escape( $args );
  4065 		$this->escape( $args );
  3867 
  4066 
  3868 		$username = $args[1];
  4067 		$username = $args[1];
  3869 		$password = $args[2];
  4068 		$password = $args[2];
  3870 
  4069 
  3871 		if ( !$user = $this->login($username, $password) )
  4070 		if ( ! $user = $this->login( $username, $password ) ) {
  3872 			return $this->error;
  4071 			return $this->error;
  3873 
  4072 		}
  3874 		if ( !current_user_can( 'edit_pages' ) )
  4073 
  3875 			return new IXR_Error( 403, __( 'Sorry, you are not allowed access to details about this site.' ) );
  4074 		if ( ! current_user_can( 'edit_pages' ) ) {
  3876 
  4075 			return new IXR_Error( 403, __( 'Sorry, you are not allowed to access details about this site.' ) );
  3877 		$templates = get_page_templates();
  4076 		}
       
  4077 
       
  4078 		$templates            = get_page_templates();
  3878 		$templates['Default'] = 'default';
  4079 		$templates['Default'] = 'default';
  3879 
  4080 
  3880 		return $templates;
  4081 		return $templates;
  3881 	}
  4082 	}
  3882 
  4083 
  3896 	 * @return array|IXR_Error
  4097 	 * @return array|IXR_Error
  3897 	 */
  4098 	 */
  3898 	public function wp_getOptions( $args ) {
  4099 	public function wp_getOptions( $args ) {
  3899 		$this->escape( $args );
  4100 		$this->escape( $args );
  3900 
  4101 
  3901 		$username	= $args[1];
  4102 		$username = $args[1];
  3902 		$password	= $args[2];
  4103 		$password = $args[2];
  3903 		$options	= isset( $args[3] ) ? (array) $args[3] : array();
  4104 		$options  = isset( $args[3] ) ? (array) $args[3] : array();
  3904 
  4105 
  3905 		if ( !$user = $this->login($username, $password) )
  4106 		if ( ! $user = $this->login( $username, $password ) ) {
  3906 			return $this->error;
  4107 			return $this->error;
       
  4108 		}
  3907 
  4109 
  3908 		// If no specific options where asked for, return all of them
  4110 		// If no specific options where asked for, return all of them
  3909 		if ( count( $options ) == 0 )
  4111 		if ( count( $options ) == 0 ) {
  3910 			$options = array_keys($this->blog_options);
  4112 			$options = array_keys( $this->blog_options );
  3911 
  4113 		}
  3912 		return $this->_getOptions($options);
  4114 
       
  4115 		return $this->_getOptions( $options );
  3913 	}
  4116 	}
  3914 
  4117 
  3915 	/**
  4118 	/**
  3916 	 * Retrieve blog options value from list.
  4119 	 * Retrieve blog options value from list.
  3917 	 *
  4120 	 *
  3918 	 * @since 2.6.0
  4121 	 * @since 2.6.0
  3919 	 *
  4122 	 *
  3920 	 * @param array $options Options to retrieve.
  4123 	 * @param array $options Options to retrieve.
  3921 	 * @return array
  4124 	 * @return array
  3922 	 */
  4125 	 */
  3923 	public function _getOptions($options) {
  4126 	public function _getOptions( $options ) {
  3924 		$data = array();
  4127 		$data       = array();
  3925 		$can_manage = current_user_can( 'manage_options' );
  4128 		$can_manage = current_user_can( 'manage_options' );
  3926 		foreach ( $options as $option ) {
  4129 		foreach ( $options as $option ) {
  3927 			if ( array_key_exists( $option, $this->blog_options ) ) {
  4130 			if ( array_key_exists( $option, $this->blog_options ) ) {
  3928 				$data[$option] = $this->blog_options[$option];
  4131 				$data[ $option ] = $this->blog_options[ $option ];
  3929 				//Is the value static or dynamic?
  4132 				//Is the value static or dynamic?
  3930 				if ( isset( $data[$option]['option'] ) ) {
  4133 				if ( isset( $data[ $option ]['option'] ) ) {
  3931 					$data[$option]['value'] = get_option( $data[$option]['option'] );
  4134 					$data[ $option ]['value'] = get_option( $data[ $option ]['option'] );
  3932 					unset($data[$option]['option']);
  4135 					unset( $data[ $option ]['option'] );
  3933 				}
  4136 				}
  3934 
  4137 
  3935 				if ( ! $can_manage )
  4138 				if ( ! $can_manage ) {
  3936 					$data[$option]['readonly'] = true;
  4139 					$data[ $option ]['readonly'] = true;
       
  4140 				}
  3937 			}
  4141 			}
  3938 		}
  4142 		}
  3939 
  4143 
  3940 		return $data;
  4144 		return $data;
  3941 	}
  4145 	}
  3956 	 * @return array|IXR_Error
  4160 	 * @return array|IXR_Error
  3957 	 */
  4161 	 */
  3958 	public function wp_setOptions( $args ) {
  4162 	public function wp_setOptions( $args ) {
  3959 		$this->escape( $args );
  4163 		$this->escape( $args );
  3960 
  4164 
  3961 		$username	= $args[1];
  4165 		$username = $args[1];
  3962 		$password	= $args[2];
  4166 		$password = $args[2];
  3963 		$options	= (array) $args[3];
  4167 		$options  = (array) $args[3];
  3964 
  4168 
  3965 		if ( !$user = $this->login($username, $password) )
  4169 		if ( ! $user = $this->login( $username, $password ) ) {
  3966 			return $this->error;
  4170 			return $this->error;
  3967 
  4171 		}
  3968 		if ( !current_user_can( 'manage_options' ) )
  4172 
       
  4173 		if ( ! current_user_can( 'manage_options' ) ) {
  3969 			return new IXR_Error( 403, __( 'Sorry, you are not allowed to update options.' ) );
  4174 			return new IXR_Error( 403, __( 'Sorry, you are not allowed to update options.' ) );
       
  4175 		}
  3970 
  4176 
  3971 		$option_names = array();
  4177 		$option_names = array();
  3972 		foreach ( $options as $o_name => $o_value ) {
  4178 		foreach ( $options as $o_name => $o_value ) {
  3973 			$option_names[] = $o_name;
  4179 			$option_names[] = $o_name;
  3974 			if ( !array_key_exists( $o_name, $this->blog_options ) )
  4180 			if ( ! array_key_exists( $o_name, $this->blog_options ) ) {
  3975 				continue;
  4181 				continue;
  3976 
  4182 			}
  3977 			if ( $this->blog_options[$o_name]['readonly'] == true )
  4183 
       
  4184 			if ( $this->blog_options[ $o_name ]['readonly'] == true ) {
  3978 				continue;
  4185 				continue;
  3979 
  4186 			}
  3980 			update_option( $this->blog_options[$o_name]['option'], wp_unslash( $o_value ) );
  4187 
       
  4188 			update_option( $this->blog_options[ $o_name ]['option'], wp_unslash( $o_value ) );
  3981 		}
  4189 		}
  3982 
  4190 
  3983 		//Now return the updated values
  4191 		//Now return the updated values
  3984 		return $this->_getOptions($option_names);
  4192 		return $this->_getOptions( $option_names );
  3985 	}
  4193 	}
  3986 
  4194 
  3987 	/**
  4195 	/**
  3988 	 * Retrieve a media item by ID
  4196 	 * Retrieve a media item by ID
  3989 	 *
  4197 	 *
  4008 	 *  - 'metadata'
  4216 	 *  - 'metadata'
  4009 	 */
  4217 	 */
  4010 	public function wp_getMediaItem( $args ) {
  4218 	public function wp_getMediaItem( $args ) {
  4011 		$this->escape( $args );
  4219 		$this->escape( $args );
  4012 
  4220 
  4013 		$username		= $args[1];
  4221 		$username      = $args[1];
  4014 		$password		= $args[2];
  4222 		$password      = $args[2];
  4015 		$attachment_id	= (int) $args[3];
  4223 		$attachment_id = (int) $args[3];
  4016 
  4224 
  4017 		if ( !$user = $this->login($username, $password) )
  4225 		if ( ! $user = $this->login( $username, $password ) ) {
  4018 			return $this->error;
  4226 			return $this->error;
  4019 
  4227 		}
  4020 		if ( !current_user_can( 'upload_files' ) )
  4228 
       
  4229 		if ( ! current_user_can( 'upload_files' ) ) {
  4021 			return new IXR_Error( 403, __( 'Sorry, you are not allowed to upload files.' ) );
  4230 			return new IXR_Error( 403, __( 'Sorry, you are not allowed to upload files.' ) );
       
  4231 		}
  4022 
  4232 
  4023 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4233 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4024 		do_action( 'xmlrpc_call', 'wp.getMediaItem' );
  4234 		do_action( 'xmlrpc_call', 'wp.getMediaItem' );
  4025 
  4235 
  4026 		if ( ! $attachment = get_post($attachment_id) )
  4236 		if ( ! $attachment = get_post( $attachment_id ) ) {
  4027 			return new IXR_Error( 404, __( 'Invalid attachment ID.' ) );
  4237 			return new IXR_Error( 404, __( 'Invalid attachment ID.' ) );
       
  4238 		}
  4028 
  4239 
  4029 		return $this->_prepare_media_item( $attachment );
  4240 		return $this->_prepare_media_item( $attachment );
  4030 	}
  4241 	}
  4031 
  4242 
  4032 	/**
  4243 	/**
  4053 	 *     @type string $password
  4264 	 *     @type string $password
  4054 	 *     @type array  $struct
  4265 	 *     @type array  $struct
  4055 	 * }
  4266 	 * }
  4056 	 * @return array|IXR_Error Contains a collection of media items. See wp_xmlrpc_server::wp_getMediaItem() for a description of each item contents
  4267 	 * @return array|IXR_Error Contains a collection of media items. See wp_xmlrpc_server::wp_getMediaItem() for a description of each item contents
  4057 	 */
  4268 	 */
  4058 	public function wp_getMediaLibrary($args) {
  4269 	public function wp_getMediaLibrary( $args ) {
  4059 		$this->escape($args);
  4270 		$this->escape( $args );
  4060 
  4271 
  4061 		$username	= $args[1];
  4272 		$username = $args[1];
  4062 		$password	= $args[2];
  4273 		$password = $args[2];
  4063 		$struct		= isset( $args[3] ) ? $args[3] : array() ;
  4274 		$struct   = isset( $args[3] ) ? $args[3] : array();
  4064 
  4275 
  4065 		if ( !$user = $this->login($username, $password) )
  4276 		if ( ! $user = $this->login( $username, $password ) ) {
  4066 			return $this->error;
  4277 			return $this->error;
  4067 
  4278 		}
  4068 		if ( !current_user_can( 'upload_files' ) )
  4279 
       
  4280 		if ( ! current_user_can( 'upload_files' ) ) {
  4069 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to upload files.' ) );
  4281 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to upload files.' ) );
       
  4282 		}
  4070 
  4283 
  4071 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4284 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4072 		do_action( 'xmlrpc_call', 'wp.getMediaLibrary' );
  4285 		do_action( 'xmlrpc_call', 'wp.getMediaLibrary' );
  4073 
  4286 
  4074 		$parent_id = ( isset($struct['parent_id']) ) ? absint($struct['parent_id']) : '' ;
  4287 		$parent_id = ( isset( $struct['parent_id'] ) ) ? absint( $struct['parent_id'] ) : '';
  4075 		$mime_type = ( isset($struct['mime_type']) ) ? $struct['mime_type'] : '' ;
  4288 		$mime_type = ( isset( $struct['mime_type'] ) ) ? $struct['mime_type'] : '';
  4076 		$offset = ( isset($struct['offset']) ) ? absint($struct['offset']) : 0 ;
  4289 		$offset    = ( isset( $struct['offset'] ) ) ? absint( $struct['offset'] ) : 0;
  4077 		$number = ( isset($struct['number']) ) ? absint($struct['number']) : -1 ;
  4290 		$number    = ( isset( $struct['number'] ) ) ? absint( $struct['number'] ) : -1;
  4078 
  4291 
  4079 		$attachments = get_posts( array('post_type' => 'attachment', 'post_parent' => $parent_id, 'offset' => $offset, 'numberposts' => $number, 'post_mime_type' => $mime_type ) );
  4292 		$attachments = get_posts(
       
  4293 			array(
       
  4294 				'post_type'      => 'attachment',
       
  4295 				'post_parent'    => $parent_id,
       
  4296 				'offset'         => $offset,
       
  4297 				'numberposts'    => $number,
       
  4298 				'post_mime_type' => $mime_type,
       
  4299 			)
       
  4300 		);
  4080 
  4301 
  4081 		$attachments_struct = array();
  4302 		$attachments_struct = array();
  4082 
  4303 
  4083 		foreach ($attachments as $attachment )
  4304 		foreach ( $attachments as $attachment ) {
  4084 			$attachments_struct[] = $this->_prepare_media_item( $attachment );
  4305 			$attachments_struct[] = $this->_prepare_media_item( $attachment );
       
  4306 		}
  4085 
  4307 
  4086 		return $attachments_struct;
  4308 		return $attachments_struct;
  4087 	}
  4309 	}
  4088 
  4310 
  4089 	/**
  4311 	/**
  4104 		$this->escape( $args );
  4326 		$this->escape( $args );
  4105 
  4327 
  4106 		$username = $args[1];
  4328 		$username = $args[1];
  4107 		$password = $args[2];
  4329 		$password = $args[2];
  4108 
  4330 
  4109 		if ( !$user = $this->login( $username, $password ) )
  4331 		if ( ! $user = $this->login( $username, $password ) ) {
  4110 			return $this->error;
  4332 			return $this->error;
  4111 
  4333 		}
  4112 		if ( !current_user_can( 'edit_posts' ) )
  4334 
  4113 			return new IXR_Error( 403, __( 'Sorry, you are not allowed access to details about this site.' ) );
  4335 		if ( ! current_user_can( 'edit_posts' ) ) {
       
  4336 			return new IXR_Error( 403, __( 'Sorry, you are not allowed to access details about this site.' ) );
       
  4337 		}
  4114 
  4338 
  4115 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4339 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4116 		do_action( 'xmlrpc_call', 'wp.getPostFormats' );
  4340 		do_action( 'xmlrpc_call', 'wp.getPostFormats' );
  4117 
  4341 
  4118 		$formats = get_post_format_strings();
  4342 		$formats = get_post_format_strings();
  4121 		if ( isset( $args[3] ) && is_array( $args[3] ) ) {
  4345 		if ( isset( $args[3] ) && is_array( $args[3] ) ) {
  4122 			if ( $args[3]['show-supported'] ) {
  4346 			if ( $args[3]['show-supported'] ) {
  4123 				if ( current_theme_supports( 'post-formats' ) ) {
  4347 				if ( current_theme_supports( 'post-formats' ) ) {
  4124 					$supported = get_theme_support( 'post-formats' );
  4348 					$supported = get_theme_support( 'post-formats' );
  4125 
  4349 
  4126 					$data = array();
  4350 					$data              = array();
  4127 					$data['all'] = $formats;
  4351 					$data['all']       = $formats;
  4128 					$data['supported'] = $supported[0];
  4352 					$data['supported'] = $supported[0];
  4129 
  4353 
  4130 					$formats = $data;
  4354 					$formats = $data;
  4131 				}
  4355 				}
  4132 			}
  4356 			}
  4161 	 *  - 'menu_position'
  4385 	 *  - 'menu_position'
  4162 	 *  - 'taxonomies'
  4386 	 *  - 'taxonomies'
  4163 	 *  - 'supports'
  4387 	 *  - 'supports'
  4164 	 */
  4388 	 */
  4165 	public function wp_getPostType( $args ) {
  4389 	public function wp_getPostType( $args ) {
  4166 		if ( ! $this->minimum_args( $args, 4 ) )
  4390 		if ( ! $this->minimum_args( $args, 4 ) ) {
  4167 			return $this->error;
  4391 			return $this->error;
       
  4392 		}
  4168 
  4393 
  4169 		$this->escape( $args );
  4394 		$this->escape( $args );
  4170 
  4395 
  4171 		$username       = $args[1];
  4396 		$username       = $args[1];
  4172 		$password       = $args[2];
  4397 		$password       = $args[2];
  4184 			 * @param string $method The method name.
  4409 			 * @param string $method The method name.
  4185 			 */
  4410 			 */
  4186 			$fields = apply_filters( 'xmlrpc_default_posttype_fields', array( 'labels', 'cap', 'taxonomies' ), 'wp.getPostType' );
  4411 			$fields = apply_filters( 'xmlrpc_default_posttype_fields', array( 'labels', 'cap', 'taxonomies' ), 'wp.getPostType' );
  4187 		}
  4412 		}
  4188 
  4413 
  4189 		if ( !$user = $this->login( $username, $password ) )
  4414 		if ( ! $user = $this->login( $username, $password ) ) {
  4190 			return $this->error;
  4415 			return $this->error;
       
  4416 		}
  4191 
  4417 
  4192 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4418 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4193 		do_action( 'xmlrpc_call', 'wp.getPostType' );
  4419 		do_action( 'xmlrpc_call', 'wp.getPostType' );
  4194 
  4420 
  4195 		if ( ! post_type_exists( $post_type_name ) )
  4421 		if ( ! post_type_exists( $post_type_name ) ) {
  4196 			return new IXR_Error( 403, __( 'Invalid post type.' ) );
  4422 			return new IXR_Error( 403, __( 'Invalid post type.' ) );
       
  4423 		}
  4197 
  4424 
  4198 		$post_type = get_post_type_object( $post_type_name );
  4425 		$post_type = get_post_type_object( $post_type_name );
  4199 
  4426 
  4200 		if ( ! current_user_can( $post_type->cap->edit_posts ) )
  4427 		if ( ! current_user_can( $post_type->cap->edit_posts ) ) {
  4201 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit posts in this post type.' ) );
  4428 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit posts in this post type.' ) );
       
  4429 		}
  4202 
  4430 
  4203 		return $this->_prepare_post_type( $post_type, $fields );
  4431 		return $this->_prepare_post_type( $post_type, $fields );
  4204 	}
  4432 	}
  4205 
  4433 
  4206 	/**
  4434 	/**
  4220 	 *     @type array  $fields (optional)
  4448 	 *     @type array  $fields (optional)
  4221 	 * }
  4449 	 * }
  4222 	 * @return array|IXR_Error
  4450 	 * @return array|IXR_Error
  4223 	 */
  4451 	 */
  4224 	public function wp_getPostTypes( $args ) {
  4452 	public function wp_getPostTypes( $args ) {
  4225 		if ( ! $this->minimum_args( $args, 3 ) )
  4453 		if ( ! $this->minimum_args( $args, 3 ) ) {
  4226 			return $this->error;
  4454 			return $this->error;
       
  4455 		}
  4227 
  4456 
  4228 		$this->escape( $args );
  4457 		$this->escape( $args );
  4229 
  4458 
  4230 		$username = $args[1];
  4459 		$username = $args[1];
  4231 		$password = $args[2];
  4460 		$password = $args[2];
  4236 		} else {
  4465 		} else {
  4237 			/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4466 			/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4238 			$fields = apply_filters( 'xmlrpc_default_posttype_fields', array( 'labels', 'cap', 'taxonomies' ), 'wp.getPostTypes' );
  4467 			$fields = apply_filters( 'xmlrpc_default_posttype_fields', array( 'labels', 'cap', 'taxonomies' ), 'wp.getPostTypes' );
  4239 		}
  4468 		}
  4240 
  4469 
  4241 		if ( ! $user = $this->login( $username, $password ) )
  4470 		if ( ! $user = $this->login( $username, $password ) ) {
  4242 			return $this->error;
  4471 			return $this->error;
       
  4472 		}
  4243 
  4473 
  4244 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4474 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4245 		do_action( 'xmlrpc_call', 'wp.getPostTypes' );
  4475 		do_action( 'xmlrpc_call', 'wp.getPostTypes' );
  4246 
  4476 
  4247 		$post_types = get_post_types( $filter, 'objects' );
  4477 		$post_types = get_post_types( $filter, 'objects' );
  4248 
  4478 
  4249 		$struct = array();
  4479 		$struct = array();
  4250 
  4480 
  4251 		foreach ( $post_types as $post_type ) {
  4481 		foreach ( $post_types as $post_type ) {
  4252 			if ( ! current_user_can( $post_type->cap->edit_posts ) )
  4482 			if ( ! current_user_can( $post_type->cap->edit_posts ) ) {
  4253 				continue;
  4483 				continue;
  4254 
  4484 			}
  4255 			$struct[$post_type->name] = $this->_prepare_post_type( $post_type, $fields );
  4485 
       
  4486 			$struct[ $post_type->name ] = $this->_prepare_post_type( $post_type, $fields );
  4256 		}
  4487 		}
  4257 
  4488 
  4258 		return $struct;
  4489 		return $struct;
  4259 	}
  4490 	}
  4260 
  4491 
  4279 	 *     @type array  $fields (optional)
  4510 	 *     @type array  $fields (optional)
  4280 	 * }
  4511 	 * }
  4281 	 * @return array|IXR_Error contains a collection of posts.
  4512 	 * @return array|IXR_Error contains a collection of posts.
  4282 	 */
  4513 	 */
  4283 	public function wp_getRevisions( $args ) {
  4514 	public function wp_getRevisions( $args ) {
  4284 		if ( ! $this->minimum_args( $args, 4 ) )
  4515 		if ( ! $this->minimum_args( $args, 4 ) ) {
  4285 			return $this->error;
  4516 			return $this->error;
       
  4517 		}
  4286 
  4518 
  4287 		$this->escape( $args );
  4519 		$this->escape( $args );
  4288 
  4520 
  4289 		$username = $args[1];
  4521 		$username = $args[1];
  4290 		$password = $args[2];
  4522 		$password = $args[2];
  4302 			 * @param string $method The method name.
  4534 			 * @param string $method The method name.
  4303 			 */
  4535 			 */
  4304 			$fields = apply_filters( 'xmlrpc_default_revision_fields', array( 'post_date', 'post_date_gmt' ), 'wp.getRevisions' );
  4536 			$fields = apply_filters( 'xmlrpc_default_revision_fields', array( 'post_date', 'post_date_gmt' ), 'wp.getRevisions' );
  4305 		}
  4537 		}
  4306 
  4538 
  4307 		if ( ! $user = $this->login( $username, $password ) )
  4539 		if ( ! $user = $this->login( $username, $password ) ) {
  4308 			return $this->error;
  4540 			return $this->error;
       
  4541 		}
  4309 
  4542 
  4310 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4543 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4311 		do_action( 'xmlrpc_call', 'wp.getRevisions' );
  4544 		do_action( 'xmlrpc_call', 'wp.getRevisions' );
  4312 
  4545 
  4313 		if ( ! $post = get_post( $post_id ) )
  4546 		if ( ! $post = get_post( $post_id ) ) {
  4314 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  4547 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  4315 
  4548 		}
  4316 		if ( ! current_user_can( 'edit_post', $post_id ) )
  4549 
       
  4550 		if ( ! current_user_can( 'edit_post', $post_id ) ) {
  4317 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit posts.' ) );
  4551 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit posts.' ) );
       
  4552 		}
  4318 
  4553 
  4319 		// Check if revisions are enabled.
  4554 		// Check if revisions are enabled.
  4320 		if ( ! wp_revisions_enabled( $post ) )
  4555 		if ( ! wp_revisions_enabled( $post ) ) {
  4321 			return new IXR_Error( 401, __( 'Sorry, revisions are disabled.' ) );
  4556 			return new IXR_Error( 401, __( 'Sorry, revisions are disabled.' ) );
       
  4557 		}
  4322 
  4558 
  4323 		$revisions = wp_get_post_revisions( $post_id );
  4559 		$revisions = wp_get_post_revisions( $post_id );
  4324 
  4560 
  4325 		if ( ! $revisions )
  4561 		if ( ! $revisions ) {
  4326 			return array();
  4562 			return array();
       
  4563 		}
  4327 
  4564 
  4328 		$struct = array();
  4565 		$struct = array();
  4329 
  4566 
  4330 		foreach ( $revisions as $revision ) {
  4567 		foreach ( $revisions as $revision ) {
  4331 			if ( ! current_user_can( 'read_post', $revision->ID ) )
  4568 			if ( ! current_user_can( 'read_post', $revision->ID ) ) {
  4332 				continue;
  4569 				continue;
       
  4570 			}
  4333 
  4571 
  4334 			// Skip autosaves
  4572 			// Skip autosaves
  4335 			if ( wp_is_post_autosave( $revision ) )
  4573 			if ( wp_is_post_autosave( $revision ) ) {
  4336 				continue;
  4574 				continue;
       
  4575 			}
  4337 
  4576 
  4338 			$struct[] = $this->_prepare_post( get_object_vars( $revision ), $fields );
  4577 			$struct[] = $this->_prepare_post( get_object_vars( $revision ), $fields );
  4339 		}
  4578 		}
  4340 
  4579 
  4341 		return $struct;
  4580 		return $struct;
  4357 	 *     @type int    $revision_id
  4596 	 *     @type int    $revision_id
  4358 	 * }
  4597 	 * }
  4359 	 * @return bool|IXR_Error false if there was an error restoring, true if success.
  4598 	 * @return bool|IXR_Error false if there was an error restoring, true if success.
  4360 	 */
  4599 	 */
  4361 	public function wp_restoreRevision( $args ) {
  4600 	public function wp_restoreRevision( $args ) {
  4362 		if ( ! $this->minimum_args( $args, 3 ) )
  4601 		if ( ! $this->minimum_args( $args, 3 ) ) {
  4363 			return $this->error;
  4602 			return $this->error;
       
  4603 		}
  4364 
  4604 
  4365 		$this->escape( $args );
  4605 		$this->escape( $args );
  4366 
  4606 
  4367 		$username    = $args[1];
  4607 		$username    = $args[1];
  4368 		$password    = $args[2];
  4608 		$password    = $args[2];
  4369 		$revision_id = (int) $args[3];
  4609 		$revision_id = (int) $args[3];
  4370 
  4610 
  4371 		if ( ! $user = $this->login( $username, $password ) )
  4611 		if ( ! $user = $this->login( $username, $password ) ) {
  4372 			return $this->error;
  4612 			return $this->error;
       
  4613 		}
  4373 
  4614 
  4374 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4615 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4375 		do_action( 'xmlrpc_call', 'wp.restoreRevision' );
  4616 		do_action( 'xmlrpc_call', 'wp.restoreRevision' );
  4376 
  4617 
  4377 		if ( ! $revision = wp_get_post_revision( $revision_id ) )
  4618 		if ( ! $revision = wp_get_post_revision( $revision_id ) ) {
  4378 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  4619 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  4379 
  4620 		}
  4380 		if ( wp_is_post_autosave( $revision ) )
  4621 
       
  4622 		if ( wp_is_post_autosave( $revision ) ) {
  4381 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  4623 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  4382 
  4624 		}
  4383 		if ( ! $post = get_post( $revision->post_parent ) )
  4625 
       
  4626 		if ( ! $post = get_post( $revision->post_parent ) ) {
  4384 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  4627 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  4385 
  4628 		}
  4386 		if ( ! current_user_can( 'edit_post', $revision->post_parent ) )
  4629 
       
  4630 		if ( ! current_user_can( 'edit_post', $revision->post_parent ) ) {
  4387 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit this post.' ) );
  4631 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit this post.' ) );
       
  4632 		}
  4388 
  4633 
  4389 		// Check if revisions are disabled.
  4634 		// Check if revisions are disabled.
  4390 		if ( ! wp_revisions_enabled( $post ) )
  4635 		if ( ! wp_revisions_enabled( $post ) ) {
  4391 			return new IXR_Error( 401, __( 'Sorry, revisions are disabled.' ) );
  4636 			return new IXR_Error( 401, __( 'Sorry, revisions are disabled.' ) );
       
  4637 		}
  4392 
  4638 
  4393 		$post = wp_restore_post_revision( $revision_id );
  4639 		$post = wp_restore_post_revision( $revision_id );
  4394 
  4640 
  4395 		return (bool) $post;
  4641 		return (bool) $post;
  4396 	}
  4642 	}
  4413 	 *     @type string $username
  4659 	 *     @type string $username
  4414 	 *     @type string $password
  4660 	 *     @type string $password
  4415 	 * }
  4661 	 * }
  4416 	 * @return array|IXR_Error
  4662 	 * @return array|IXR_Error
  4417 	 */
  4663 	 */
  4418 	public function blogger_getUsersBlogs($args) {
  4664 	public function blogger_getUsersBlogs( $args ) {
  4419 		if ( ! $this->minimum_args( $args, 3 ) ) {
  4665 		if ( ! $this->minimum_args( $args, 3 ) ) {
  4420 			return $this->error;
  4666 			return $this->error;
  4421 		}
  4667 		}
  4422 
  4668 
  4423 		if ( is_multisite() ) {
  4669 		if ( is_multisite() ) {
  4424 			return $this->_multisite_getUsersBlogs($args);
  4670 			return $this->_multisite_getUsersBlogs( $args );
  4425 		}
  4671 		}
  4426 
  4672 
  4427 		$this->escape($args);
  4673 		$this->escape( $args );
  4428 
  4674 
  4429 		$username = $args[1];
  4675 		$username = $args[1];
  4430 		$password = $args[2];
  4676 		$password = $args[2];
  4431 
  4677 
  4432 		if ( !$user = $this->login($username, $password) )
  4678 		if ( ! $user = $this->login( $username, $password ) ) {
  4433 			return $this->error;
  4679 			return $this->error;
       
  4680 		}
  4434 
  4681 
  4435 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4682 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4436 		do_action( 'xmlrpc_call', 'blogger.getUsersBlogs' );
  4683 		do_action( 'xmlrpc_call', 'blogger.getUsersBlogs' );
  4437 
  4684 
  4438 		$is_admin = current_user_can('manage_options');
  4685 		$is_admin = current_user_can( 'manage_options' );
  4439 
  4686 
  4440 		$struct = array(
  4687 		$struct = array(
  4441 			'isAdmin'  => $is_admin,
  4688 			'isAdmin'  => $is_admin,
  4442 			'url'      => get_option('home') . '/',
  4689 			'url'      => get_option( 'home' ) . '/',
  4443 			'blogid'   => '1',
  4690 			'blogid'   => '1',
  4444 			'blogName' => get_option('blogname'),
  4691 			'blogName' => get_option( 'blogname' ),
  4445 			'xmlrpc'   => site_url( 'xmlrpc.php', 'rpc' ),
  4692 			'xmlrpc'   => site_url( 'xmlrpc.php', 'rpc' ),
  4446 		);
  4693 		);
  4447 
  4694 
  4448 		return array($struct);
  4695 		return array( $struct );
  4449 	}
  4696 	}
  4450 
  4697 
  4451 	/**
  4698 	/**
  4452 	 * Private function for retrieving a users blogs for multisite setups
  4699 	 * Private function for retrieving a users blogs for multisite setups
  4453 	 *
  4700 	 *
  4463 	 */
  4710 	 */
  4464 	protected function _multisite_getUsersBlogs( $args ) {
  4711 	protected function _multisite_getUsersBlogs( $args ) {
  4465 		$current_blog = get_site();
  4712 		$current_blog = get_site();
  4466 
  4713 
  4467 		$domain = $current_blog->domain;
  4714 		$domain = $current_blog->domain;
  4468 		$path = $current_blog->path . 'xmlrpc.php';
  4715 		$path   = $current_blog->path . 'xmlrpc.php';
  4469 
  4716 
  4470 		$rpc = new IXR_Client( set_url_scheme( "http://{$domain}{$path}" ) );
  4717 		$rpc = new IXR_Client( set_url_scheme( "http://{$domain}{$path}" ) );
  4471 		$rpc->query('wp.getUsersBlogs', $args[1], $args[2]);
  4718 		$rpc->query( 'wp.getUsersBlogs', $args[1], $args[2] );
  4472 		$blogs = $rpc->getResponse();
  4719 		$blogs = $rpc->getResponse();
  4473 
  4720 
  4474 		if ( isset($blogs['faultCode']) )
  4721 		if ( isset( $blogs['faultCode'] ) ) {
  4475 			return new IXR_Error($blogs['faultCode'], $blogs['faultString']);
  4722 			return new IXR_Error( $blogs['faultCode'], $blogs['faultString'] );
       
  4723 		}
  4476 
  4724 
  4477 		if ( $_SERVER['HTTP_HOST'] == $domain && $_SERVER['REQUEST_URI'] == $path ) {
  4725 		if ( $_SERVER['HTTP_HOST'] == $domain && $_SERVER['REQUEST_URI'] == $path ) {
  4478 			return $blogs;
  4726 			return $blogs;
  4479 		} else {
  4727 		} else {
  4480 			foreach ( (array) $blogs as $blog ) {
  4728 			foreach ( (array) $blogs as $blog ) {
  4481 				if ( strpos($blog['url'], $_SERVER['HTTP_HOST']) )
  4729 				if ( strpos( $blog['url'], $_SERVER['HTTP_HOST'] ) ) {
  4482 					return array($blog);
  4730 					return array( $blog );
       
  4731 				}
  4483 			}
  4732 			}
  4484 			return array();
  4733 			return array();
  4485 		}
  4734 		}
  4486 	}
  4735 	}
  4487 
  4736 
  4505 		$this->escape( $args );
  4754 		$this->escape( $args );
  4506 
  4755 
  4507 		$username = $args[1];
  4756 		$username = $args[1];
  4508 		$password = $args[2];
  4757 		$password = $args[2];
  4509 
  4758 
  4510 		if ( !$user = $this->login($username, $password) )
  4759 		if ( ! $user = $this->login( $username, $password ) ) {
  4511 			return $this->error;
  4760 			return $this->error;
  4512 
  4761 		}
  4513 		if ( !current_user_can( 'edit_posts' ) )
  4762 
       
  4763 		if ( ! current_user_can( 'edit_posts' ) ) {
  4514 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to access user data on this site.' ) );
  4764 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to access user data on this site.' ) );
       
  4765 		}
  4515 
  4766 
  4516 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4767 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4517 		do_action( 'xmlrpc_call', 'blogger.getUserInfo' );
  4768 		do_action( 'xmlrpc_call', 'blogger.getUserInfo' );
  4518 
  4769 
  4519 		$struct = array(
  4770 		$struct = array(
  4520 			'nickname'  => $user->nickname,
  4771 			'nickname'  => $user->nickname,
  4521 			'userid'    => $user->ID,
  4772 			'userid'    => $user->ID,
  4522 			'url'       => $user->user_url,
  4773 			'url'       => $user->user_url,
  4523 			'lastname'  => $user->last_name,
  4774 			'lastname'  => $user->last_name,
  4524 			'firstname' => $user->first_name
  4775 			'firstname' => $user->first_name,
  4525 		);
  4776 		);
  4526 
  4777 
  4527 		return $struct;
  4778 		return $struct;
  4528 	}
  4779 	}
  4529 
  4780 
  4547 
  4798 
  4548 		$post_ID  = (int) $args[1];
  4799 		$post_ID  = (int) $args[1];
  4549 		$username = $args[2];
  4800 		$username = $args[2];
  4550 		$password = $args[3];
  4801 		$password = $args[3];
  4551 
  4802 
  4552 		if ( !$user = $this->login($username, $password) )
  4803 		if ( ! $user = $this->login( $username, $password ) ) {
  4553 			return $this->error;
  4804 			return $this->error;
  4554 
  4805 		}
  4555 		$post_data = get_post($post_ID, ARRAY_A);
  4806 
  4556 		if ( ! $post_data )
  4807 		$post_data = get_post( $post_ID, ARRAY_A );
       
  4808 		if ( ! $post_data ) {
  4557 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  4809 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  4558 
  4810 		}
  4559 		if ( !current_user_can( 'edit_post', $post_ID ) )
  4811 
       
  4812 		if ( ! current_user_can( 'edit_post', $post_ID ) ) {
  4560 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit this post.' ) );
  4813 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit this post.' ) );
       
  4814 		}
  4561 
  4815 
  4562 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4816 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4563 		do_action( 'xmlrpc_call', 'blogger.getPost' );
  4817 		do_action( 'xmlrpc_call', 'blogger.getPost' );
  4564 
  4818 
  4565 		$categories = implode(',', wp_get_post_categories($post_ID));
  4819 		$categories = implode( ',', wp_get_post_categories( $post_ID ) );
  4566 
  4820 
  4567 		$content  = '<title>'.wp_unslash($post_data['post_title']).'</title>';
  4821 		$content  = '<title>' . wp_unslash( $post_data['post_title'] ) . '</title>';
  4568 		$content .= '<category>'.$categories.'</category>';
  4822 		$content .= '<category>' . $categories . '</category>';
  4569 		$content .= wp_unslash($post_data['post_content']);
  4823 		$content .= wp_unslash( $post_data['post_content'] );
  4570 
  4824 
  4571 		$struct = array(
  4825 		$struct = array(
  4572 			'userid'    => $post_data['post_author'],
  4826 			'userid'      => $post_data['post_author'],
  4573 			'dateCreated' => $this->_convert_date( $post_data['post_date'] ),
  4827 			'dateCreated' => $this->_convert_date( $post_data['post_date'] ),
  4574 			'content'     => $content,
  4828 			'content'     => $content,
  4575 			'postid'  => (string) $post_data['ID']
  4829 			'postid'      => (string) $post_data['ID'],
  4576 		);
  4830 		);
  4577 
  4831 
  4578 		return $struct;
  4832 		return $struct;
  4579 	}
  4833 	}
  4580 
  4834 
  4594 	 * }
  4848 	 * }
  4595 	 * @return array|IXR_Error
  4849 	 * @return array|IXR_Error
  4596 	 */
  4850 	 */
  4597 	public function blogger_getRecentPosts( $args ) {
  4851 	public function blogger_getRecentPosts( $args ) {
  4598 
  4852 
  4599 		$this->escape($args);
  4853 		$this->escape( $args );
  4600 
  4854 
  4601 		// $args[0] = appkey - ignored
  4855 		// $args[0] = appkey - ignored
  4602 		$username = $args[2];
  4856 		$username = $args[2];
  4603 		$password = $args[3];
  4857 		$password = $args[3];
  4604 		if ( isset( $args[4] ) )
  4858 		if ( isset( $args[4] ) ) {
  4605 			$query = array( 'numberposts' => absint( $args[4] ) );
  4859 			$query = array( 'numberposts' => absint( $args[4] ) );
  4606 		else
  4860 		} else {
  4607 			$query = array();
  4861 			$query = array();
  4608 
  4862 		}
  4609 		if ( !$user = $this->login($username, $password) )
  4863 
  4610 			return $this->error;
  4864 		if ( ! $user = $this->login( $username, $password ) ) {
  4611 
  4865 			return $this->error;
  4612 		if ( ! current_user_can( 'edit_posts' ) )
  4866 		}
       
  4867 
       
  4868 		if ( ! current_user_can( 'edit_posts' ) ) {
  4613 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit posts.' ) );
  4869 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit posts.' ) );
       
  4870 		}
  4614 
  4871 
  4615 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4872 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4616 		do_action( 'xmlrpc_call', 'blogger.getRecentPosts' );
  4873 		do_action( 'xmlrpc_call', 'blogger.getRecentPosts' );
  4617 
  4874 
  4618 		$posts_list = wp_get_recent_posts( $query );
  4875 		$posts_list = wp_get_recent_posts( $query );
  4619 
  4876 
  4620 		if ( !$posts_list ) {
  4877 		if ( ! $posts_list ) {
  4621 			$this->error = new IXR_Error(500, __('Either there are no posts, or something went wrong.'));
  4878 			$this->error = new IXR_Error( 500, __( 'Either there are no posts, or something went wrong.' ) );
  4622 			return $this->error;
  4879 			return $this->error;
  4623 		}
  4880 		}
  4624 
  4881 
  4625 		$recent_posts = array();
  4882 		$recent_posts = array();
  4626 		foreach ($posts_list as $entry) {
  4883 		foreach ( $posts_list as $entry ) {
  4627 			if ( !current_user_can( 'edit_post', $entry['ID'] ) )
  4884 			if ( ! current_user_can( 'edit_post', $entry['ID'] ) ) {
  4628 				continue;
  4885 				continue;
       
  4886 			}
  4629 
  4887 
  4630 			$post_date  = $this->_convert_date( $entry['post_date'] );
  4888 			$post_date  = $this->_convert_date( $entry['post_date'] );
  4631 			$categories = implode(',', wp_get_post_categories($entry['ID']));
  4889 			$categories = implode( ',', wp_get_post_categories( $entry['ID'] ) );
  4632 
  4890 
  4633 			$content  = '<title>'.wp_unslash($entry['post_title']).'</title>';
  4891 			$content  = '<title>' . wp_unslash( $entry['post_title'] ) . '</title>';
  4634 			$content .= '<category>'.$categories.'</category>';
  4892 			$content .= '<category>' . $categories . '</category>';
  4635 			$content .= wp_unslash($entry['post_content']);
  4893 			$content .= wp_unslash( $entry['post_content'] );
  4636 
  4894 
  4637 			$recent_posts[] = array(
  4895 			$recent_posts[] = array(
  4638 				'userid' => $entry['post_author'],
  4896 				'userid'      => $entry['post_author'],
  4639 				'dateCreated' => $post_date,
  4897 				'dateCreated' => $post_date,
  4640 				'content' => $content,
  4898 				'content'     => $content,
  4641 				'postid' => (string) $entry['ID'],
  4899 				'postid'      => (string) $entry['ID'],
  4642 			);
  4900 			);
  4643 		}
  4901 		}
  4644 
  4902 
  4645 		return $recent_posts;
  4903 		return $recent_posts;
  4646 	}
  4904 	}
  4652 	 * @deprecated 3.5.0
  4910 	 * @deprecated 3.5.0
  4653 	 *
  4911 	 *
  4654 	 * @param array $args Unused.
  4912 	 * @param array $args Unused.
  4655 	 * @return IXR_Error Error object.
  4913 	 * @return IXR_Error Error object.
  4656 	 */
  4914 	 */
  4657 	public function blogger_getTemplate($args) {
  4915 	public function blogger_getTemplate( $args ) {
  4658 		return new IXR_Error( 403, __('Sorry, that file cannot be edited.' ) );
  4916 		return new IXR_Error( 403, __( 'Sorry, that file cannot be edited.' ) );
  4659 	}
  4917 	}
  4660 
  4918 
  4661 	/**
  4919 	/**
  4662 	 * Deprecated.
  4920 	 * Deprecated.
  4663 	 *
  4921 	 *
  4665 	 * @deprecated 3.5.0
  4923 	 * @deprecated 3.5.0
  4666 	 *
  4924 	 *
  4667 	 * @param array $args Unused.
  4925 	 * @param array $args Unused.
  4668 	 * @return IXR_Error Error object.
  4926 	 * @return IXR_Error Error object.
  4669 	 */
  4927 	 */
  4670 	public function blogger_setTemplate($args) {
  4928 	public function blogger_setTemplate( $args ) {
  4671 		return new IXR_Error( 403, __('Sorry, that file cannot be edited.' ) );
  4929 		return new IXR_Error( 403, __( 'Sorry, that file cannot be edited.' ) );
  4672 	}
  4930 	}
  4673 
  4931 
  4674 	/**
  4932 	/**
  4675 	 * Creates new post.
  4933 	 * Creates new post.
  4676 	 *
  4934 	 *
  4694 		$username = $args[2];
  4952 		$username = $args[2];
  4695 		$password = $args[3];
  4953 		$password = $args[3];
  4696 		$content  = $args[4];
  4954 		$content  = $args[4];
  4697 		$publish  = $args[5];
  4955 		$publish  = $args[5];
  4698 
  4956 
  4699 		if ( !$user = $this->login($username, $password) )
  4957 		if ( ! $user = $this->login( $username, $password ) ) {
  4700 			return $this->error;
  4958 			return $this->error;
       
  4959 		}
  4701 
  4960 
  4702 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4961 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4703 		do_action( 'xmlrpc_call', 'blogger.newPost' );
  4962 		do_action( 'xmlrpc_call', 'blogger.newPost' );
  4704 
  4963 
  4705 		$cap = ($publish) ? 'publish_posts' : 'edit_posts';
  4964 		$cap = ( $publish ) ? 'publish_posts' : 'edit_posts';
  4706 		if ( ! current_user_can( get_post_type_object( 'post' )->cap->create_posts ) || !current_user_can($cap) )
  4965 		if ( ! current_user_can( get_post_type_object( 'post' )->cap->create_posts ) || ! current_user_can( $cap ) ) {
  4707 			return new IXR_Error(401, __('Sorry, you are not allowed to post on this site.'));
  4966 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to post on this site.' ) );
  4708 
  4967 		}
  4709 		$post_status = ($publish) ? 'publish' : 'draft';
  4968 
       
  4969 		$post_status = ( $publish ) ? 'publish' : 'draft';
  4710 
  4970 
  4711 		$post_author = $user->ID;
  4971 		$post_author = $user->ID;
  4712 
  4972 
  4713 		$post_title = xmlrpc_getposttitle($content);
  4973 		$post_title    = xmlrpc_getposttitle( $content );
  4714 		$post_category = xmlrpc_getpostcategory($content);
  4974 		$post_category = xmlrpc_getpostcategory( $content );
  4715 		$post_content = xmlrpc_removepostdata($content);
  4975 		$post_content  = xmlrpc_removepostdata( $content );
  4716 
  4976 
  4717 		$post_date = current_time('mysql');
  4977 		$post_date     = current_time( 'mysql' );
  4718 		$post_date_gmt = current_time('mysql', 1);
  4978 		$post_date_gmt = current_time( 'mysql', 1 );
  4719 
  4979 
  4720 		$post_data = compact('post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_title', 'post_category', 'post_status');
  4980 		$post_data = compact( 'post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_title', 'post_category', 'post_status' );
  4721 
  4981 
  4722 		$post_ID = wp_insert_post($post_data);
  4982 		$post_ID = wp_insert_post( $post_data );
  4723 		if ( is_wp_error( $post_ID ) )
  4983 		if ( is_wp_error( $post_ID ) ) {
  4724 			return new IXR_Error(500, $post_ID->get_error_message());
  4984 			return new IXR_Error( 500, $post_ID->get_error_message() );
  4725 
  4985 		}
  4726 		if ( !$post_ID )
  4986 
  4727 			return new IXR_Error(500, __('Sorry, your entry could not be posted.'));
  4987 		if ( ! $post_ID ) {
       
  4988 			return new IXR_Error( 500, __( 'Sorry, your entry could not be posted.' ) );
       
  4989 		}
  4728 
  4990 
  4729 		$this->attach_uploads( $post_ID, $post_content );
  4991 		$this->attach_uploads( $post_ID, $post_content );
  4730 
  4992 
  4731 		/**
  4993 		/**
  4732 		 * Fires after a new post has been successfully created via the XML-RPC Blogger API.
  4994 		 * Fires after a new post has been successfully created via the XML-RPC Blogger API.
  4758 	 * }
  5020 	 * }
  4759 	 * @return true|IXR_Error true when done.
  5021 	 * @return true|IXR_Error true when done.
  4760 	 */
  5022 	 */
  4761 	public function blogger_editPost( $args ) {
  5023 	public function blogger_editPost( $args ) {
  4762 
  5024 
  4763 		$this->escape($args);
  5025 		$this->escape( $args );
  4764 
  5026 
  4765 		$post_ID  = (int) $args[1];
  5027 		$post_ID  = (int) $args[1];
  4766 		$username = $args[2];
  5028 		$username = $args[2];
  4767 		$password = $args[3];
  5029 		$password = $args[3];
  4768 		$content  = $args[4];
  5030 		$content  = $args[4];
  4779 
  5041 
  4780 		if ( ! $actual_post || $actual_post['post_type'] != 'post' ) {
  5042 		if ( ! $actual_post || $actual_post['post_type'] != 'post' ) {
  4781 			return new IXR_Error( 404, __( 'Sorry, no such post.' ) );
  5043 			return new IXR_Error( 404, __( 'Sorry, no such post.' ) );
  4782 		}
  5044 		}
  4783 
  5045 
  4784 		$this->escape($actual_post);
  5046 		$this->escape( $actual_post );
  4785 
  5047 
  4786 		if ( ! current_user_can( 'edit_post', $post_ID ) ) {
  5048 		if ( ! current_user_can( 'edit_post', $post_ID ) ) {
  4787 			return new IXR_Error(401, __('Sorry, you are not allowed to edit this post.'));
  5049 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit this post.' ) );
  4788 		}
  5050 		}
  4789 		if ( 'publish' == $actual_post['post_status'] && ! current_user_can( 'publish_posts' ) ) {
  5051 		if ( 'publish' == $actual_post['post_status'] && ! current_user_can( 'publish_posts' ) ) {
  4790 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to publish this post.' ) );
  5052 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to publish this post.' ) );
  4791 		}
  5053 		}
  4792 
  5054 
  4793 		$postdata = array();
  5055 		$postdata                  = array();
  4794 		$postdata['ID'] = $actual_post['ID'];
  5056 		$postdata['ID']            = $actual_post['ID'];
  4795 		$postdata['post_content'] = xmlrpc_removepostdata( $content );
  5057 		$postdata['post_content']  = xmlrpc_removepostdata( $content );
  4796 		$postdata['post_title'] = xmlrpc_getposttitle( $content );
  5058 		$postdata['post_title']    = xmlrpc_getposttitle( $content );
  4797 		$postdata['post_category'] = xmlrpc_getpostcategory( $content );
  5059 		$postdata['post_category'] = xmlrpc_getpostcategory( $content );
  4798 		$postdata['post_status'] = $actual_post['post_status'];
  5060 		$postdata['post_status']   = $actual_post['post_status'];
  4799 		$postdata['post_excerpt'] = $actual_post['post_excerpt'];
  5061 		$postdata['post_excerpt']  = $actual_post['post_excerpt'];
  4800 		$postdata['post_status'] = $publish ? 'publish' : 'draft';
  5062 		$postdata['post_status']   = $publish ? 'publish' : 'draft';
  4801 
  5063 
  4802 		$result = wp_update_post( $postdata );
  5064 		$result = wp_update_post( $postdata );
  4803 
  5065 
  4804 		if ( ! $result ) {
  5066 		if ( ! $result ) {
  4805 			return new IXR_Error(500, __('For some strange yet very annoying reason, this post could not be edited.'));
  5067 			return new IXR_Error( 500, __( 'For some strange yet very annoying reason, this post could not be edited.' ) );
  4806 		}
  5068 		}
  4807 		$this->attach_uploads( $actual_post['ID'], $postdata['post_content'] );
  5069 		$this->attach_uploads( $actual_post['ID'], $postdata['post_content'] );
  4808 
  5070 
  4809 		/**
  5071 		/**
  4810 		 * Fires after a post has been successfully updated via the XML-RPC Blogger API.
  5072 		 * Fires after a post has been successfully updated via the XML-RPC Blogger API.
  4839 
  5101 
  4840 		$post_ID  = (int) $args[1];
  5102 		$post_ID  = (int) $args[1];
  4841 		$username = $args[2];
  5103 		$username = $args[2];
  4842 		$password = $args[3];
  5104 		$password = $args[3];
  4843 
  5105 
  4844 		if ( !$user = $this->login($username, $password) )
  5106 		if ( ! $user = $this->login( $username, $password ) ) {
  4845 			return $this->error;
  5107 			return $this->error;
       
  5108 		}
  4846 
  5109 
  4847 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  5110 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4848 		do_action( 'xmlrpc_call', 'blogger.deletePost' );
  5111 		do_action( 'xmlrpc_call', 'blogger.deletePost' );
  4849 
  5112 
  4850 		$actual_post = get_post( $post_ID, ARRAY_A );
  5113 		$actual_post = get_post( $post_ID, ARRAY_A );
  4916 	 *     @type array  $content_struct
  5179 	 *     @type array  $content_struct
  4917 	 *     @type int    $publish
  5180 	 *     @type int    $publish
  4918 	 * }
  5181 	 * }
  4919 	 * @return int|IXR_Error
  5182 	 * @return int|IXR_Error
  4920 	 */
  5183 	 */
  4921 	public function mw_newPost($args) {
  5184 	public function mw_newPost( $args ) {
  4922 		$this->escape($args);
  5185 		$this->escape( $args );
  4923 
  5186 
  4924 		$username       = $args[1];
  5187 		$username       = $args[1];
  4925 		$password       = $args[2];
  5188 		$password       = $args[2];
  4926 		$content_struct = $args[3];
  5189 		$content_struct = $args[3];
  4927 		$publish        = isset( $args[4] ) ? $args[4] : 0;
  5190 		$publish        = isset( $args[4] ) ? $args[4] : 0;
  4928 
  5191 
  4929 		if ( !$user = $this->login($username, $password) )
  5192 		if ( ! $user = $this->login( $username, $password ) ) {
  4930 			return $this->error;
  5193 			return $this->error;
       
  5194 		}
  4931 
  5195 
  4932 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  5196 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4933 		do_action( 'xmlrpc_call', 'metaWeblog.newPost' );
  5197 		do_action( 'xmlrpc_call', 'metaWeblog.newPost' );
  4934 
  5198 
  4935 		$page_template = '';
  5199 		$page_template = '';
  4936 		if ( !empty( $content_struct['post_type'] ) ) {
  5200 		if ( ! empty( $content_struct['post_type'] ) ) {
  4937 			if ( $content_struct['post_type'] == 'page' ) {
  5201 			if ( $content_struct['post_type'] == 'page' ) {
  4938 				if ( $publish )
  5202 				if ( $publish ) {
  4939 					$cap  = 'publish_pages';
  5203 					$cap = 'publish_pages';
  4940 				elseif ( isset( $content_struct['page_status'] ) && 'publish' == $content_struct['page_status'] )
  5204 				} elseif ( isset( $content_struct['page_status'] ) && 'publish' == $content_struct['page_status'] ) {
  4941 					$cap  = 'publish_pages';
  5205 					$cap = 'publish_pages';
  4942 				else
  5206 				} else {
  4943 					$cap = 'edit_pages';
  5207 					$cap = 'edit_pages';
       
  5208 				}
  4944 				$error_message = __( 'Sorry, you are not allowed to publish pages on this site.' );
  5209 				$error_message = __( 'Sorry, you are not allowed to publish pages on this site.' );
  4945 				$post_type = 'page';
  5210 				$post_type     = 'page';
  4946 				if ( !empty( $content_struct['wp_page_template'] ) )
  5211 				if ( ! empty( $content_struct['wp_page_template'] ) ) {
  4947 					$page_template = $content_struct['wp_page_template'];
  5212 					$page_template = $content_struct['wp_page_template'];
       
  5213 				}
  4948 			} elseif ( $content_struct['post_type'] == 'post' ) {
  5214 			} elseif ( $content_struct['post_type'] == 'post' ) {
  4949 				if ( $publish )
  5215 				if ( $publish ) {
  4950 					$cap  = 'publish_posts';
  5216 					$cap = 'publish_posts';
  4951 				elseif ( isset( $content_struct['post_status'] ) && 'publish' == $content_struct['post_status'] )
  5217 				} elseif ( isset( $content_struct['post_status'] ) && 'publish' == $content_struct['post_status'] ) {
  4952 					$cap  = 'publish_posts';
  5218 					$cap = 'publish_posts';
  4953 				else
  5219 				} else {
  4954 					$cap = 'edit_posts';
  5220 					$cap = 'edit_posts';
       
  5221 				}
  4955 				$error_message = __( 'Sorry, you are not allowed to publish posts on this site.' );
  5222 				$error_message = __( 'Sorry, you are not allowed to publish posts on this site.' );
  4956 				$post_type = 'post';
  5223 				$post_type     = 'post';
  4957 			} else {
  5224 			} else {
  4958 				// No other post_type values are allowed here
  5225 				// No other post_type values are allowed here
  4959 				return new IXR_Error( 401, __( 'Invalid post type.' ) );
  5226 				return new IXR_Error( 401, __( 'Invalid post type.' ) );
  4960 			}
  5227 			}
  4961 		} else {
  5228 		} else {
  4962 			if ( $publish )
  5229 			if ( $publish ) {
  4963 				$cap  = 'publish_posts';
  5230 				$cap = 'publish_posts';
  4964 			elseif ( isset( $content_struct['post_status'] ) && 'publish' == $content_struct['post_status'])
  5231 			} elseif ( isset( $content_struct['post_status'] ) && 'publish' == $content_struct['post_status'] ) {
  4965 				$cap  = 'publish_posts';
  5232 				$cap = 'publish_posts';
  4966 			else
  5233 			} else {
  4967 				$cap = 'edit_posts';
  5234 				$cap = 'edit_posts';
       
  5235 			}
  4968 			$error_message = __( 'Sorry, you are not allowed to publish posts on this site.' );
  5236 			$error_message = __( 'Sorry, you are not allowed to publish posts on this site.' );
  4969 			$post_type = 'post';
  5237 			$post_type     = 'post';
  4970 		}
  5238 		}
  4971 
  5239 
  4972 		if ( ! current_user_can( get_post_type_object( $post_type )->cap->create_posts ) )
  5240 		if ( ! current_user_can( get_post_type_object( $post_type )->cap->create_posts ) ) {
  4973 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to publish posts on this site.' ) );
  5241 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to publish posts on this site.' ) );
  4974 		if ( !current_user_can( $cap ) )
  5242 		}
       
  5243 		if ( ! current_user_can( $cap ) ) {
  4975 			return new IXR_Error( 401, $error_message );
  5244 			return new IXR_Error( 401, $error_message );
       
  5245 		}
  4976 
  5246 
  4977 		// Check for a valid post format if one was given
  5247 		// Check for a valid post format if one was given
  4978 		if ( isset( $content_struct['wp_post_format'] ) ) {
  5248 		if ( isset( $content_struct['wp_post_format'] ) ) {
  4979 			$content_struct['wp_post_format'] = sanitize_key( $content_struct['wp_post_format'] );
  5249 			$content_struct['wp_post_format'] = sanitize_key( $content_struct['wp_post_format'] );
  4980 			if ( !array_key_exists( $content_struct['wp_post_format'], get_post_format_strings() ) ) {
  5250 			if ( ! array_key_exists( $content_struct['wp_post_format'], get_post_format_strings() ) ) {
  4981 				return new IXR_Error( 404, __( 'Invalid post format.' ) );
  5251 				return new IXR_Error( 404, __( 'Invalid post format.' ) );
  4982 			}
  5252 			}
  4983 		}
  5253 		}
  4984 
  5254 
  4985 		// Let WordPress generate the post_name (slug) unless
  5255 		// Let WordPress generate the post_name (slug) unless
  4986 		// one has been provided.
  5256 		// one has been provided.
  4987 		$post_name = "";
  5257 		$post_name = '';
  4988 		if ( isset($content_struct['wp_slug']) )
  5258 		if ( isset( $content_struct['wp_slug'] ) ) {
  4989 			$post_name = $content_struct['wp_slug'];
  5259 			$post_name = $content_struct['wp_slug'];
       
  5260 		}
  4990 
  5261 
  4991 		// Only use a password if one was given.
  5262 		// Only use a password if one was given.
  4992 		if ( isset($content_struct['wp_password']) )
  5263 		if ( isset( $content_struct['wp_password'] ) ) {
  4993 			$post_password = $content_struct['wp_password'];
  5264 			$post_password = $content_struct['wp_password'];
       
  5265 		} else {
       
  5266 			$post_password = '';
       
  5267 		}
  4994 
  5268 
  4995 		// Only set a post parent if one was provided.
  5269 		// Only set a post parent if one was provided.
  4996 		if ( isset($content_struct['wp_page_parent_id']) )
  5270 		if ( isset( $content_struct['wp_page_parent_id'] ) ) {
  4997 			$post_parent = $content_struct['wp_page_parent_id'];
  5271 			$post_parent = $content_struct['wp_page_parent_id'];
       
  5272 		} else {
       
  5273 			$post_parent = 0;
       
  5274 		}
  4998 
  5275 
  4999 		// Only set the menu_order if it was provided.
  5276 		// Only set the menu_order if it was provided.
  5000 		if ( isset($content_struct['wp_page_order']) )
  5277 		if ( isset( $content_struct['wp_page_order'] ) ) {
  5001 			$menu_order = $content_struct['wp_page_order'];
  5278 			$menu_order = $content_struct['wp_page_order'];
       
  5279 		} else {
       
  5280 			$menu_order = 0;
       
  5281 		}
  5002 
  5282 
  5003 		$post_author = $user->ID;
  5283 		$post_author = $user->ID;
  5004 
  5284 
  5005 		// If an author id was provided then use it instead.
  5285 		// If an author id was provided then use it instead.
  5006 		if ( isset( $content_struct['wp_author_id'] ) && ( $user->ID != $content_struct['wp_author_id'] ) ) {
  5286 		if ( isset( $content_struct['wp_author_id'] ) && ( $user->ID != $content_struct['wp_author_id'] ) ) {
  5007 			switch ( $post_type ) {
  5287 			switch ( $post_type ) {
  5008 				case "post":
  5288 				case 'post':
  5009 					if ( !current_user_can( 'edit_others_posts' ) )
  5289 					if ( ! current_user_can( 'edit_others_posts' ) ) {
  5010 						return new IXR_Error( 401, __( 'Sorry, you are not allowed to create posts as this user.' ) );
  5290 						return new IXR_Error( 401, __( 'Sorry, you are not allowed to create posts as this user.' ) );
       
  5291 					}
  5011 					break;
  5292 					break;
  5012 				case "page":
  5293 				case 'page':
  5013 					if ( !current_user_can( 'edit_others_pages' ) )
  5294 					if ( ! current_user_can( 'edit_others_pages' ) ) {
  5014 						return new IXR_Error( 401, __( 'Sorry, you are not allowed to create pages as this user.' ) );
  5295 						return new IXR_Error( 401, __( 'Sorry, you are not allowed to create pages as this user.' ) );
       
  5296 					}
  5015 					break;
  5297 					break;
  5016 				default:
  5298 				default:
  5017 					return new IXR_Error( 401, __( 'Invalid post type.' ) );
  5299 					return new IXR_Error( 401, __( 'Invalid post type.' ) );
  5018 			}
  5300 			}
  5019 			$author = get_userdata( $content_struct['wp_author_id'] );
  5301 			$author = get_userdata( $content_struct['wp_author_id'] );
  5020 			if ( ! $author )
  5302 			if ( ! $author ) {
  5021 				return new IXR_Error( 404, __( 'Invalid author ID.' ) );
  5303 				return new IXR_Error( 404, __( 'Invalid author ID.' ) );
       
  5304 			}
  5022 			$post_author = $content_struct['wp_author_id'];
  5305 			$post_author = $content_struct['wp_author_id'];
  5023 		}
  5306 		}
  5024 
  5307 
  5025 		$post_title = isset( $content_struct['title'] ) ? $content_struct['title'] : null;
  5308 		$post_title   = isset( $content_struct['title'] ) ? $content_struct['title'] : null;
  5026 		$post_content = isset( $content_struct['description'] ) ? $content_struct['description'] : null;
  5309 		$post_content = isset( $content_struct['description'] ) ? $content_struct['description'] : null;
  5027 
  5310 
  5028 		$post_status = $publish ? 'publish' : 'draft';
  5311 		$post_status = $publish ? 'publish' : 'draft';
  5029 
  5312 
  5030 		if ( isset( $content_struct["{$post_type}_status"] ) ) {
  5313 		if ( isset( $content_struct[ "{$post_type}_status" ] ) ) {
  5031 			switch ( $content_struct["{$post_type}_status"] ) {
  5314 			switch ( $content_struct[ "{$post_type}_status" ] ) {
  5032 				case 'draft':
  5315 				case 'draft':
  5033 				case 'pending':
  5316 				case 'pending':
  5034 				case 'private':
  5317 				case 'private':
  5035 				case 'publish':
  5318 				case 'publish':
  5036 					$post_status = $content_struct["{$post_type}_status"];
  5319 					$post_status = $content_struct[ "{$post_type}_status" ];
  5037 					break;
  5320 					break;
  5038 				default:
  5321 				default:
  5039 					$post_status = $publish ? 'publish' : 'draft';
  5322 					$post_status = $publish ? 'publish' : 'draft';
  5040 					break;
  5323 					break;
  5041 			}
  5324 			}
  5042 		}
  5325 		}
  5043 
  5326 
  5044 		$post_excerpt = isset($content_struct['mt_excerpt']) ? $content_struct['mt_excerpt'] : null;
  5327 		$post_excerpt = isset( $content_struct['mt_excerpt'] ) ? $content_struct['mt_excerpt'] : null;
  5045 		$post_more = isset($content_struct['mt_text_more']) ? $content_struct['mt_text_more'] : null;
  5328 		$post_more    = isset( $content_struct['mt_text_more'] ) ? $content_struct['mt_text_more'] : null;
  5046 
  5329 
  5047 		$tags_input = isset($content_struct['mt_keywords']) ? $content_struct['mt_keywords'] : null;
  5330 		$tags_input = isset( $content_struct['mt_keywords'] ) ? $content_struct['mt_keywords'] : null;
  5048 
  5331 
  5049 		if ( isset($content_struct['mt_allow_comments']) ) {
  5332 		if ( isset( $content_struct['mt_allow_comments'] ) ) {
  5050 			if ( !is_numeric($content_struct['mt_allow_comments']) ) {
  5333 			if ( ! is_numeric( $content_struct['mt_allow_comments'] ) ) {
  5051 				switch ( $content_struct['mt_allow_comments'] ) {
  5334 				switch ( $content_struct['mt_allow_comments'] ) {
  5052 					case 'closed':
  5335 					case 'closed':
  5053 						$comment_status = 'closed';
  5336 						$comment_status = 'closed';
  5054 						break;
  5337 						break;
  5055 					case 'open':
  5338 					case 'open':
  5075 			}
  5358 			}
  5076 		} else {
  5359 		} else {
  5077 			$comment_status = get_default_comment_status( $post_type );
  5360 			$comment_status = get_default_comment_status( $post_type );
  5078 		}
  5361 		}
  5079 
  5362 
  5080 		if ( isset($content_struct['mt_allow_pings']) ) {
  5363 		if ( isset( $content_struct['mt_allow_pings'] ) ) {
  5081 			if ( !is_numeric($content_struct['mt_allow_pings']) ) {
  5364 			if ( ! is_numeric( $content_struct['mt_allow_pings'] ) ) {
  5082 				switch ( $content_struct['mt_allow_pings'] ) {
  5365 				switch ( $content_struct['mt_allow_pings'] ) {
  5083 					case 'closed':
  5366 					case 'closed':
  5084 						$ping_status = 'closed';
  5367 						$ping_status = 'closed';
  5085 						break;
  5368 						break;
  5086 					case 'open':
  5369 					case 'open':
  5105 			}
  5388 			}
  5106 		} else {
  5389 		} else {
  5107 			$ping_status = get_default_comment_status( $post_type, 'pingback' );
  5390 			$ping_status = get_default_comment_status( $post_type, 'pingback' );
  5108 		}
  5391 		}
  5109 
  5392 
  5110 		if ( $post_more )
  5393 		if ( $post_more ) {
  5111 			$post_content = $post_content . '<!--more-->' . $post_more;
  5394 			$post_content = $post_content . '<!--more-->' . $post_more;
       
  5395 		}
  5112 
  5396 
  5113 		$to_ping = null;
  5397 		$to_ping = null;
  5114 		if ( isset( $content_struct['mt_tb_ping_urls'] ) ) {
  5398 		if ( isset( $content_struct['mt_tb_ping_urls'] ) ) {
  5115 			$to_ping = $content_struct['mt_tb_ping_urls'];
  5399 			$to_ping = $content_struct['mt_tb_ping_urls'];
  5116 			if ( is_array($to_ping) )
  5400 			if ( is_array( $to_ping ) ) {
  5117 				$to_ping = implode(' ', $to_ping);
  5401 				$to_ping = implode( ' ', $to_ping );
       
  5402 			}
  5118 		}
  5403 		}
  5119 
  5404 
  5120 		// Do some timestamp voodoo
  5405 		// Do some timestamp voodoo
  5121 		if ( !empty( $content_struct['date_created_gmt'] ) )
  5406 		if ( ! empty( $content_struct['date_created_gmt'] ) ) {
  5122 			// We know this is supposed to be GMT, so we're going to slap that Z on there by force
  5407 			// We know this is supposed to be GMT, so we're going to slap that Z on there by force
  5123 			$dateCreated = rtrim( $content_struct['date_created_gmt']->getIso(), 'Z' ) . 'Z';
  5408 			$dateCreated = rtrim( $content_struct['date_created_gmt']->getIso(), 'Z' ) . 'Z';
  5124 		elseif ( !empty( $content_struct['dateCreated']) )
  5409 		} elseif ( ! empty( $content_struct['dateCreated'] ) ) {
  5125 			$dateCreated = $content_struct['dateCreated']->getIso();
  5410 			$dateCreated = $content_struct['dateCreated']->getIso();
  5126 
  5411 		}
  5127 		if ( !empty( $dateCreated ) ) {
  5412 
  5128 			$post_date = get_date_from_gmt(iso8601_to_datetime($dateCreated));
  5413 		if ( ! empty( $dateCreated ) ) {
  5129 			$post_date_gmt = iso8601_to_datetime($dateCreated, 'GMT');
  5414 			$post_date     = get_date_from_gmt( iso8601_to_datetime( $dateCreated ) );
       
  5415 			$post_date_gmt = iso8601_to_datetime( $dateCreated, 'GMT' );
  5130 		} else {
  5416 		} else {
  5131 			$post_date = '';
  5417 			$post_date     = '';
  5132 			$post_date_gmt = '';
  5418 			$post_date_gmt = '';
  5133 		}
  5419 		}
  5134 
  5420 
  5135 		$post_category = array();
  5421 		$post_category = array();
  5136 		if ( isset( $content_struct['categories'] ) ) {
  5422 		if ( isset( $content_struct['categories'] ) ) {
  5137 			$catnames = $content_struct['categories'];
  5423 			$catnames = $content_struct['categories'];
  5138 
  5424 
  5139 			if ( is_array($catnames) ) {
  5425 			if ( is_array( $catnames ) ) {
  5140 				foreach ($catnames as $cat) {
  5426 				foreach ( $catnames as $cat ) {
  5141 					$post_category[] = get_cat_ID($cat);
  5427 					$post_category[] = get_cat_ID( $cat );
  5142 				}
  5428 				}
  5143 			}
  5429 			}
  5144 		}
  5430 		}
  5145 
  5431 
  5146 		$postdata = compact('post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt', 'comment_status', 'ping_status', 'to_ping', 'post_type', 'post_name', 'post_password', 'post_parent', 'menu_order', 'tags_input', 'page_template');
  5432 		$postdata = compact( 'post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt', 'comment_status', 'ping_status', 'to_ping', 'post_type', 'post_name', 'post_password', 'post_parent', 'menu_order', 'tags_input', 'page_template' );
  5147 
  5433 
  5148 		$post_ID = $postdata['ID'] = get_default_post_to_edit( $post_type, true )->ID;
  5434 		$post_ID = $postdata['ID'] = get_default_post_to_edit( $post_type, true )->ID;
  5149 
  5435 
  5150 		// Only posts can be sticky
  5436 		// Only posts can be sticky
  5151 		if ( $post_type == 'post' && isset( $content_struct['sticky'] ) ) {
  5437 		if ( $post_type == 'post' && isset( $content_struct['sticky'] ) ) {
  5152 			$data = $postdata;
  5438 			$data           = $postdata;
  5153 			$data['sticky'] = $content_struct['sticky'];
  5439 			$data['sticky'] = $content_struct['sticky'];
  5154 			$error = $this->_toggle_sticky( $data );
  5440 			$error          = $this->_toggle_sticky( $data );
  5155 			if ( $error ) {
  5441 			if ( $error ) {
  5156 				return $error;
  5442 				return $error;
  5157 			}
  5443 			}
  5158 		}
  5444 		}
  5159 
  5445 
  5160 		if ( isset($content_struct['custom_fields']) )
  5446 		if ( isset( $content_struct['custom_fields'] ) ) {
  5161 			$this->set_custom_fields($post_ID, $content_struct['custom_fields']);
  5447 			$this->set_custom_fields( $post_ID, $content_struct['custom_fields'] );
  5162 
  5448 		}
  5163 		if ( isset ( $content_struct['wp_post_thumbnail'] ) ) {
  5449 
  5164 			if ( set_post_thumbnail( $post_ID, $content_struct['wp_post_thumbnail'] ) === false )
  5450 		if ( isset( $content_struct['wp_post_thumbnail'] ) ) {
       
  5451 			if ( set_post_thumbnail( $post_ID, $content_struct['wp_post_thumbnail'] ) === false ) {
  5165 				return new IXR_Error( 404, __( 'Invalid attachment ID.' ) );
  5452 				return new IXR_Error( 404, __( 'Invalid attachment ID.' ) );
       
  5453 			}
  5166 
  5454 
  5167 			unset( $content_struct['wp_post_thumbnail'] );
  5455 			unset( $content_struct['wp_post_thumbnail'] );
  5168 		}
  5456 		}
  5169 
  5457 
  5170 		// Handle enclosures
  5458 		// Handle enclosures
  5171 		$thisEnclosure = isset($content_struct['enclosure']) ? $content_struct['enclosure'] : null;
  5459 		$thisEnclosure = isset( $content_struct['enclosure'] ) ? $content_struct['enclosure'] : null;
  5172 		$this->add_enclosure_if_new($post_ID, $thisEnclosure);
  5460 		$this->add_enclosure_if_new( $post_ID, $thisEnclosure );
  5173 
  5461 
  5174 		$this->attach_uploads( $post_ID, $post_content );
  5462 		$this->attach_uploads( $post_ID, $post_content );
  5175 
  5463 
  5176 		// Handle post formats if assigned, value is validated earlier
  5464 		// Handle post formats if assigned, value is validated earlier
  5177 		// in this function
  5465 		// in this function
  5178 		if ( isset( $content_struct['wp_post_format'] ) )
  5466 		if ( isset( $content_struct['wp_post_format'] ) ) {
  5179 			set_post_format( $post_ID, $content_struct['wp_post_format'] );
  5467 			set_post_format( $post_ID, $content_struct['wp_post_format'] );
       
  5468 		}
  5180 
  5469 
  5181 		$post_ID = wp_insert_post( $postdata, true );
  5470 		$post_ID = wp_insert_post( $postdata, true );
  5182 		if ( is_wp_error( $post_ID ) )
  5471 		if ( is_wp_error( $post_ID ) ) {
  5183 			return new IXR_Error(500, $post_ID->get_error_message());
  5472 			return new IXR_Error( 500, $post_ID->get_error_message() );
  5184 
  5473 		}
  5185 		if ( !$post_ID )
  5474 
  5186 			return new IXR_Error(500, __('Sorry, your entry could not be posted.'));
  5475 		if ( ! $post_ID ) {
       
  5476 			return new IXR_Error( 500, __( 'Sorry, your entry could not be posted.' ) );
       
  5477 		}
  5187 
  5478 
  5188 		/**
  5479 		/**
  5189 		 * Fires after a new post has been successfully created via the XML-RPC MovableType API.
  5480 		 * Fires after a new post has been successfully created via the XML-RPC MovableType API.
  5190 		 *
  5481 		 *
  5191 		 * @since 3.4.0
  5482 		 * @since 3.4.0
  5193 		 * @param int   $post_ID ID of the new post.
  5484 		 * @param int   $post_ID ID of the new post.
  5194 		 * @param array $args    An array of arguments to create the new post.
  5485 		 * @param array $args    An array of arguments to create the new post.
  5195 		 */
  5486 		 */
  5196 		do_action( 'xmlrpc_call_success_mw_newPost', $post_ID, $args );
  5487 		do_action( 'xmlrpc_call_success_mw_newPost', $post_ID, $args );
  5197 
  5488 
  5198 		return strval($post_ID);
  5489 		return strval( $post_ID );
  5199 	}
  5490 	}
  5200 
  5491 
  5201 	/**
  5492 	/**
  5202 	 * Adds an enclosure to a post if it's new.
  5493 	 * Adds an enclosure to a post if it's new.
  5203 	 *
  5494 	 *
  5207 	 * @param array   $enclosure Enclosure data.
  5498 	 * @param array   $enclosure Enclosure data.
  5208 	 */
  5499 	 */
  5209 	public function add_enclosure_if_new( $post_ID, $enclosure ) {
  5500 	public function add_enclosure_if_new( $post_ID, $enclosure ) {
  5210 		if ( is_array( $enclosure ) && isset( $enclosure['url'] ) && isset( $enclosure['length'] ) && isset( $enclosure['type'] ) ) {
  5501 		if ( is_array( $enclosure ) && isset( $enclosure['url'] ) && isset( $enclosure['length'] ) && isset( $enclosure['type'] ) ) {
  5211 			$encstring = $enclosure['url'] . "\n" . $enclosure['length'] . "\n" . $enclosure['type'] . "\n";
  5502 			$encstring = $enclosure['url'] . "\n" . $enclosure['length'] . "\n" . $enclosure['type'] . "\n";
  5212 			$found = false;
  5503 			$found     = false;
  5213 			if ( $enclosures = get_post_meta( $post_ID, 'enclosure' ) ) {
  5504 			if ( $enclosures = get_post_meta( $post_ID, 'enclosure' ) ) {
  5214 				foreach ( $enclosures as $enc ) {
  5505 				foreach ( $enclosures as $enc ) {
  5215 					// This method used to omit the trailing new line. #23219
  5506 					// This method used to omit the trailing new line. #23219
  5216 					if ( rtrim( $enc, "\n" ) == rtrim( $encstring, "\n" ) ) {
  5507 					if ( rtrim( $enc, "\n" ) == rtrim( $encstring, "\n" ) ) {
  5217 						$found = true;
  5508 						$found = true;
  5218 						break;
  5509 						break;
  5219 					}
  5510 					}
  5220 				}
  5511 				}
  5221 			}
  5512 			}
  5222 			if ( ! $found )
  5513 			if ( ! $found ) {
  5223 				add_post_meta( $post_ID, 'enclosure', $encstring );
  5514 				add_post_meta( $post_ID, 'enclosure', $encstring );
       
  5515 			}
  5224 		}
  5516 		}
  5225 	}
  5517 	}
  5226 
  5518 
  5227 	/**
  5519 	/**
  5228 	 * Attach upload to a post.
  5520 	 * Attach upload to a post.
  5239 
  5531 
  5240 		// find any unattached files
  5532 		// find any unattached files
  5241 		$attachments = $wpdb->get_results( "SELECT ID, guid FROM {$wpdb->posts} WHERE post_parent = '0' AND post_type = 'attachment'" );
  5533 		$attachments = $wpdb->get_results( "SELECT ID, guid FROM {$wpdb->posts} WHERE post_parent = '0' AND post_type = 'attachment'" );
  5242 		if ( is_array( $attachments ) ) {
  5534 		if ( is_array( $attachments ) ) {
  5243 			foreach ( $attachments as $file ) {
  5535 			foreach ( $attachments as $file ) {
  5244 				if ( ! empty( $file->guid ) && strpos( $post_content, $file->guid ) !== false )
  5536 				if ( ! empty( $file->guid ) && strpos( $post_content, $file->guid ) !== false ) {
  5245 					$wpdb->update($wpdb->posts, array('post_parent' => $post_ID), array('ID' => $file->ID) );
  5537 					$wpdb->update( $wpdb->posts, array( 'post_parent' => $post_ID ), array( 'ID' => $file->ID ) );
       
  5538 				}
  5246 			}
  5539 			}
  5247 		}
  5540 		}
  5248 	}
  5541 	}
  5249 
  5542 
  5250 	/**
  5543 	/**
  5270 		$username       = $args[1];
  5563 		$username       = $args[1];
  5271 		$password       = $args[2];
  5564 		$password       = $args[2];
  5272 		$content_struct = $args[3];
  5565 		$content_struct = $args[3];
  5273 		$publish        = isset( $args[4] ) ? $args[4] : 0;
  5566 		$publish        = isset( $args[4] ) ? $args[4] : 0;
  5274 
  5567 
  5275 		if ( ! $user = $this->login($username, $password) )
  5568 		if ( ! $user = $this->login( $username, $password ) ) {
  5276 			return $this->error;
  5569 			return $this->error;
       
  5570 		}
  5277 
  5571 
  5278 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  5572 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  5279 		do_action( 'xmlrpc_call', 'metaWeblog.editPost' );
  5573 		do_action( 'xmlrpc_call', 'metaWeblog.editPost' );
  5280 
  5574 
  5281 		$postdata = get_post( $post_ID, ARRAY_A );
  5575 		$postdata = get_post( $post_ID, ARRAY_A );
  5282 
  5576 
  5283 		/*
  5577 		/*
  5284 		 * If there is no post data for the give post id, stop now and return an error.
  5578 		 * If there is no post data for the give post id, stop now and return an error.
  5285 		 * Otherwise a new post will be created (which was the old behavior).
  5579 		 * Otherwise a new post will be created (which was the old behavior).
  5286 		 */
  5580 		 */
  5287 		if ( ! $postdata || empty( $postdata[ 'ID' ] ) )
  5581 		if ( ! $postdata || empty( $postdata['ID'] ) ) {
  5288 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  5582 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  5289 
  5583 		}
  5290 		if ( ! current_user_can( 'edit_post', $post_ID ) )
  5584 
       
  5585 		if ( ! current_user_can( 'edit_post', $post_ID ) ) {
  5291 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit this post.' ) );
  5586 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit this post.' ) );
       
  5587 		}
  5292 
  5588 
  5293 		// Use wp.editPost to edit post types other than post and page.
  5589 		// Use wp.editPost to edit post types other than post and page.
  5294 		if ( ! in_array( $postdata[ 'post_type' ], array( 'post', 'page' ) ) )
  5590 		if ( ! in_array( $postdata['post_type'], array( 'post', 'page' ) ) ) {
  5295 			return new IXR_Error( 401, __( 'Invalid post type.' ) );
  5591 			return new IXR_Error( 401, __( 'Invalid post type.' ) );
       
  5592 		}
  5296 
  5593 
  5297 		// Thwart attempt to change the post type.
  5594 		// Thwart attempt to change the post type.
  5298 		if ( ! empty( $content_struct[ 'post_type' ] ) && ( $content_struct['post_type'] != $postdata[ 'post_type' ] ) )
  5595 		if ( ! empty( $content_struct['post_type'] ) && ( $content_struct['post_type'] != $postdata['post_type'] ) ) {
  5299 			return new IXR_Error( 401, __( 'The post type may not be changed.' ) );
  5596 			return new IXR_Error( 401, __( 'The post type may not be changed.' ) );
       
  5597 		}
  5300 
  5598 
  5301 		// Check for a valid post format if one was given
  5599 		// Check for a valid post format if one was given
  5302 		if ( isset( $content_struct['wp_post_format'] ) ) {
  5600 		if ( isset( $content_struct['wp_post_format'] ) ) {
  5303 			$content_struct['wp_post_format'] = sanitize_key( $content_struct['wp_post_format'] );
  5601 			$content_struct['wp_post_format'] = sanitize_key( $content_struct['wp_post_format'] );
  5304 			if ( !array_key_exists( $content_struct['wp_post_format'], get_post_format_strings() ) ) {
  5602 			if ( ! array_key_exists( $content_struct['wp_post_format'], get_post_format_strings() ) ) {
  5305 				return new IXR_Error( 404, __( 'Invalid post format.' ) );
  5603 				return new IXR_Error( 404, __( 'Invalid post format.' ) );
  5306 			}
  5604 			}
  5307 		}
  5605 		}
  5308 
  5606 
  5309 		$this->escape($postdata);
  5607 		$this->escape( $postdata );
  5310 
  5608 
  5311 		$ID = $postdata['ID'];
  5609 		$ID             = $postdata['ID'];
  5312 		$post_content = $postdata['post_content'];
  5610 		$post_content   = $postdata['post_content'];
  5313 		$post_title = $postdata['post_title'];
  5611 		$post_title     = $postdata['post_title'];
  5314 		$post_excerpt = $postdata['post_excerpt'];
  5612 		$post_excerpt   = $postdata['post_excerpt'];
  5315 		$post_password = $postdata['post_password'];
  5613 		$post_password  = $postdata['post_password'];
  5316 		$post_parent = $postdata['post_parent'];
  5614 		$post_parent    = $postdata['post_parent'];
  5317 		$post_type = $postdata['post_type'];
  5615 		$post_type      = $postdata['post_type'];
  5318 		$menu_order = $postdata['menu_order'];
  5616 		$menu_order     = $postdata['menu_order'];
       
  5617 		$ping_status    = $postdata['ping_status'];
       
  5618 		$comment_status = $postdata['comment_status'];
  5319 
  5619 
  5320 		// Let WordPress manage slug if none was provided.
  5620 		// Let WordPress manage slug if none was provided.
  5321 		$post_name = $postdata['post_name'];
  5621 		$post_name = $postdata['post_name'];
  5322 		if ( isset($content_struct['wp_slug']) )
  5622 		if ( isset( $content_struct['wp_slug'] ) ) {
  5323 			$post_name = $content_struct['wp_slug'];
  5623 			$post_name = $content_struct['wp_slug'];
       
  5624 		}
  5324 
  5625 
  5325 		// Only use a password if one was given.
  5626 		// Only use a password if one was given.
  5326 		if ( isset($content_struct['wp_password']) )
  5627 		if ( isset( $content_struct['wp_password'] ) ) {
  5327 			$post_password = $content_struct['wp_password'];
  5628 			$post_password = $content_struct['wp_password'];
       
  5629 		}
  5328 
  5630 
  5329 		// Only set a post parent if one was given.
  5631 		// Only set a post parent if one was given.
  5330 		if ( isset($content_struct['wp_page_parent_id']) )
  5632 		if ( isset( $content_struct['wp_page_parent_id'] ) ) {
  5331 			$post_parent = $content_struct['wp_page_parent_id'];
  5633 			$post_parent = $content_struct['wp_page_parent_id'];
       
  5634 		}
  5332 
  5635 
  5333 		// Only set the menu_order if it was given.
  5636 		// Only set the menu_order if it was given.
  5334 		if ( isset($content_struct['wp_page_order']) )
  5637 		if ( isset( $content_struct['wp_page_order'] ) ) {
  5335 			$menu_order = $content_struct['wp_page_order'];
  5638 			$menu_order = $content_struct['wp_page_order'];
       
  5639 		}
  5336 
  5640 
  5337 		$page_template = null;
  5641 		$page_template = null;
  5338 		if ( ! empty( $content_struct['wp_page_template'] ) && 'page' == $post_type )
  5642 		if ( ! empty( $content_struct['wp_page_template'] ) && 'page' == $post_type ) {
  5339 			$page_template = $content_struct['wp_page_template'];
  5643 			$page_template = $content_struct['wp_page_template'];
       
  5644 		}
  5340 
  5645 
  5341 		$post_author = $postdata['post_author'];
  5646 		$post_author = $postdata['post_author'];
  5342 
  5647 
  5343 		// Only set the post_author if one is set.
  5648 		// Only set the post_author if one is set.
  5344 		if ( isset( $content_struct['wp_author_id'] ) ) {
  5649 		if ( isset( $content_struct['wp_author_id'] ) ) {
  5360 				}
  5665 				}
  5361 				$post_author = $content_struct['wp_author_id'];
  5666 				$post_author = $content_struct['wp_author_id'];
  5362 			}
  5667 			}
  5363 		}
  5668 		}
  5364 
  5669 
  5365 		if ( isset($content_struct['mt_allow_comments']) ) {
  5670 		if ( isset( $content_struct['mt_allow_comments'] ) ) {
  5366 			if ( !is_numeric($content_struct['mt_allow_comments']) ) {
  5671 			if ( ! is_numeric( $content_struct['mt_allow_comments'] ) ) {
  5367 				switch ( $content_struct['mt_allow_comments'] ) {
  5672 				switch ( $content_struct['mt_allow_comments'] ) {
  5368 					case 'closed':
  5673 					case 'closed':
  5369 						$comment_status = 'closed';
  5674 						$comment_status = 'closed';
  5370 						break;
  5675 						break;
  5371 					case 'open':
  5676 					case 'open':
  5389 						break;
  5694 						break;
  5390 				}
  5695 				}
  5391 			}
  5696 			}
  5392 		}
  5697 		}
  5393 
  5698 
  5394 		if ( isset($content_struct['mt_allow_pings']) ) {
  5699 		if ( isset( $content_struct['mt_allow_pings'] ) ) {
  5395 			if ( !is_numeric($content_struct['mt_allow_pings']) ) {
  5700 			if ( ! is_numeric( $content_struct['mt_allow_pings'] ) ) {
  5396 				switch ( $content_struct['mt_allow_pings'] ) {
  5701 				switch ( $content_struct['mt_allow_pings'] ) {
  5397 					case 'closed':
  5702 					case 'closed':
  5398 						$ping_status = 'closed';
  5703 						$ping_status = 'closed';
  5399 						break;
  5704 						break;
  5400 					case 'open':
  5705 					case 'open':
  5403 					default:
  5708 					default:
  5404 						$ping_status = get_default_comment_status( $post_type, 'pingback' );
  5709 						$ping_status = get_default_comment_status( $post_type, 'pingback' );
  5405 						break;
  5710 						break;
  5406 				}
  5711 				}
  5407 			} else {
  5712 			} else {
  5408 				switch ( (int) $content_struct["mt_allow_pings"] ) {
  5713 				switch ( (int) $content_struct['mt_allow_pings'] ) {
  5409 					case 0:
  5714 					case 0:
  5410 						$ping_status = 'closed';
  5715 						$ping_status = 'closed';
  5411 						break;
  5716 						break;
  5412 					case 1:
  5717 					case 1:
  5413 						$ping_status = 'open';
  5718 						$ping_status = 'open';
  5417 						break;
  5722 						break;
  5418 				}
  5723 				}
  5419 			}
  5724 			}
  5420 		}
  5725 		}
  5421 
  5726 
  5422 		if ( isset( $content_struct['title'] ) )
  5727 		if ( isset( $content_struct['title'] ) ) {
  5423 			$post_title =  $content_struct['title'];
  5728 			$post_title = $content_struct['title'];
  5424 
  5729 		}
  5425 		if ( isset( $content_struct['description'] ) )
  5730 
       
  5731 		if ( isset( $content_struct['description'] ) ) {
  5426 			$post_content = $content_struct['description'];
  5732 			$post_content = $content_struct['description'];
       
  5733 		}
  5427 
  5734 
  5428 		$post_category = array();
  5735 		$post_category = array();
  5429 		if ( isset( $content_struct['categories'] ) ) {
  5736 		if ( isset( $content_struct['categories'] ) ) {
  5430 			$catnames = $content_struct['categories'];
  5737 			$catnames = $content_struct['categories'];
  5431 			if ( is_array($catnames) ) {
  5738 			if ( is_array( $catnames ) ) {
  5432 				foreach ($catnames as $cat) {
  5739 				foreach ( $catnames as $cat ) {
  5433 					$post_category[] = get_cat_ID($cat);
  5740 					$post_category[] = get_cat_ID( $cat );
  5434 				}
  5741 				}
  5435 			}
  5742 			}
  5436 		}
  5743 		}
  5437 
  5744 
  5438 		if ( isset( $content_struct['mt_excerpt'] ) )
  5745 		if ( isset( $content_struct['mt_excerpt'] ) ) {
  5439 			$post_excerpt =  $content_struct['mt_excerpt'];
  5746 			$post_excerpt = $content_struct['mt_excerpt'];
       
  5747 		}
  5440 
  5748 
  5441 		$post_more = isset( $content_struct['mt_text_more'] ) ? $content_struct['mt_text_more'] : null;
  5749 		$post_more = isset( $content_struct['mt_text_more'] ) ? $content_struct['mt_text_more'] : null;
  5442 
  5750 
  5443 		$post_status = $publish ? 'publish' : 'draft';
  5751 		$post_status = $publish ? 'publish' : 'draft';
  5444 		if ( isset( $content_struct["{$post_type}_status"] ) ) {
  5752 		if ( isset( $content_struct[ "{$post_type}_status" ] ) ) {
  5445 			switch( $content_struct["{$post_type}_status"] ) {
  5753 			switch ( $content_struct[ "{$post_type}_status" ] ) {
  5446 				case 'draft':
  5754 				case 'draft':
  5447 				case 'pending':
  5755 				case 'pending':
  5448 				case 'private':
  5756 				case 'private':
  5449 				case 'publish':
  5757 				case 'publish':
  5450 					$post_status = $content_struct["{$post_type}_status"];
  5758 					$post_status = $content_struct[ "{$post_type}_status" ];
  5451 					break;
  5759 					break;
  5452 				default:
  5760 				default:
  5453 					$post_status = $publish ? 'publish' : 'draft';
  5761 					$post_status = $publish ? 'publish' : 'draft';
  5454 					break;
  5762 					break;
  5455 			}
  5763 			}
  5463 			} elseif ( ! current_user_can( 'publish_posts' ) ) {
  5771 			} elseif ( ! current_user_can( 'publish_posts' ) ) {
  5464 				return new IXR_Error( 401, __( 'Sorry, you are not allowed to publish this post.' ) );
  5772 				return new IXR_Error( 401, __( 'Sorry, you are not allowed to publish this post.' ) );
  5465 			}
  5773 			}
  5466 		}
  5774 		}
  5467 
  5775 
  5468 		if ( $post_more )
  5776 		if ( $post_more ) {
  5469 			$post_content = $post_content . "<!--more-->" . $post_more;
  5777 			$post_content = $post_content . '<!--more-->' . $post_more;
       
  5778 		}
  5470 
  5779 
  5471 		$to_ping = null;
  5780 		$to_ping = null;
  5472 		if ( isset( $content_struct['mt_tb_ping_urls'] ) ) {
  5781 		if ( isset( $content_struct['mt_tb_ping_urls'] ) ) {
  5473 			$to_ping = $content_struct['mt_tb_ping_urls'];
  5782 			$to_ping = $content_struct['mt_tb_ping_urls'];
  5474 			if ( is_array($to_ping) )
  5783 			if ( is_array( $to_ping ) ) {
  5475 				$to_ping = implode(' ', $to_ping);
  5784 				$to_ping = implode( ' ', $to_ping );
       
  5785 			}
  5476 		}
  5786 		}
  5477 
  5787 
  5478 		// Do some timestamp voodoo.
  5788 		// Do some timestamp voodoo.
  5479 		if ( !empty( $content_struct['date_created_gmt'] ) )
  5789 		if ( ! empty( $content_struct['date_created_gmt'] ) ) {
  5480 			// We know this is supposed to be GMT, so we're going to slap that Z on there by force.
  5790 			// We know this is supposed to be GMT, so we're going to slap that Z on there by force.
  5481 			$dateCreated = rtrim( $content_struct['date_created_gmt']->getIso(), 'Z' ) . 'Z';
  5791 			$dateCreated = rtrim( $content_struct['date_created_gmt']->getIso(), 'Z' ) . 'Z';
  5482 		elseif ( !empty( $content_struct['dateCreated']) )
  5792 		} elseif ( ! empty( $content_struct['dateCreated'] ) ) {
  5483 			$dateCreated = $content_struct['dateCreated']->getIso();
  5793 			$dateCreated = $content_struct['dateCreated']->getIso();
       
  5794 		}
  5484 
  5795 
  5485 		// Default to not flagging the post date to be edited unless it's intentional.
  5796 		// Default to not flagging the post date to be edited unless it's intentional.
  5486 		$edit_date = false;
  5797 		$edit_date = false;
  5487 
  5798 
  5488 		if ( !empty( $dateCreated ) ) {
  5799 		if ( ! empty( $dateCreated ) ) {
  5489 			$post_date = get_date_from_gmt(iso8601_to_datetime($dateCreated));
  5800 			$post_date     = get_date_from_gmt( iso8601_to_datetime( $dateCreated ) );
  5490 			$post_date_gmt = iso8601_to_datetime($dateCreated, 'GMT');
  5801 			$post_date_gmt = iso8601_to_datetime( $dateCreated, 'GMT' );
  5491 
  5802 
  5492 			// Flag the post date to be edited.
  5803 			// Flag the post date to be edited.
  5493 			$edit_date = true;
  5804 			$edit_date = true;
  5494 		} else {
  5805 		} else {
  5495 			$post_date     = $postdata['post_date'];
  5806 			$post_date     = $postdata['post_date'];
  5496 			$post_date_gmt = $postdata['post_date_gmt'];
  5807 			$post_date_gmt = $postdata['post_date_gmt'];
  5497 		}
  5808 		}
  5498 
  5809 
  5499 		// We've got all the data -- post it.
  5810 		// We've got all the data -- post it.
  5500 		$newpost = compact('ID', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt', 'comment_status', 'ping_status', 'edit_date', 'post_date', 'post_date_gmt', 'to_ping', 'post_name', 'post_password', 'post_parent', 'menu_order', 'post_author', 'tags_input', 'page_template');
  5811 		$newpost = compact( 'ID', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt', 'comment_status', 'ping_status', 'edit_date', 'post_date', 'post_date_gmt', 'to_ping', 'post_name', 'post_password', 'post_parent', 'menu_order', 'post_author', 'tags_input', 'page_template' );
  5501 
  5812 
  5502 		$result = wp_update_post($newpost, true);
  5813 		$result = wp_update_post( $newpost, true );
  5503 		if ( is_wp_error( $result ) )
  5814 		if ( is_wp_error( $result ) ) {
  5504 			return new IXR_Error(500, $result->get_error_message());
  5815 			return new IXR_Error( 500, $result->get_error_message() );
  5505 
  5816 		}
  5506 		if ( !$result )
  5817 
  5507 			return new IXR_Error(500, __('Sorry, your entry could not be edited.'));
  5818 		if ( ! $result ) {
       
  5819 			return new IXR_Error( 500, __( 'Sorry, your entry could not be edited.' ) );
       
  5820 		}
  5508 
  5821 
  5509 		// Only posts can be sticky
  5822 		// Only posts can be sticky
  5510 		if ( $post_type == 'post' && isset( $content_struct['sticky'] ) ) {
  5823 		if ( $post_type == 'post' && isset( $content_struct['sticky'] ) ) {
  5511 			$data = $newpost;
  5824 			$data              = $newpost;
  5512 			$data['sticky'] = $content_struct['sticky'];
  5825 			$data['sticky']    = $content_struct['sticky'];
  5513 			$data['post_type'] = 'post';
  5826 			$data['post_type'] = 'post';
  5514 			$error = $this->_toggle_sticky( $data, true );
  5827 			$error             = $this->_toggle_sticky( $data, true );
  5515 			if ( $error ) {
  5828 			if ( $error ) {
  5516 				return $error;
  5829 				return $error;
  5517 			}
  5830 			}
  5518 		}
  5831 		}
  5519 
  5832 
  5520 		if ( isset($content_struct['custom_fields']) )
  5833 		if ( isset( $content_struct['custom_fields'] ) ) {
  5521 			$this->set_custom_fields($post_ID, $content_struct['custom_fields']);
  5834 			$this->set_custom_fields( $post_ID, $content_struct['custom_fields'] );
  5522 
  5835 		}
  5523 		if ( isset ( $content_struct['wp_post_thumbnail'] ) ) {
  5836 
       
  5837 		if ( isset( $content_struct['wp_post_thumbnail'] ) ) {
  5524 
  5838 
  5525 			// Empty value deletes, non-empty value adds/updates.
  5839 			// Empty value deletes, non-empty value adds/updates.
  5526 			if ( empty( $content_struct['wp_post_thumbnail'] ) ) {
  5840 			if ( empty( $content_struct['wp_post_thumbnail'] ) ) {
  5527 				delete_post_thumbnail( $post_ID );
  5841 				delete_post_thumbnail( $post_ID );
  5528 			} else {
  5842 			} else {
  5529 				if ( set_post_thumbnail( $post_ID, $content_struct['wp_post_thumbnail'] ) === false )
  5843 				if ( set_post_thumbnail( $post_ID, $content_struct['wp_post_thumbnail'] ) === false ) {
  5530 					return new IXR_Error( 404, __( 'Invalid attachment ID.' ) );
  5844 					return new IXR_Error( 404, __( 'Invalid attachment ID.' ) );
       
  5845 				}
  5531 			}
  5846 			}
  5532 			unset( $content_struct['wp_post_thumbnail'] );
  5847 			unset( $content_struct['wp_post_thumbnail'] );
  5533 		}
  5848 		}
  5534 
  5849 
  5535 		// Handle enclosures.
  5850 		// Handle enclosures.
  5536 		$thisEnclosure = isset($content_struct['enclosure']) ? $content_struct['enclosure'] : null;
  5851 		$thisEnclosure = isset( $content_struct['enclosure'] ) ? $content_struct['enclosure'] : null;
  5537 		$this->add_enclosure_if_new($post_ID, $thisEnclosure);
  5852 		$this->add_enclosure_if_new( $post_ID, $thisEnclosure );
  5538 
  5853 
  5539 		$this->attach_uploads( $ID, $post_content );
  5854 		$this->attach_uploads( $ID, $post_content );
  5540 
  5855 
  5541 		// Handle post formats if assigned, validation is handled earlier in this function.
  5856 		// Handle post formats if assigned, validation is handled earlier in this function.
  5542 		if ( isset( $content_struct['wp_post_format'] ) )
  5857 		if ( isset( $content_struct['wp_post_format'] ) ) {
  5543 			set_post_format( $post_ID, $content_struct['wp_post_format'] );
  5858 			set_post_format( $post_ID, $content_struct['wp_post_format'] );
       
  5859 		}
  5544 
  5860 
  5545 		/**
  5861 		/**
  5546 		 * Fires after a post has been successfully updated via the XML-RPC MovableType API.
  5862 		 * Fires after a post has been successfully updated via the XML-RPC MovableType API.
  5547 		 *
  5863 		 *
  5548 		 * @since 3.4.0
  5864 		 * @since 3.4.0
  5575 
  5891 
  5576 		$post_ID  = (int) $args[0];
  5892 		$post_ID  = (int) $args[0];
  5577 		$username = $args[1];
  5893 		$username = $args[1];
  5578 		$password = $args[2];
  5894 		$password = $args[2];
  5579 
  5895 
  5580 		if ( !$user = $this->login($username, $password) )
  5896 		if ( ! $user = $this->login( $username, $password ) ) {
  5581 			return $this->error;
  5897 			return $this->error;
  5582 
  5898 		}
  5583 		$postdata = get_post($post_ID, ARRAY_A);
  5899 
  5584 		if ( ! $postdata )
  5900 		$postdata = get_post( $post_ID, ARRAY_A );
       
  5901 		if ( ! $postdata ) {
  5585 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  5902 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  5586 
  5903 		}
  5587 		if ( !current_user_can( 'edit_post', $post_ID ) )
  5904 
       
  5905 		if ( ! current_user_can( 'edit_post', $post_ID ) ) {
  5588 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit this post.' ) );
  5906 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit this post.' ) );
       
  5907 		}
  5589 
  5908 
  5590 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  5909 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  5591 		do_action( 'xmlrpc_call', 'metaWeblog.getPost' );
  5910 		do_action( 'xmlrpc_call', 'metaWeblog.getPost' );
  5592 
  5911 
  5593 		if ($postdata['post_date'] != '') {
  5912 		if ( $postdata['post_date'] != '' ) {
  5594 			$post_date = $this->_convert_date( $postdata['post_date'] );
  5913 			$post_date         = $this->_convert_date( $postdata['post_date'] );
  5595 			$post_date_gmt = $this->_convert_date_gmt( $postdata['post_date_gmt'],  $postdata['post_date'] );
  5914 			$post_date_gmt     = $this->_convert_date_gmt( $postdata['post_date_gmt'], $postdata['post_date'] );
  5596 			$post_modified = $this->_convert_date( $postdata['post_modified'] );
  5915 			$post_modified     = $this->_convert_date( $postdata['post_modified'] );
  5597 			$post_modified_gmt = $this->_convert_date_gmt( $postdata['post_modified_gmt'], $postdata['post_modified'] );
  5916 			$post_modified_gmt = $this->_convert_date_gmt( $postdata['post_modified_gmt'], $postdata['post_modified'] );
  5598 
  5917 
  5599 			$categories = array();
  5918 			$categories = array();
  5600 			$catids = wp_get_post_categories($post_ID);
  5919 			$catids     = wp_get_post_categories( $post_ID );
  5601 			foreach ($catids as $catid)
  5920 			foreach ( $catids as $catid ) {
  5602 				$categories[] = get_cat_name($catid);
  5921 				$categories[] = get_cat_name( $catid );
       
  5922 			}
  5603 
  5923 
  5604 			$tagnames = array();
  5924 			$tagnames = array();
  5605 			$tags = wp_get_post_tags( $post_ID );
  5925 			$tags     = wp_get_post_tags( $post_ID );
  5606 			if ( !empty( $tags ) ) {
  5926 			if ( ! empty( $tags ) ) {
  5607 				foreach ( $tags as $tag )
  5927 				foreach ( $tags as $tag ) {
  5608 					$tagnames[] = $tag->name;
  5928 					$tagnames[] = $tag->name;
       
  5929 				}
  5609 				$tagnames = implode( ', ', $tagnames );
  5930 				$tagnames = implode( ', ', $tagnames );
  5610 			} else {
  5931 			} else {
  5611 				$tagnames = '';
  5932 				$tagnames = '';
  5612 			}
  5933 			}
  5613 
  5934 
  5614 			$post = get_extended($postdata['post_content']);
  5935 			$post = get_extended( $postdata['post_content'] );
  5615 			$link = get_permalink($postdata['ID']);
  5936 			$link = get_permalink( $postdata['ID'] );
  5616 
  5937 
  5617 			// Get the author info.
  5938 			// Get the author info.
  5618 			$author = get_userdata($postdata['post_author']);
  5939 			$author = get_userdata( $postdata['post_author'] );
  5619 
  5940 
  5620 			$allow_comments = ('open' == $postdata['comment_status']) ? 1 : 0;
  5941 			$allow_comments = ( 'open' == $postdata['comment_status'] ) ? 1 : 0;
  5621 			$allow_pings = ('open' == $postdata['ping_status']) ? 1 : 0;
  5942 			$allow_pings    = ( 'open' == $postdata['ping_status'] ) ? 1 : 0;
  5622 
  5943 
  5623 			// Consider future posts as published
  5944 			// Consider future posts as published
  5624 			if ( $postdata['post_status'] === 'future' )
  5945 			if ( $postdata['post_status'] === 'future' ) {
  5625 				$postdata['post_status'] = 'publish';
  5946 				$postdata['post_status'] = 'publish';
       
  5947 			}
  5626 
  5948 
  5627 			// Get post format
  5949 			// Get post format
  5628 			$post_format = get_post_format( $post_ID );
  5950 			$post_format = get_post_format( $post_ID );
  5629 			if ( empty( $post_format ) )
  5951 			if ( empty( $post_format ) ) {
  5630 				$post_format = 'standard';
  5952 				$post_format = 'standard';
       
  5953 			}
  5631 
  5954 
  5632 			$sticky = false;
  5955 			$sticky = false;
  5633 			if ( is_sticky( $post_ID ) )
  5956 			if ( is_sticky( $post_ID ) ) {
  5634 				$sticky = true;
  5957 				$sticky = true;
       
  5958 			}
  5635 
  5959 
  5636 			$enclosure = array();
  5960 			$enclosure = array();
  5637 			foreach ( (array) get_post_custom($post_ID) as $key => $val) {
  5961 			foreach ( (array) get_post_custom( $post_ID ) as $key => $val ) {
  5638 				if ($key == 'enclosure') {
  5962 				if ( $key == 'enclosure' ) {
  5639 					foreach ( (array) $val as $enc ) {
  5963 					foreach ( (array) $val as $enc ) {
  5640 						$encdata = explode("\n", $enc);
  5964 						$encdata             = explode( "\n", $enc );
  5641 						$enclosure['url'] = trim(htmlspecialchars($encdata[0]));
  5965 						$enclosure['url']    = trim( htmlspecialchars( $encdata[0] ) );
  5642 						$enclosure['length'] = (int) trim($encdata[1]);
  5966 						$enclosure['length'] = (int) trim( $encdata[1] );
  5643 						$enclosure['type'] = trim($encdata[2]);
  5967 						$enclosure['type']   = trim( $encdata[2] );
  5644 						break 2;
  5968 						break 2;
  5645 					}
  5969 					}
  5646 				}
  5970 				}
  5647 			}
  5971 			}
  5648 
  5972 
  5649 			$resp = array(
  5973 			$resp = array(
  5650 				'dateCreated' => $post_date,
  5974 				'dateCreated'            => $post_date,
  5651 				'userid' => $postdata['post_author'],
  5975 				'userid'                 => $postdata['post_author'],
  5652 				'postid' => $postdata['ID'],
  5976 				'postid'                 => $postdata['ID'],
  5653 				'description' => $post['main'],
  5977 				'description'            => $post['main'],
  5654 				'title' => $postdata['post_title'],
  5978 				'title'                  => $postdata['post_title'],
  5655 				'link' => $link,
  5979 				'link'                   => $link,
  5656 				'permaLink' => $link,
  5980 				'permaLink'              => $link,
  5657 				// commented out because no other tool seems to use this
  5981 				// commented out because no other tool seems to use this
  5658 				//	      'content' => $entry['post_content'],
  5982 				//	      'content' => $entry['post_content'],
  5659 				'categories' => $categories,
  5983 				'categories'             => $categories,
  5660 				'mt_excerpt' => $postdata['post_excerpt'],
  5984 				'mt_excerpt'             => $postdata['post_excerpt'],
  5661 				'mt_text_more' => $post['extended'],
  5985 				'mt_text_more'           => $post['extended'],
  5662 				'wp_more_text' => $post['more_text'],
  5986 				'wp_more_text'           => $post['more_text'],
  5663 				'mt_allow_comments' => $allow_comments,
  5987 				'mt_allow_comments'      => $allow_comments,
  5664 				'mt_allow_pings' => $allow_pings,
  5988 				'mt_allow_pings'         => $allow_pings,
  5665 				'mt_keywords' => $tagnames,
  5989 				'mt_keywords'            => $tagnames,
  5666 				'wp_slug' => $postdata['post_name'],
  5990 				'wp_slug'                => $postdata['post_name'],
  5667 				'wp_password' => $postdata['post_password'],
  5991 				'wp_password'            => $postdata['post_password'],
  5668 				'wp_author_id' => (string) $author->ID,
  5992 				'wp_author_id'           => (string) $author->ID,
  5669 				'wp_author_display_name' => $author->display_name,
  5993 				'wp_author_display_name' => $author->display_name,
  5670 				'date_created_gmt' => $post_date_gmt,
  5994 				'date_created_gmt'       => $post_date_gmt,
  5671 				'post_status' => $postdata['post_status'],
  5995 				'post_status'            => $postdata['post_status'],
  5672 				'custom_fields' => $this->get_custom_fields($post_ID),
  5996 				'custom_fields'          => $this->get_custom_fields( $post_ID ),
  5673 				'wp_post_format' => $post_format,
  5997 				'wp_post_format'         => $post_format,
  5674 				'sticky' => $sticky,
  5998 				'sticky'                 => $sticky,
  5675 				'date_modified' => $post_modified,
  5999 				'date_modified'          => $post_modified,
  5676 				'date_modified_gmt' => $post_modified_gmt
  6000 				'date_modified_gmt'      => $post_modified_gmt,
  5677 			);
  6001 			);
  5678 
  6002 
  5679 			if ( !empty($enclosure) ) $resp['enclosure'] = $enclosure;
  6003 			if ( ! empty( $enclosure ) ) {
       
  6004 				$resp['enclosure'] = $enclosure;
       
  6005 			}
  5680 
  6006 
  5681 			$resp['wp_post_thumbnail'] = get_post_thumbnail_id( $postdata['ID'] );
  6007 			$resp['wp_post_thumbnail'] = get_post_thumbnail_id( $postdata['ID'] );
  5682 
  6008 
  5683 			return $resp;
  6009 			return $resp;
  5684 		} else {
  6010 		} else {
  5685 			return new IXR_Error(404, __('Sorry, no such post.'));
  6011 			return new IXR_Error( 404, __( 'Sorry, no such post.' ) );
  5686 		}
  6012 		}
  5687 	}
  6013 	}
  5688 
  6014 
  5689 	/**
  6015 	/**
  5690 	 * Retrieve list of recent posts.
  6016 	 * Retrieve list of recent posts.
  5704 	public function mw_getRecentPosts( $args ) {
  6030 	public function mw_getRecentPosts( $args ) {
  5705 		$this->escape( $args );
  6031 		$this->escape( $args );
  5706 
  6032 
  5707 		$username = $args[1];
  6033 		$username = $args[1];
  5708 		$password = $args[2];
  6034 		$password = $args[2];
  5709 		if ( isset( $args[3] ) )
  6035 		if ( isset( $args[3] ) ) {
  5710 			$query = array( 'numberposts' => absint( $args[3] ) );
  6036 			$query = array( 'numberposts' => absint( $args[3] ) );
  5711 		else
  6037 		} else {
  5712 			$query = array();
  6038 			$query = array();
  5713 
  6039 		}
  5714 		if ( !$user = $this->login($username, $password) )
  6040 
  5715 			return $this->error;
  6041 		if ( ! $user = $this->login( $username, $password ) ) {
  5716 
  6042 			return $this->error;
  5717 		if ( ! current_user_can( 'edit_posts' ) )
  6043 		}
       
  6044 
       
  6045 		if ( ! current_user_can( 'edit_posts' ) ) {
  5718 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit posts.' ) );
  6046 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit posts.' ) );
       
  6047 		}
  5719 
  6048 
  5720 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  6049 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  5721 		do_action( 'xmlrpc_call', 'metaWeblog.getRecentPosts' );
  6050 		do_action( 'xmlrpc_call', 'metaWeblog.getRecentPosts' );
  5722 
  6051 
  5723 		$posts_list = wp_get_recent_posts( $query );
  6052 		$posts_list = wp_get_recent_posts( $query );
  5724 
  6053 
  5725 		if ( !$posts_list )
  6054 		if ( ! $posts_list ) {
  5726 			return array();
  6055 			return array();
       
  6056 		}
  5727 
  6057 
  5728 		$recent_posts = array();
  6058 		$recent_posts = array();
  5729 		foreach ($posts_list as $entry) {
  6059 		foreach ( $posts_list as $entry ) {
  5730 			if ( !current_user_can( 'edit_post', $entry['ID'] ) )
  6060 			if ( ! current_user_can( 'edit_post', $entry['ID'] ) ) {
  5731 				continue;
  6061 				continue;
  5732 
  6062 			}
  5733 			$post_date = $this->_convert_date( $entry['post_date'] );
  6063 
  5734 			$post_date_gmt = $this->_convert_date_gmt( $entry['post_date_gmt'], $entry['post_date'] );
  6064 			$post_date         = $this->_convert_date( $entry['post_date'] );
  5735 			$post_modified = $this->_convert_date( $entry['post_modified'] );
  6065 			$post_date_gmt     = $this->_convert_date_gmt( $entry['post_date_gmt'], $entry['post_date'] );
       
  6066 			$post_modified     = $this->_convert_date( $entry['post_modified'] );
  5736 			$post_modified_gmt = $this->_convert_date_gmt( $entry['post_modified_gmt'], $entry['post_modified'] );
  6067 			$post_modified_gmt = $this->_convert_date_gmt( $entry['post_modified_gmt'], $entry['post_modified'] );
  5737 
  6068 
  5738 			$categories = array();
  6069 			$categories = array();
  5739 			$catids = wp_get_post_categories($entry['ID']);
  6070 			$catids     = wp_get_post_categories( $entry['ID'] );
  5740 			foreach ( $catids as $catid )
  6071 			foreach ( $catids as $catid ) {
  5741 				$categories[] = get_cat_name($catid);
  6072 				$categories[] = get_cat_name( $catid );
       
  6073 			}
  5742 
  6074 
  5743 			$tagnames = array();
  6075 			$tagnames = array();
  5744 			$tags = wp_get_post_tags( $entry['ID'] );
  6076 			$tags     = wp_get_post_tags( $entry['ID'] );
  5745 			if ( !empty( $tags ) ) {
  6077 			if ( ! empty( $tags ) ) {
  5746 				foreach ( $tags as $tag ) {
  6078 				foreach ( $tags as $tag ) {
  5747 					$tagnames[] = $tag->name;
  6079 					$tagnames[] = $tag->name;
  5748 				}
  6080 				}
  5749 				$tagnames = implode( ', ', $tagnames );
  6081 				$tagnames = implode( ', ', $tagnames );
  5750 			} else {
  6082 			} else {
  5751 				$tagnames = '';
  6083 				$tagnames = '';
  5752 			}
  6084 			}
  5753 
  6085 
  5754 			$post = get_extended($entry['post_content']);
  6086 			$post = get_extended( $entry['post_content'] );
  5755 			$link = get_permalink($entry['ID']);
  6087 			$link = get_permalink( $entry['ID'] );
  5756 
  6088 
  5757 			// Get the post author info.
  6089 			// Get the post author info.
  5758 			$author = get_userdata($entry['post_author']);
  6090 			$author = get_userdata( $entry['post_author'] );
  5759 
  6091 
  5760 			$allow_comments = ('open' == $entry['comment_status']) ? 1 : 0;
  6092 			$allow_comments = ( 'open' == $entry['comment_status'] ) ? 1 : 0;
  5761 			$allow_pings = ('open' == $entry['ping_status']) ? 1 : 0;
  6093 			$allow_pings    = ( 'open' == $entry['ping_status'] ) ? 1 : 0;
  5762 
  6094 
  5763 			// Consider future posts as published
  6095 			// Consider future posts as published
  5764 			if ( $entry['post_status'] === 'future' )
  6096 			if ( $entry['post_status'] === 'future' ) {
  5765 				$entry['post_status'] = 'publish';
  6097 				$entry['post_status'] = 'publish';
       
  6098 			}
  5766 
  6099 
  5767 			// Get post format
  6100 			// Get post format
  5768 			$post_format = get_post_format( $entry['ID'] );
  6101 			$post_format = get_post_format( $entry['ID'] );
  5769 			if ( empty( $post_format ) )
  6102 			if ( empty( $post_format ) ) {
  5770 				$post_format = 'standard';
  6103 				$post_format = 'standard';
       
  6104 			}
  5771 
  6105 
  5772 			$recent_posts[] = array(
  6106 			$recent_posts[] = array(
  5773 				'dateCreated' => $post_date,
  6107 				'dateCreated'            => $post_date,
  5774 				'userid' => $entry['post_author'],
  6108 				'userid'                 => $entry['post_author'],
  5775 				'postid' => (string) $entry['ID'],
  6109 				'postid'                 => (string) $entry['ID'],
  5776 				'description' => $post['main'],
  6110 				'description'            => $post['main'],
  5777 				'title' => $entry['post_title'],
  6111 				'title'                  => $entry['post_title'],
  5778 				'link' => $link,
  6112 				'link'                   => $link,
  5779 				'permaLink' => $link,
  6113 				'permaLink'              => $link,
  5780 				// commented out because no other tool seems to use this
  6114 				// commented out because no other tool seems to use this
  5781 				// 'content' => $entry['post_content'],
  6115 				// 'content' => $entry['post_content'],
  5782 				'categories' => $categories,
  6116 				'categories'             => $categories,
  5783 				'mt_excerpt' => $entry['post_excerpt'],
  6117 				'mt_excerpt'             => $entry['post_excerpt'],
  5784 				'mt_text_more' => $post['extended'],
  6118 				'mt_text_more'           => $post['extended'],
  5785 				'wp_more_text' => $post['more_text'],
  6119 				'wp_more_text'           => $post['more_text'],
  5786 				'mt_allow_comments' => $allow_comments,
  6120 				'mt_allow_comments'      => $allow_comments,
  5787 				'mt_allow_pings' => $allow_pings,
  6121 				'mt_allow_pings'         => $allow_pings,
  5788 				'mt_keywords' => $tagnames,
  6122 				'mt_keywords'            => $tagnames,
  5789 				'wp_slug' => $entry['post_name'],
  6123 				'wp_slug'                => $entry['post_name'],
  5790 				'wp_password' => $entry['post_password'],
  6124 				'wp_password'            => $entry['post_password'],
  5791 				'wp_author_id' => (string) $author->ID,
  6125 				'wp_author_id'           => (string) $author->ID,
  5792 				'wp_author_display_name' => $author->display_name,
  6126 				'wp_author_display_name' => $author->display_name,
  5793 				'date_created_gmt' => $post_date_gmt,
  6127 				'date_created_gmt'       => $post_date_gmt,
  5794 				'post_status' => $entry['post_status'],
  6128 				'post_status'            => $entry['post_status'],
  5795 				'custom_fields' => $this->get_custom_fields($entry['ID']),
  6129 				'custom_fields'          => $this->get_custom_fields( $entry['ID'] ),
  5796 				'wp_post_format' => $post_format,
  6130 				'wp_post_format'         => $post_format,
  5797 				'date_modified' => $post_modified,
  6131 				'date_modified'          => $post_modified,
  5798 				'date_modified_gmt' => $post_modified_gmt,
  6132 				'date_modified_gmt'      => $post_modified_gmt,
  5799 				'sticky' => ( $entry['post_type'] === 'post' && is_sticky( $entry['ID'] ) ),
  6133 				'sticky'                 => ( $entry['post_type'] === 'post' && is_sticky( $entry['ID'] ) ),
  5800 				'wp_post_thumbnail' => get_post_thumbnail_id( $entry['ID'] )
  6134 				'wp_post_thumbnail'      => get_post_thumbnail_id( $entry['ID'] ),
  5801 			);
  6135 			);
  5802 		}
  6136 		}
  5803 
  6137 
  5804 		return $recent_posts;
  6138 		return $recent_posts;
  5805 	}
  6139 	}
  5822 		$this->escape( $args );
  6156 		$this->escape( $args );
  5823 
  6157 
  5824 		$username = $args[1];
  6158 		$username = $args[1];
  5825 		$password = $args[2];
  6159 		$password = $args[2];
  5826 
  6160 
  5827 		if ( !$user = $this->login($username, $password) )
  6161 		if ( ! $user = $this->login( $username, $password ) ) {
  5828 			return $this->error;
  6162 			return $this->error;
  5829 
  6163 		}
  5830 		if ( !current_user_can( 'edit_posts' ) )
  6164 
       
  6165 		if ( ! current_user_can( 'edit_posts' ) ) {
  5831 			return new IXR_Error( 401, __( 'Sorry, you must be able to edit posts on this site in order to view categories.' ) );
  6166 			return new IXR_Error( 401, __( 'Sorry, you must be able to edit posts on this site in order to view categories.' ) );
       
  6167 		}
  5832 
  6168 
  5833 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  6169 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  5834 		do_action( 'xmlrpc_call', 'metaWeblog.getCategories' );
  6170 		do_action( 'xmlrpc_call', 'metaWeblog.getCategories' );
  5835 
  6171 
  5836 		$categories_struct = array();
  6172 		$categories_struct = array();
  5837 
  6173 
  5838 		if ( $cats = get_categories(array('get' => 'all')) ) {
  6174 		if ( $cats = get_categories( array( 'get' => 'all' ) ) ) {
  5839 			foreach ( $cats as $cat ) {
  6175 			foreach ( $cats as $cat ) {
  5840 				$struct = array();
  6176 				$struct                        = array();
  5841 				$struct['categoryId'] = $cat->term_id;
  6177 				$struct['categoryId']          = $cat->term_id;
  5842 				$struct['parentId'] = $cat->parent;
  6178 				$struct['parentId']            = $cat->parent;
  5843 				$struct['description'] = $cat->name;
  6179 				$struct['description']         = $cat->name;
  5844 				$struct['categoryDescription'] = $cat->description;
  6180 				$struct['categoryDescription'] = $cat->description;
  5845 				$struct['categoryName'] = $cat->name;
  6181 				$struct['categoryName']        = $cat->name;
  5846 				$struct['htmlUrl'] = esc_html(get_category_link($cat->term_id));
  6182 				$struct['htmlUrl']             = esc_html( get_category_link( $cat->term_id ) );
  5847 				$struct['rssUrl'] = esc_html(get_category_feed_link($cat->term_id, 'rss2'));
  6183 				$struct['rssUrl']              = esc_html( get_category_feed_link( $cat->term_id, 'rss2' ) );
  5848 
  6184 
  5849 				$categories_struct[] = $struct;
  6185 				$categories_struct[] = $struct;
  5850 			}
  6186 			}
  5851 		}
  6187 		}
  5852 
  6188 
  5883 
  6219 
  5884 		$name = sanitize_file_name( $data['name'] );
  6220 		$name = sanitize_file_name( $data['name'] );
  5885 		$type = $data['type'];
  6221 		$type = $data['type'];
  5886 		$bits = $data['bits'];
  6222 		$bits = $data['bits'];
  5887 
  6223 
  5888 		if ( !$user = $this->login($username, $password) )
  6224 		if ( ! $user = $this->login( $username, $password ) ) {
  5889 			return $this->error;
  6225 			return $this->error;
       
  6226 		}
  5890 
  6227 
  5891 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  6228 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  5892 		do_action( 'xmlrpc_call', 'metaWeblog.newMediaObject' );
  6229 		do_action( 'xmlrpc_call', 'metaWeblog.newMediaObject' );
  5893 
  6230 
  5894 		if ( !current_user_can('upload_files') ) {
  6231 		if ( ! current_user_can( 'upload_files' ) ) {
  5895 			$this->error = new IXR_Error( 401, __( 'Sorry, you are not allowed to upload files.' ) );
  6232 			$this->error = new IXR_Error( 401, __( 'Sorry, you are not allowed to upload files.' ) );
  5896 			return $this->error;
  6233 			return $this->error;
  5897 		}
  6234 		}
  5898 
  6235 
  5899 		if ( is_multisite() && upload_is_user_over_quota( false ) ) {
  6236 		if ( is_multisite() && upload_is_user_over_quota( false ) ) {
  5900 			$this->error = new IXR_Error( 401, __( 'Sorry, you have used your space allocation.' ) );
  6237 			$this->error = new IXR_Error(
       
  6238 				401,
       
  6239 				sprintf(
       
  6240 					/* translators: %s: allowed space allocation */
       
  6241 					__( 'Sorry, you have used your space allocation of %s. Please delete some files to upload more files.' ),
       
  6242 					size_format( get_space_allowed() * MB_IN_BYTES )
       
  6243 				)
       
  6244 			);
  5901 			return $this->error;
  6245 			return $this->error;
  5902 		}
  6246 		}
  5903 
  6247 
  5904 		/**
  6248 		/**
  5905 		 * Filters whether to preempt the XML-RPC media upload.
  6249 		 * Filters whether to preempt the XML-RPC media upload.
  5913 		 */
  6257 		 */
  5914 		if ( $upload_err = apply_filters( 'pre_upload_error', false ) ) {
  6258 		if ( $upload_err = apply_filters( 'pre_upload_error', false ) ) {
  5915 			return new IXR_Error( 500, $upload_err );
  6259 			return new IXR_Error( 500, $upload_err );
  5916 		}
  6260 		}
  5917 
  6261 
  5918 		$upload = wp_upload_bits($name, null, $bits);
  6262 		$upload = wp_upload_bits( $name, null, $bits );
  5919 		if ( ! empty($upload['error']) ) {
  6263 		if ( ! empty( $upload['error'] ) ) {
  5920 			/* translators: 1: file name, 2: error message */
  6264 			/* translators: 1: file name, 2: error message */
  5921 			$errorString = sprintf( __( 'Could not write file %1$s (%2$s).' ), $name, $upload['error'] );
  6265 			$errorString = sprintf( __( 'Could not write file %1$s (%2$s).' ), $name, $upload['error'] );
  5922 			return new IXR_Error( 500, $errorString );
  6266 			return new IXR_Error( 500, $errorString );
  5923 		}
  6267 		}
  5924 		// Construct the attachment array
  6268 		// Construct the attachment array
  5925 		$post_id = 0;
  6269 		$post_id = 0;
  5926 		if ( ! empty( $data['post_id'] ) ) {
  6270 		if ( ! empty( $data['post_id'] ) ) {
  5927 			$post_id = (int) $data['post_id'];
  6271 			$post_id = (int) $data['post_id'];
  5928 
  6272 
  5929 			if ( ! current_user_can( 'edit_post', $post_id ) )
  6273 			if ( ! current_user_can( 'edit_post', $post_id ) ) {
  5930 				return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit this post.' ) );
  6274 				return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit this post.' ) );
       
  6275 			}
  5931 		}
  6276 		}
  5932 		$attachment = array(
  6277 		$attachment = array(
  5933 			'post_title' => $name,
  6278 			'post_title'     => $name,
  5934 			'post_content' => '',
  6279 			'post_content'   => '',
  5935 			'post_type' => 'attachment',
  6280 			'post_type'      => 'attachment',
  5936 			'post_parent' => $post_id,
  6281 			'post_parent'    => $post_id,
  5937 			'post_mime_type' => $type,
  6282 			'post_mime_type' => $type,
  5938 			'guid' => $upload[ 'url' ]
  6283 			'guid'           => $upload['url'],
  5939 		);
  6284 		);
  5940 
  6285 
  5941 		// Save the data
  6286 		// Save the data
  5942 		$id = wp_insert_attachment( $attachment, $upload[ 'file' ], $post_id );
  6287 		$id = wp_insert_attachment( $attachment, $upload['file'], $post_id );
  5943 		wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $upload['file'] ) );
  6288 		wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $upload['file'] ) );
  5944 
  6289 
  5945 		/**
  6290 		/**
  5946 		 * Fires after a new attachment has been added via the XML-RPC MovableType API.
  6291 		 * Fires after a new attachment has been added via the XML-RPC MovableType API.
  5947 		 *
  6292 		 *
  5984 	public function mt_getRecentPostTitles( $args ) {
  6329 	public function mt_getRecentPostTitles( $args ) {
  5985 		$this->escape( $args );
  6330 		$this->escape( $args );
  5986 
  6331 
  5987 		$username = $args[1];
  6332 		$username = $args[1];
  5988 		$password = $args[2];
  6333 		$password = $args[2];
  5989 		if ( isset( $args[3] ) )
  6334 		if ( isset( $args[3] ) ) {
  5990 			$query = array( 'numberposts' => absint( $args[3] ) );
  6335 			$query = array( 'numberposts' => absint( $args[3] ) );
  5991 		else
  6336 		} else {
  5992 			$query = array();
  6337 			$query = array();
  5993 
  6338 		}
  5994 		if ( !$user = $this->login($username, $password) )
  6339 
  5995 			return $this->error;
  6340 		if ( ! $user = $this->login( $username, $password ) ) {
       
  6341 			return $this->error;
       
  6342 		}
  5996 
  6343 
  5997 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  6344 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  5998 		do_action( 'xmlrpc_call', 'mt.getRecentPostTitles' );
  6345 		do_action( 'xmlrpc_call', 'mt.getRecentPostTitles' );
  5999 
  6346 
  6000 		$posts_list = wp_get_recent_posts( $query );
  6347 		$posts_list = wp_get_recent_posts( $query );
  6001 
  6348 
  6002 		if ( !$posts_list ) {
  6349 		if ( ! $posts_list ) {
  6003 			$this->error = new IXR_Error(500, __('Either there are no posts, or something went wrong.'));
  6350 			$this->error = new IXR_Error( 500, __( 'Either there are no posts, or something went wrong.' ) );
  6004 			return $this->error;
  6351 			return $this->error;
  6005 		}
  6352 		}
  6006 
  6353 
  6007 		$recent_posts = array();
  6354 		$recent_posts = array();
  6008 
  6355 
  6009 		foreach ($posts_list as $entry) {
  6356 		foreach ( $posts_list as $entry ) {
  6010 			if ( !current_user_can( 'edit_post', $entry['ID'] ) )
  6357 			if ( ! current_user_can( 'edit_post', $entry['ID'] ) ) {
  6011 				continue;
  6358 				continue;
  6012 
  6359 			}
  6013 			$post_date = $this->_convert_date( $entry['post_date'] );
  6360 
       
  6361 			$post_date     = $this->_convert_date( $entry['post_date'] );
  6014 			$post_date_gmt = $this->_convert_date_gmt( $entry['post_date_gmt'], $entry['post_date'] );
  6362 			$post_date_gmt = $this->_convert_date_gmt( $entry['post_date_gmt'], $entry['post_date'] );
  6015 
  6363 
  6016 			$recent_posts[] = array(
  6364 			$recent_posts[] = array(
  6017 				'dateCreated' => $post_date,
  6365 				'dateCreated'      => $post_date,
  6018 				'userid' => $entry['post_author'],
  6366 				'userid'           => $entry['post_author'],
  6019 				'postid' => (string) $entry['ID'],
  6367 				'postid'           => (string) $entry['ID'],
  6020 				'title' => $entry['post_title'],
  6368 				'title'            => $entry['post_title'],
  6021 				'post_status' => $entry['post_status'],
  6369 				'post_status'      => $entry['post_status'],
  6022 				'date_created_gmt' => $post_date_gmt
  6370 				'date_created_gmt' => $post_date_gmt,
  6023 			);
  6371 			);
  6024 		}
  6372 		}
  6025 
  6373 
  6026 		return $recent_posts;
  6374 		return $recent_posts;
  6027 	}
  6375 	}
  6044 		$this->escape( $args );
  6392 		$this->escape( $args );
  6045 
  6393 
  6046 		$username = $args[1];
  6394 		$username = $args[1];
  6047 		$password = $args[2];
  6395 		$password = $args[2];
  6048 
  6396 
  6049 		if ( !$user = $this->login($username, $password) )
  6397 		if ( ! $user = $this->login( $username, $password ) ) {
  6050 			return $this->error;
  6398 			return $this->error;
  6051 
  6399 		}
  6052 		if ( !current_user_can( 'edit_posts' ) )
  6400 
       
  6401 		if ( ! current_user_can( 'edit_posts' ) ) {
  6053 			return new IXR_Error( 401, __( 'Sorry, you must be able to edit posts on this site in order to view categories.' ) );
  6402 			return new IXR_Error( 401, __( 'Sorry, you must be able to edit posts on this site in order to view categories.' ) );
       
  6403 		}
  6054 
  6404 
  6055 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  6405 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  6056 		do_action( 'xmlrpc_call', 'mt.getCategoryList' );
  6406 		do_action( 'xmlrpc_call', 'mt.getCategoryList' );
  6057 
  6407 
  6058 		$categories_struct = array();
  6408 		$categories_struct = array();
  6059 
  6409 
  6060 		if ( $cats = get_categories(array('hide_empty' => 0, 'hierarchical' => 0)) ) {
  6410 		if ( $cats = get_categories(
       
  6411 			array(
       
  6412 				'hide_empty'   => 0,
       
  6413 				'hierarchical' => 0,
       
  6414 			)
       
  6415 		) ) {
  6061 			foreach ( $cats as $cat ) {
  6416 			foreach ( $cats as $cat ) {
  6062 				$struct = array();
  6417 				$struct                 = array();
  6063 				$struct['categoryId'] = $cat->term_id;
  6418 				$struct['categoryId']   = $cat->term_id;
  6064 				$struct['categoryName'] = $cat->name;
  6419 				$struct['categoryName'] = $cat->name;
  6065 
  6420 
  6066 				$categories_struct[] = $struct;
  6421 				$categories_struct[] = $struct;
  6067 			}
  6422 			}
  6068 		}
  6423 		}
  6089 
  6444 
  6090 		$post_ID  = (int) $args[0];
  6445 		$post_ID  = (int) $args[0];
  6091 		$username = $args[1];
  6446 		$username = $args[1];
  6092 		$password = $args[2];
  6447 		$password = $args[2];
  6093 
  6448 
  6094 		if ( !$user = $this->login($username, $password) )
  6449 		if ( ! $user = $this->login( $username, $password ) ) {
  6095 			return $this->error;
  6450 			return $this->error;
  6096 
  6451 		}
  6097 		if ( ! get_post( $post_ID ) )
  6452 
       
  6453 		if ( ! get_post( $post_ID ) ) {
  6098 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  6454 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  6099 
  6455 		}
  6100 		if ( !current_user_can( 'edit_post', $post_ID ) )
  6456 
       
  6457 		if ( ! current_user_can( 'edit_post', $post_ID ) ) {
  6101 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit this post.' ) );
  6458 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit this post.' ) );
       
  6459 		}
  6102 
  6460 
  6103 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  6461 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  6104 		do_action( 'xmlrpc_call', 'mt.getPostCategories' );
  6462 		do_action( 'xmlrpc_call', 'mt.getPostCategories' );
  6105 
  6463 
  6106 		$categories = array();
  6464 		$categories = array();
  6107 		$catids = wp_get_post_categories(intval($post_ID));
  6465 		$catids     = wp_get_post_categories( intval( $post_ID ) );
  6108 		// first listed category will be the primary category
  6466 		// first listed category will be the primary category
  6109 		$isPrimary = true;
  6467 		$isPrimary = true;
  6110 		foreach ( $catids as $catid ) {
  6468 		foreach ( $catids as $catid ) {
  6111 			$categories[] = array(
  6469 			$categories[] = array(
  6112 				'categoryName' => get_cat_name($catid),
  6470 				'categoryName' => get_cat_name( $catid ),
  6113 				'categoryId' => (string) $catid,
  6471 				'categoryId'   => (string) $catid,
  6114 				'isPrimary' => $isPrimary
  6472 				'isPrimary'    => $isPrimary,
  6115 			);
  6473 			);
  6116 			$isPrimary = false;
  6474 			$isPrimary    = false;
  6117 		}
  6475 		}
  6118 
  6476 
  6119 		return $categories;
  6477 		return $categories;
  6120 	}
  6478 	}
  6121 
  6479 
  6140 		$post_ID    = (int) $args[0];
  6498 		$post_ID    = (int) $args[0];
  6141 		$username   = $args[1];
  6499 		$username   = $args[1];
  6142 		$password   = $args[2];
  6500 		$password   = $args[2];
  6143 		$categories = $args[3];
  6501 		$categories = $args[3];
  6144 
  6502 
  6145 		if ( !$user = $this->login($username, $password) )
  6503 		if ( ! $user = $this->login( $username, $password ) ) {
  6146 			return $this->error;
  6504 			return $this->error;
       
  6505 		}
  6147 
  6506 
  6148 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  6507 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  6149 		do_action( 'xmlrpc_call', 'mt.setPostCategories' );
  6508 		do_action( 'xmlrpc_call', 'mt.setPostCategories' );
  6150 
  6509 
  6151 		if ( ! get_post( $post_ID ) )
  6510 		if ( ! get_post( $post_ID ) ) {
  6152 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  6511 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  6153 
  6512 		}
  6154 		if ( !current_user_can('edit_post', $post_ID) )
  6513 
  6155 			return new IXR_Error(401, __('Sorry, you are not allowed to edit this post.'));
  6514 		if ( ! current_user_can( 'edit_post', $post_ID ) ) {
       
  6515 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit this post.' ) );
       
  6516 		}
  6156 
  6517 
  6157 		$catids = array();
  6518 		$catids = array();
  6158 		foreach ( $categories as $cat ) {
  6519 		foreach ( $categories as $cat ) {
  6159 			$catids[] = $cat['categoryId'];
  6520 			$catids[] = $cat['categoryId'];
  6160 		}
  6521 		}
  6161 
  6522 
  6162 		wp_set_post_categories($post_ID, $catids);
  6523 		wp_set_post_categories( $post_ID, $catids );
  6163 
  6524 
  6164 		return true;
  6525 		return true;
  6165 	}
  6526 	}
  6166 
  6527 
  6167 	/**
  6528 	/**
  6211 		global $wpdb;
  6572 		global $wpdb;
  6212 
  6573 
  6213 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  6574 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  6214 		do_action( 'xmlrpc_call', 'mt.getTrackbackPings' );
  6575 		do_action( 'xmlrpc_call', 'mt.getTrackbackPings' );
  6215 
  6576 
  6216 		$actual_post = get_post($post_ID, ARRAY_A);
  6577 		$actual_post = get_post( $post_ID, ARRAY_A );
  6217 
  6578 
  6218 		if ( !$actual_post )
  6579 		if ( ! $actual_post ) {
  6219 			return new IXR_Error(404, __('Sorry, no such post.'));
  6580 			return new IXR_Error( 404, __( 'Sorry, no such post.' ) );
  6220 
  6581 		}
  6221 		$comments = $wpdb->get_results( $wpdb->prepare("SELECT comment_author_url, comment_content, comment_author_IP, comment_type FROM $wpdb->comments WHERE comment_post_ID = %d", $post_ID) );
  6582 
  6222 
  6583 		$comments = $wpdb->get_results( $wpdb->prepare( "SELECT comment_author_url, comment_content, comment_author_IP, comment_type FROM $wpdb->comments WHERE comment_post_ID = %d", $post_ID ) );
  6223 		if ( !$comments )
  6584 
       
  6585 		if ( ! $comments ) {
  6224 			return array();
  6586 			return array();
       
  6587 		}
  6225 
  6588 
  6226 		$trackback_pings = array();
  6589 		$trackback_pings = array();
  6227 		foreach ( $comments as $comment ) {
  6590 		foreach ( $comments as $comment ) {
  6228 			if ( 'trackback' == $comment->comment_type ) {
  6591 			if ( 'trackback' == $comment->comment_type ) {
  6229 				$content = $comment->comment_content;
  6592 				$content           = $comment->comment_content;
  6230 				$title = substr($content, 8, (strpos($content, '</strong>') - 8));
  6593 				$title             = substr( $content, 8, ( strpos( $content, '</strong>' ) - 8 ) );
  6231 				$trackback_pings[] = array(
  6594 				$trackback_pings[] = array(
  6232 					'pingTitle' => $title,
  6595 					'pingTitle' => $title,
  6233 					'pingURL'   => $comment->comment_author_url,
  6596 					'pingURL'   => $comment->comment_author_url,
  6234 					'pingIP'    => $comment->comment_author_IP
  6597 					'pingIP'    => $comment->comment_author_IP,
  6235 				);
  6598 				);
  6236 			}
  6599 			}
  6237 		}
  6600 		}
  6238 
  6601 
  6239 		return $trackback_pings;
  6602 		return $trackback_pings;
  6258 
  6621 
  6259 		$post_ID  = (int) $args[0];
  6622 		$post_ID  = (int) $args[0];
  6260 		$username = $args[1];
  6623 		$username = $args[1];
  6261 		$password = $args[2];
  6624 		$password = $args[2];
  6262 
  6625 
  6263 		if ( !$user = $this->login($username, $password) )
  6626 		if ( ! $user = $this->login( $username, $password ) ) {
  6264 			return $this->error;
  6627 			return $this->error;
       
  6628 		}
  6265 
  6629 
  6266 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  6630 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  6267 		do_action( 'xmlrpc_call', 'mt.publishPost' );
  6631 		do_action( 'xmlrpc_call', 'mt.publishPost' );
  6268 
  6632 
  6269 		$postdata = get_post($post_ID, ARRAY_A);
  6633 		$postdata = get_post( $post_ID, ARRAY_A );
  6270 		if ( ! $postdata )
  6634 		if ( ! $postdata ) {
  6271 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  6635 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  6272 
  6636 		}
  6273 		if ( !current_user_can('publish_posts') || !current_user_can('edit_post', $post_ID) )
  6637 
  6274 			return new IXR_Error(401, __('Sorry, you are not allowed to publish this post.'));
  6638 		if ( ! current_user_can( 'publish_posts' ) || ! current_user_can( 'edit_post', $post_ID ) ) {
       
  6639 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to publish this post.' ) );
       
  6640 		}
  6275 
  6641 
  6276 		$postdata['post_status'] = 'publish';
  6642 		$postdata['post_status'] = 'publish';
  6277 
  6643 
  6278 		// retain old cats
  6644 		// retain old cats
  6279 		$cats = wp_get_post_categories($post_ID);
  6645 		$cats                      = wp_get_post_categories( $post_ID );
  6280 		$postdata['post_category'] = $cats;
  6646 		$postdata['post_category'] = $cats;
  6281 		$this->escape($postdata);
  6647 		$this->escape( $postdata );
  6282 
  6648 
  6283 		return wp_update_post( $postdata );
  6649 		return wp_update_post( $postdata );
  6284 	}
  6650 	}
  6285 
  6651 
  6286 	/* PingBack functions
  6652 	/* PingBack functions
  6307 		do_action( 'xmlrpc_call', 'pingback.ping' );
  6673 		do_action( 'xmlrpc_call', 'pingback.ping' );
  6308 
  6674 
  6309 		$this->escape( $args );
  6675 		$this->escape( $args );
  6310 
  6676 
  6311 		$pagelinkedfrom = str_replace( '&amp;', '&', $args[0] );
  6677 		$pagelinkedfrom = str_replace( '&amp;', '&', $args[0] );
  6312 		$pagelinkedto = str_replace( '&amp;', '&', $args[1] );
  6678 		$pagelinkedto   = str_replace( '&amp;', '&', $args[1] );
  6313 		$pagelinkedto = str_replace( '&', '&amp;', $pagelinkedto );
  6679 		$pagelinkedto   = str_replace( '&', '&amp;', $pagelinkedto );
  6314 
  6680 
  6315 		/**
  6681 		/**
  6316 		 * Filters the pingback source URI.
  6682 		 * Filters the pingback source URI.
  6317 		 *
  6683 		 *
  6318 		 * @since 3.6.0
  6684 		 * @since 3.6.0
  6320 		 * @param string $pagelinkedfrom URI of the page linked from.
  6686 		 * @param string $pagelinkedfrom URI of the page linked from.
  6321 		 * @param string $pagelinkedto   URI of the page linked to.
  6687 		 * @param string $pagelinkedto   URI of the page linked to.
  6322 		 */
  6688 		 */
  6323 		$pagelinkedfrom = apply_filters( 'pingback_ping_source_uri', $pagelinkedfrom, $pagelinkedto );
  6689 		$pagelinkedfrom = apply_filters( 'pingback_ping_source_uri', $pagelinkedfrom, $pagelinkedto );
  6324 
  6690 
  6325 		if ( ! $pagelinkedfrom )
  6691 		if ( ! $pagelinkedfrom ) {
  6326 			return $this->pingback_error( 0, __( 'A valid URL was not provided.' ) );
  6692 			return $this->pingback_error( 0, __( 'A valid URL was not provided.' ) );
       
  6693 		}
  6327 
  6694 
  6328 		// Check if the page linked to is in our site
  6695 		// Check if the page linked to is in our site
  6329 		$pos1 = strpos($pagelinkedto, str_replace(array('http://www.','http://','https://www.','https://'), '', get_option('home')));
  6696 		$pos1 = strpos( $pagelinkedto, str_replace( array( 'http://www.', 'http://', 'https://www.', 'https://' ), '', get_option( 'home' ) ) );
  6330 		if ( !$pos1 )
  6697 		if ( ! $pos1 ) {
  6331 			return $this->pingback_error( 0, __( 'Is there no link to us?' ) );
  6698 			return $this->pingback_error( 0, __( 'Is there no link to us?' ) );
       
  6699 		}
  6332 
  6700 
  6333 		// let's find which post is linked to
  6701 		// let's find which post is linked to
  6334 		// FIXME: does url_to_postid() cover all these cases already?
  6702 		// FIXME: does url_to_postid() cover all these cases already?
  6335 		//        if so, then let's use it and drop the old code.
  6703 		//        if so, then let's use it and drop the old code.
  6336 		$urltest = parse_url($pagelinkedto);
  6704 		$urltest = parse_url( $pagelinkedto );
  6337 		if ( $post_ID = url_to_postid($pagelinkedto) ) {
  6705 		if ( $post_ID = url_to_postid( $pagelinkedto ) ) {
  6338 			// $way
  6706 			// $way
  6339 		} elseif ( isset( $urltest['path'] ) && preg_match('#p/[0-9]{1,}#', $urltest['path'], $match) ) {
  6707 		} elseif ( isset( $urltest['path'] ) && preg_match( '#p/[0-9]{1,}#', $urltest['path'], $match ) ) {
  6340 			// the path defines the post_ID (archives/p/XXXX)
  6708 			// the path defines the post_ID (archives/p/XXXX)
  6341 			$blah = explode('/', $match[0]);
  6709 			$blah    = explode( '/', $match[0] );
  6342 			$post_ID = (int) $blah[1];
  6710 			$post_ID = (int) $blah[1];
  6343 		} elseif ( isset( $urltest['query'] ) && preg_match('#p=[0-9]{1,}#', $urltest['query'], $match) ) {
  6711 		} elseif ( isset( $urltest['query'] ) && preg_match( '#p=[0-9]{1,}#', $urltest['query'], $match ) ) {
  6344 			// the querystring defines the post_ID (?p=XXXX)
  6712 			// the querystring defines the post_ID (?p=XXXX)
  6345 			$blah = explode('=', $match[0]);
  6713 			$blah    = explode( '=', $match[0] );
  6346 			$post_ID = (int) $blah[1];
  6714 			$post_ID = (int) $blah[1];
  6347 		} elseif ( isset($urltest['fragment']) ) {
  6715 		} elseif ( isset( $urltest['fragment'] ) ) {
  6348 			// an #anchor is there, it's either...
  6716 			// an #anchor is there, it's either...
  6349 			if ( intval($urltest['fragment']) ) {
  6717 			if ( intval( $urltest['fragment'] ) ) {
  6350 				// ...an integer #XXXX (simplest case)
  6718 				// ...an integer #XXXX (simplest case)
  6351 				$post_ID = (int) $urltest['fragment'];
  6719 				$post_ID = (int) $urltest['fragment'];
  6352 			} elseif ( preg_match('/post-[0-9]+/',$urltest['fragment']) ) {
  6720 			} elseif ( preg_match( '/post-[0-9]+/', $urltest['fragment'] ) ) {
  6353 				// ...a post id in the form 'post-###'
  6721 				// ...a post id in the form 'post-###'
  6354 				$post_ID = preg_replace('/[^0-9]+/', '', $urltest['fragment']);
  6722 				$post_ID = preg_replace( '/[^0-9]+/', '', $urltest['fragment'] );
  6355 			} elseif ( is_string($urltest['fragment']) ) {
  6723 			} elseif ( is_string( $urltest['fragment'] ) ) {
  6356 				// ...or a string #title, a little more complicated
  6724 				// ...or a string #title, a little more complicated
  6357 				$title = preg_replace('/[^a-z0-9]/i', '.', $urltest['fragment']);
  6725 				$title = preg_replace( '/[^a-z0-9]/i', '.', $urltest['fragment'] );
  6358 				$sql = $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE post_title RLIKE %s", $title );
  6726 				$sql   = $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_title RLIKE %s", $title );
  6359 				if (! ($post_ID = $wpdb->get_var($sql)) ) {
  6727 				if ( ! ( $post_ID = $wpdb->get_var( $sql ) ) ) {
  6360 					// returning unknown error '0' is better than die()ing
  6728 					// returning unknown error '0' is better than die()ing
  6361 			  		return $this->pingback_error( 0, '' );
  6729 					return $this->pingback_error( 0, '' );
  6362 				}
  6730 				}
  6363 			}
  6731 			}
  6364 		} else {
  6732 		} else {
  6365 			// TODO: Attempt to extract a post ID from the given URL
  6733 			// TODO: Attempt to extract a post ID from the given URL
  6366 	  		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.' ) );
  6734 			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.' ) );
  6367 		}
  6735 		}
  6368 		$post_ID = (int) $post_ID;
  6736 		$post_ID = (int) $post_ID;
  6369 
  6737 
  6370 		$post = get_post($post_ID);
  6738 		$post = get_post( $post_ID );
  6371 
  6739 
  6372 		if ( !$post ) // Post_ID not found
  6740 		if ( ! $post ) { // Post_ID not found
  6373 	  		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.' ) );
  6741 			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.' ) );
  6374 
  6742 		}
  6375 		if ( $post_ID == url_to_postid($pagelinkedfrom) )
  6743 
       
  6744 		if ( $post_ID == url_to_postid( $pagelinkedfrom ) ) {
  6376 			return $this->pingback_error( 0, __( 'The source URL and the target URL cannot both point to the same resource.' ) );
  6745 			return $this->pingback_error( 0, __( 'The source URL and the target URL cannot both point to the same resource.' ) );
       
  6746 		}
  6377 
  6747 
  6378 		// Check if pings are on
  6748 		// Check if pings are on
  6379 		if ( !pings_open($post) )
  6749 		if ( ! pings_open( $post ) ) {
  6380 	  		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.' ) );
  6750 			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.' ) );
       
  6751 		}
  6381 
  6752 
  6382 		// Let's check that the remote site didn't already pingback this entry
  6753 		// Let's check that the remote site didn't already pingback this entry
  6383 		if ( $wpdb->get_results( $wpdb->prepare("SELECT * FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_author_url = %s", $post_ID, $pagelinkedfrom) ) )
  6754 		if ( $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_author_url = %s", $post_ID, $pagelinkedfrom ) ) ) {
  6384 			return $this->pingback_error( 48, __( 'The pingback has already been registered.' ) );
  6755 			return $this->pingback_error( 48, __( 'The pingback has already been registered.' ) );
       
  6756 		}
  6385 
  6757 
  6386 		// very stupid, but gives time to the 'from' server to publish !
  6758 		// very stupid, but gives time to the 'from' server to publish !
  6387 		sleep(1);
  6759 		sleep( 1 );
  6388 
  6760 
  6389 		$remote_ip = preg_replace( '/[^0-9a-fA-F:., ]/', '', $_SERVER['REMOTE_ADDR'] );
  6761 		$remote_ip = preg_replace( '/[^0-9a-fA-F:., ]/', '', $_SERVER['REMOTE_ADDR'] );
  6390 
  6762 
  6391 		/** This filter is documented in wp-includes/class-http.php */
  6763 		/** This filter is documented in wp-includes/class-http.php */
  6392 		$user_agent = apply_filters( 'http_headers_useragent', 'WordPress/' . get_bloginfo( 'version' ) . '; ' . get_bloginfo( 'url' ) );
  6764 		$user_agent = apply_filters( 'http_headers_useragent', 'WordPress/' . get_bloginfo( 'version' ) . '; ' . get_bloginfo( 'url' ), $url );
  6393 
  6765 
  6394 		// Let's check the remote site
  6766 		// Let's check the remote site
  6395 		$http_api_args = array(
  6767 		$http_api_args = array(
  6396 			'timeout' => 10,
  6768 			'timeout'             => 10,
  6397 			'redirection' => 0,
  6769 			'redirection'         => 0,
  6398 			'limit_response_size' => 153600, // 150 KB
  6770 			'limit_response_size' => 153600, // 150 KB
  6399 			'user-agent' => "$user_agent; verifying pingback from $remote_ip",
  6771 			'user-agent'          => "$user_agent; verifying pingback from $remote_ip",
  6400 			'headers' => array(
  6772 			'headers'             => array(
  6401 				'X-Pingback-Forwarded-For' => $remote_ip,
  6773 				'X-Pingback-Forwarded-For' => $remote_ip,
  6402 			),
  6774 			),
  6403 		);
  6775 		);
  6404 
  6776 
  6405 		$request = wp_safe_remote_get( $pagelinkedfrom, $http_api_args );
  6777 		$request       = wp_safe_remote_get( $pagelinkedfrom, $http_api_args );
  6406 		$remote_source = $remote_source_original = wp_remote_retrieve_body( $request );
  6778 		$remote_source = $remote_source_original = wp_remote_retrieve_body( $request );
  6407 
  6779 
  6408 		if ( ! $remote_source ) {
  6780 		if ( ! $remote_source ) {
  6409 			return $this->pingback_error( 16, __( 'The source URL does not exist.' ) );
  6781 			return $this->pingback_error( 16, __( 'The source URL does not exist.' ) );
  6410 		}
  6782 		}
  6420 		$remote_source = apply_filters( 'pre_remote_source', $remote_source, $pagelinkedto );
  6792 		$remote_source = apply_filters( 'pre_remote_source', $remote_source, $pagelinkedto );
  6421 
  6793 
  6422 		// Work around bug in strip_tags():
  6794 		// Work around bug in strip_tags():
  6423 		$remote_source = str_replace( '<!DOC', '<DOC', $remote_source );
  6795 		$remote_source = str_replace( '<!DOC', '<DOC', $remote_source );
  6424 		$remote_source = preg_replace( '/[\r\n\t ]+/', ' ', $remote_source ); // normalize spaces
  6796 		$remote_source = preg_replace( '/[\r\n\t ]+/', ' ', $remote_source ); // normalize spaces
  6425 		$remote_source = preg_replace( "/<\/*(h1|h2|h3|h4|h5|h6|p|th|td|li|dt|dd|pre|caption|input|textarea|button|body)[^>]*>/", "\n\n", $remote_source );
  6797 		$remote_source = preg_replace( '/<\/*(h1|h2|h3|h4|h5|h6|p|th|td|li|dt|dd|pre|caption|input|textarea|button|body)[^>]*>/', "\n\n", $remote_source );
  6426 
  6798 
  6427 		preg_match( '|<title>([^<]*?)</title>|is', $remote_source, $matchtitle );
  6799 		preg_match( '|<title>([^<]*?)</title>|is', $remote_source, $matchtitle );
  6428 		$title = isset( $matchtitle[1] ) ? $matchtitle[1] : '';
  6800 		$title = isset( $matchtitle[1] ) ? $matchtitle[1] : '';
  6429 		if ( empty( $title ) ) {
  6801 		if ( empty( $title ) ) {
  6430 			return $this->pingback_error( 32, __( 'We cannot find a title on that page.' ) );
  6802 			return $this->pingback_error( 32, __( 'We cannot find a title on that page.' ) );
  6432 
  6804 
  6433 		$remote_source = strip_tags( $remote_source, '<a>' ); // just keep the tag we need
  6805 		$remote_source = strip_tags( $remote_source, '<a>' ); // just keep the tag we need
  6434 
  6806 
  6435 		$p = explode( "\n\n", $remote_source );
  6807 		$p = explode( "\n\n", $remote_source );
  6436 
  6808 
  6437 		$preg_target = preg_quote($pagelinkedto, '|');
  6809 		$preg_target = preg_quote( $pagelinkedto, '|' );
  6438 
  6810 
  6439 		foreach ( $p as $para ) {
  6811 		foreach ( $p as $para ) {
  6440 			if ( strpos($para, $pagelinkedto) !== false ) { // it exists, but is it a link?
  6812 			if ( strpos( $para, $pagelinkedto ) !== false ) { // it exists, but is it a link?
  6441 				preg_match("|<a[^>]+?".$preg_target."[^>]*>([^>]+?)</a>|", $para, $context);
  6813 				preg_match( '|<a[^>]+?' . $preg_target . '[^>]*>([^>]+?)</a>|', $para, $context );
  6442 
  6814 
  6443 				// If the URL isn't in a link context, keep looking
  6815 				// If the URL isn't in a link context, keep looking
  6444 				if ( empty($context) )
  6816 				if ( empty( $context ) ) {
  6445 					continue;
  6817 					continue;
       
  6818 				}
  6446 
  6819 
  6447 				// We're going to use this fake tag to mark the context in a bit
  6820 				// We're going to use this fake tag to mark the context in a bit
  6448 				// the marker is needed in case the link text appears more than once in the paragraph
  6821 				// the marker is needed in case the link text appears more than once in the paragraph
  6449 				$excerpt = preg_replace('|\</?wpcontext\>|', '', $para);
  6822 				$excerpt = preg_replace( '|\</?wpcontext\>|', '', $para );
  6450 
  6823 
  6451 				// prevent really long link text
  6824 				// prevent really long link text
  6452 				if ( strlen($context[1]) > 100 )
  6825 				if ( strlen( $context[1] ) > 100 ) {
  6453 					$context[1] = substr($context[1], 0, 100) . '&#8230;';
  6826 					$context[1] = substr( $context[1], 0, 100 ) . '&#8230;';
  6454 
  6827 				}
  6455 				$marker = '<wpcontext>'.$context[1].'</wpcontext>';    // set up our marker
  6828 
  6456 				$excerpt= str_replace($context[0], $marker, $excerpt); // swap out the link for our marker
  6829 				$marker      = '<wpcontext>' . $context[1] . '</wpcontext>';    // set up our marker
  6457 				$excerpt = strip_tags($excerpt, '<wpcontext>');        // strip all tags but our context marker
  6830 				$excerpt     = str_replace( $context[0], $marker, $excerpt ); // swap out the link for our marker
  6458 				$excerpt = trim($excerpt);
  6831 				$excerpt     = strip_tags( $excerpt, '<wpcontext>' );        // strip all tags but our context marker
  6459 				$preg_marker = preg_quote($marker, '|');
  6832 				$excerpt     = trim( $excerpt );
  6460 				$excerpt = preg_replace("|.*?\s(.{0,100}$preg_marker.{0,100})\s.*|s", '$1', $excerpt);
  6833 				$preg_marker = preg_quote( $marker, '|' );
  6461 				$excerpt = strip_tags($excerpt); // YES, again, to remove the marker wrapper
  6834 				$excerpt     = preg_replace( "|.*?\s(.{0,100}$preg_marker.{0,100})\s.*|s", '$1', $excerpt );
       
  6835 				$excerpt     = strip_tags( $excerpt ); // YES, again, to remove the marker wrapper
  6462 				break;
  6836 				break;
  6463 			}
  6837 			}
  6464 		}
  6838 		}
  6465 
  6839 
  6466 		if ( empty($context) ) // Link to target not found
  6840 		if ( empty( $context ) ) { // Link to target not found
  6467 			return $this->pingback_error( 17, __( 'The source URL does not contain a link to the target URL, and so cannot be used as a source.' ) );
  6841 			return $this->pingback_error( 17, __( 'The source URL does not contain a link to the target URL, and so cannot be used as a source.' ) );
  6468 
  6842 		}
  6469 		$pagelinkedfrom = str_replace('&', '&amp;', $pagelinkedfrom);
  6843 
  6470 
  6844 		$pagelinkedfrom = str_replace( '&', '&amp;', $pagelinkedfrom );
  6471 		$context = '[&#8230;] ' . esc_html( $excerpt ) . ' [&#8230;]';
  6845 
       
  6846 		$context        = '[&#8230;] ' . esc_html( $excerpt ) . ' [&#8230;]';
  6472 		$pagelinkedfrom = $this->escape( $pagelinkedfrom );
  6847 		$pagelinkedfrom = $this->escape( $pagelinkedfrom );
  6473 
  6848 
  6474 		$comment_post_ID = (int) $post_ID;
  6849 		$comment_post_ID      = (int) $post_ID;
  6475 		$comment_author = $title;
  6850 		$comment_author       = $title;
  6476 		$comment_author_email = '';
  6851 		$comment_author_email = '';
  6477 		$this->escape($comment_author);
  6852 		$this->escape( $comment_author );
  6478 		$comment_author_url = $pagelinkedfrom;
  6853 		$comment_author_url = $pagelinkedfrom;
  6479 		$comment_content = $context;
  6854 		$comment_content    = $context;
  6480 		$this->escape($comment_content);
  6855 		$this->escape( $comment_content );
  6481 		$comment_type = 'pingback';
  6856 		$comment_type = 'pingback';
  6482 
  6857 
  6483 		$commentdata = compact(
  6858 		$commentdata = compact(
  6484 			'comment_post_ID', 'comment_author', 'comment_author_url', 'comment_author_email',
  6859 			'comment_post_ID',
  6485 			'comment_content', 'comment_type', 'remote_source', 'remote_source_original'
  6860 			'comment_author',
       
  6861 			'comment_author_url',
       
  6862 			'comment_author_email',
       
  6863 			'comment_content',
       
  6864 			'comment_type',
       
  6865 			'remote_source',
       
  6866 			'remote_source_original'
  6486 		);
  6867 		);
  6487 
  6868 
  6488 		$comment_ID = wp_new_comment($commentdata);
  6869 		$comment_ID = wp_new_comment( $commentdata );
  6489 
  6870 
  6490 		if ( is_wp_error( $comment_ID ) ) {
  6871 		if ( is_wp_error( $comment_ID ) ) {
  6491 			return $this->pingback_error( 0, $comment_ID->get_error_message() );
  6872 			return $this->pingback_error( 0, $comment_ID->get_error_message() );
  6492 		}
  6873 		}
  6493 
  6874 
  6522 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  6903 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  6523 		do_action( 'xmlrpc_call', 'pingback.extensions.getPingbacks' );
  6904 		do_action( 'xmlrpc_call', 'pingback.extensions.getPingbacks' );
  6524 
  6905 
  6525 		$url = $this->escape( $url );
  6906 		$url = $this->escape( $url );
  6526 
  6907 
  6527 		$post_ID = url_to_postid($url);
  6908 		$post_ID = url_to_postid( $url );
  6528 		if ( !$post_ID ) {
  6909 		if ( ! $post_ID ) {
  6529 			// We aren't sure that the resource is available and/or pingback enabled
  6910 			// We aren't sure that the resource is available and/or pingback enabled
  6530 	  		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.' ) );
  6911 			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.' ) );
  6531 		}
  6912 		}
  6532 
  6913 
  6533 		$actual_post = get_post($post_ID, ARRAY_A);
  6914 		$actual_post = get_post( $post_ID, ARRAY_A );
  6534 
  6915 
  6535 		if ( !$actual_post ) {
  6916 		if ( ! $actual_post ) {
  6536 			// No such post = resource not found
  6917 			// No such post = resource not found
  6537 	  		return $this->pingback_error( 32, __('The specified target URL does not exist.' ) );
  6918 			return $this->pingback_error( 32, __( 'The specified target URL does not exist.' ) );
  6538 		}
  6919 		}
  6539 
  6920 
  6540 		$comments = $wpdb->get_results( $wpdb->prepare("SELECT comment_author_url, comment_content, comment_author_IP, comment_type FROM $wpdb->comments WHERE comment_post_ID = %d", $post_ID) );
  6921 		$comments = $wpdb->get_results( $wpdb->prepare( "SELECT comment_author_url, comment_content, comment_author_IP, comment_type FROM $wpdb->comments WHERE comment_post_ID = %d", $post_ID ) );
  6541 
  6922 
  6542 		if ( !$comments )
  6923 		if ( ! $comments ) {
  6543 			return array();
  6924 			return array();
       
  6925 		}
  6544 
  6926 
  6545 		$pingbacks = array();
  6927 		$pingbacks = array();
  6546 		foreach ( $comments as $comment ) {
  6928 		foreach ( $comments as $comment ) {
  6547 			if ( 'pingback' == $comment->comment_type )
  6929 			if ( 'pingback' == $comment->comment_type ) {
  6548 				$pingbacks[] = $comment->comment_author_url;
  6930 				$pingbacks[] = $comment->comment_author_url;
       
  6931 			}
  6549 		}
  6932 		}
  6550 
  6933 
  6551 		return $pingbacks;
  6934 		return $pingbacks;
  6552 	}
  6935 	}
  6553 
  6936