wp/wp-includes/class-wp-xmlrpc-server.php
changeset 16 a86126ab1dd4
parent 9 177826044cd9
child 18 be944660c56a
equal deleted inserted replaced
15:3d4e9c994f10 16:a86126ab1dd4
    58 	 *
    58 	 *
    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',
    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',
   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',
   159 		 *
   159 		 *
   160 		 * This filter can be used to add new methods, and remove built-in methods.
   160 		 * This filter can be used to add new methods, and remove built-in methods.
   161 		 *
   161 		 *
   162 		 * @since 1.5.0
   162 		 * @since 1.5.0
   163 		 *
   163 		 *
   164 		 * @param array $methods An array of XML-RPC methods.
   164 		 * @param string[] $methods An array of XML-RPC methods, keyed by their methodName.
   165 		 */
   165 		 */
   166 		$this->methods = apply_filters( 'xmlrpc_methods', $this->methods );
   166 		$this->methods = apply_filters( 'xmlrpc_methods', $this->methods );
   167 	}
   167 	}
   168 
   168 
   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 string   $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 ) {
   180 			return call_user_func_array( array( $this, $name ), $arguments );
   180 			return $this->_multisite_getUsersBlogs( ...$arguments );
   181 		}
   181 		}
   182 		return false;
   182 		return false;
   183 	}
   183 	}
   184 
   184 
   185 	/**
   185 	/**
   205 	/**
   205 	/**
   206 	 * Test XMLRPC API by adding two numbers for client.
   206 	 * Test XMLRPC API by adding two numbers for client.
   207 	 *
   207 	 *
   208 	 * @since 1.5.0
   208 	 * @since 1.5.0
   209 	 *
   209 	 *
   210 	 * @param array  $args {
   210 	 * @param array $args {
   211 	 *     Method arguments. Note: arguments must be ordered as documented.
   211 	 *     Method arguments. Note: arguments must be ordered as documented.
   212 	 *
   212 	 *
   213 	 *     @type int $number1 A number to add.
   213 	 *     @type int $number1 A number to add.
   214 	 *     @type int $number2 A second number to add.
   214 	 *     @type int $number2 A second number to add.
   215 	 * }
   215 	 * }
   276 		}
   276 		}
   277 
   277 
   278 		if ( is_wp_error( $user ) ) {
   278 		if ( is_wp_error( $user ) ) {
   279 			$this->error = new IXR_Error( 403, __( 'Incorrect username or password.' ) );
   279 			$this->error = new IXR_Error( 403, __( 'Incorrect username or password.' ) );
   280 
   280 
   281 			// Flag that authentication has failed once on this wp_xmlrpc_server instance
   281 			// Flag that authentication has failed once on this wp_xmlrpc_server instance.
   282 			$this->auth_failed = true;
   282 			$this->auth_failed = true;
   283 
   283 
   284 			/**
   284 			/**
   285 			 * Filters the XML-RPC user login error message.
   285 			 * Filters the XML-RPC user login error message.
   286 			 *
   286 			 *
   287 			 * @since 3.5.0
   287 			 * @since 3.5.0
   288 			 *
   288 			 *
   289 			 * @param string  $error The XML-RPC error message.
   289 			 * @param string   $error The XML-RPC error message.
   290 			 * @param WP_User $user  WP_User object.
   290 			 * @param WP_Error $user  WP_Error object.
   291 			 */
   291 			 */
   292 			$this->error = apply_filters( 'xmlrpc_login_error', $this->error, $user );
   292 			$this->error = apply_filters( 'xmlrpc_login_error', $this->error, $user );
   293 			return false;
   293 			return false;
   294 		}
   294 		}
   295 
   295 
   367 	/**
   367 	/**
   368 	 * Set custom fields for post.
   368 	 * Set custom fields for post.
   369 	 *
   369 	 *
   370 	 * @since 2.5.0
   370 	 * @since 2.5.0
   371 	 *
   371 	 *
   372 	 * @param int $post_id Post ID.
   372 	 * @param int   $post_id Post ID.
   373 	 * @param array $fields Custom fields.
   373 	 * @param array $fields  Custom fields.
   374 	 */
   374 	 */
   375 	public function set_custom_fields( $post_id, $fields ) {
   375 	public function set_custom_fields( $post_id, $fields ) {
   376 		$post_id = (int) $post_id;
   376 		$post_id = (int) $post_id;
   377 
   377 
   378 		foreach ( (array) $fields as $meta ) {
   378 		foreach ( (array) $fields as $meta ) {
   434 	/**
   434 	/**
   435 	 * Set custom fields for a term.
   435 	 * Set custom fields for a term.
   436 	 *
   436 	 *
   437 	 * @since 4.9.0
   437 	 * @since 4.9.0
   438 	 *
   438 	 *
   439 	 * @param int $term_id Term ID.
   439 	 * @param int   $term_id Term ID.
   440 	 * @param array $fields Custom fields.
   440 	 * @param array $fields  Custom fields.
   441 	 */
   441 	 */
   442 	public function set_term_custom_fields( $term_id, $fields ) {
   442 	public function set_term_custom_fields( $term_id, $fields ) {
   443 		$term_id = (int) $term_id;
   443 		$term_id = (int) $term_id;
   444 
   444 
   445 		foreach ( (array) $fields as $meta ) {
   445 		foreach ( (array) $fields as $meta ) {
   471 	 *
   471 	 *
   472 	 * @since 2.6.0
   472 	 * @since 2.6.0
   473 	 */
   473 	 */
   474 	public function initialise_blog_option_info() {
   474 	public function initialise_blog_option_info() {
   475 		$this->blog_options = array(
   475 		$this->blog_options = array(
   476 			// Read only options
   476 			// Read-only options.
   477 			'software_name'           => array(
   477 			'software_name'           => array(
   478 				'desc'     => __( 'Software Name' ),
   478 				'desc'     => __( 'Software Name' ),
   479 				'readonly' => true,
   479 				'readonly' => true,
   480 				'value'    => 'WordPress',
   480 				'value'    => 'WordPress',
   481 			),
   481 			),
   533 				'desc'     => __( 'Post Thumbnail' ),
   533 				'desc'     => __( 'Post Thumbnail' ),
   534 				'readonly' => true,
   534 				'readonly' => true,
   535 				'value'    => current_theme_supports( 'post-thumbnails' ),
   535 				'value'    => current_theme_supports( 'post-thumbnails' ),
   536 			),
   536 			),
   537 
   537 
   538 			// Updatable options
   538 			// Updatable options.
   539 			'time_zone'               => array(
   539 			'time_zone'               => array(
   540 				'desc'     => __( 'Time Zone' ),
   540 				'desc'     => __( 'Time Zone' ),
   541 				'readonly' => false,
   541 				'readonly' => false,
   542 				'option'   => 'gmt_offset',
   542 				'option'   => 'gmt_offset',
   543 			),
   543 			),
   610 				'desc'     => __( 'Large size image height' ),
   610 				'desc'     => __( 'Large size image height' ),
   611 				'readonly' => false,
   611 				'readonly' => false,
   612 				'option'   => 'large_size_h',
   612 				'option'   => 'large_size_h',
   613 			),
   613 			),
   614 			'default_comment_status'  => array(
   614 			'default_comment_status'  => array(
   615 				'desc'     => __( 'Allow people to post comments on new articles' ),
   615 				'desc'     => __( 'Allow people to submit comments on new posts.' ),
   616 				'readonly' => false,
   616 				'readonly' => false,
   617 				'option'   => 'default_comment_status',
   617 				'option'   => 'default_comment_status',
   618 			),
   618 			),
   619 			'default_ping_status'     => array(
   619 			'default_ping_status'     => array(
   620 				'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 posts.' ),
   621 				'readonly' => false,
   621 				'readonly' => false,
   622 				'option'   => 'default_ping_status',
   622 				'option'   => 'default_ping_status',
   623 			),
   623 			),
   624 		);
   624 		);
   625 
   625 
   655 	public function wp_getUsersBlogs( $args ) {
   655 	public function wp_getUsersBlogs( $args ) {
   656 		if ( ! $this->minimum_args( $args, 2 ) ) {
   656 		if ( ! $this->minimum_args( $args, 2 ) ) {
   657 			return $this->error;
   657 			return $this->error;
   658 		}
   658 		}
   659 
   659 
   660 		// If this isn't on WPMU then just use blogger_getUsersBlogs
   660 		// If this isn't on WPMU then just use blogger_getUsersBlogs().
   661 		if ( ! is_multisite() ) {
   661 		if ( ! is_multisite() ) {
   662 			array_unshift( $args, 1 );
   662 			array_unshift( $args, 1 );
   663 			return $this->blogger_getUsersBlogs( $args );
   663 			return $this->blogger_getUsersBlogs( $args );
   664 		}
   664 		}
   665 
   665 
   666 		$this->escape( $args );
   666 		$this->escape( $args );
   667 
   667 
   668 		$username = $args[0];
   668 		$username = $args[0];
   669 		$password = $args[1];
   669 		$password = $args[1];
   670 
   670 
   671 		if ( ! $user = $this->login( $username, $password ) ) {
   671 		$user = $this->login( $username, $password );
       
   672 		if ( ! $user ) {
   672 			return $this->error;
   673 			return $this->error;
   673 		}
   674 		}
   674 
   675 
   675 		/**
   676 		/**
   676 		 * Fires after the XML-RPC user has been authenticated but before the rest of
   677 		 * Fires after the XML-RPC user has been authenticated but before the rest of
   693 			$primary_blog_id = (int) $active_blog->blog_id;
   694 			$primary_blog_id = (int) $active_blog->blog_id;
   694 		}
   695 		}
   695 
   696 
   696 		foreach ( $blogs as $blog ) {
   697 		foreach ( $blogs as $blog ) {
   697 			// Don't include blogs that aren't hosted at this site.
   698 			// Don't include blogs that aren't hosted at this site.
   698 			if ( $blog->site_id != get_current_network_id() ) {
   699 			if ( get_current_network_id() != $blog->site_id ) {
   699 				continue;
   700 				continue;
   700 			}
   701 			}
   701 
   702 
   702 			$blog_id = $blog->userblog_id;
   703 			$blog_id = $blog->userblog_id;
   703 
   704 
   724 	/**
   725 	/**
   725 	 * Checks if the method received at least the minimum number of arguments.
   726 	 * Checks if the method received at least the minimum number of arguments.
   726 	 *
   727 	 *
   727 	 * @since 3.4.0
   728 	 * @since 3.4.0
   728 	 *
   729 	 *
   729 	 * @param string|array $args Sanitize single string or array of strings.
   730 	 * @param array $args  An array of arguments to check.
   730 	 * @param int $count         Minimum number of arguments.
   731 	 * @param int   $count Minimum number of arguments.
   731 	 * @return bool if `$args` contains at least $count arguments.
   732 	 * @return bool True if `$args` contains at least `$count` arguments, false otherwise.
   732 	 */
   733 	 */
   733 	protected function minimum_args( $args, $count ) {
   734 	protected function minimum_args( $args, $count ) {
   734 		if ( count( $args ) < $count ) {
   735 		if ( ! is_array( $args ) || count( $args ) < $count ) {
   735 			$this->error = new IXR_Error( 400, __( 'Insufficient arguments passed to this XML-RPC method.' ) );
   736 			$this->error = new IXR_Error( 400, __( 'Insufficient arguments passed to this XML-RPC method.' ) );
   736 			return false;
   737 			return false;
   737 		}
   738 		}
   738 
   739 
   739 		return true;
   740 		return true;
   741 
   742 
   742 	/**
   743 	/**
   743 	 * Prepares taxonomy data for return in an XML-RPC object.
   744 	 * Prepares taxonomy data for return in an XML-RPC object.
   744 	 *
   745 	 *
   745 	 * @param object $taxonomy The unprepared taxonomy data.
   746 	 * @param object $taxonomy The unprepared taxonomy data.
   746 	 * @param array $fields    The subset of taxonomy fields to return.
   747 	 * @param array  $fields   The subset of taxonomy fields to return.
   747 	 * @return array The prepared taxonomy data.
   748 	 * @return array The prepared taxonomy data.
   748 	 */
   749 	 */
   749 	protected function _prepare_taxonomy( $taxonomy, $fields ) {
   750 	protected function _prepare_taxonomy( $taxonomy, $fields ) {
   750 		$_taxonomy = array(
   751 		$_taxonomy = array(
   751 			'name'         => $taxonomy->name,
   752 			'name'         => $taxonomy->name,
   754 			'public'       => (bool) $taxonomy->public,
   755 			'public'       => (bool) $taxonomy->public,
   755 			'show_ui'      => (bool) $taxonomy->show_ui,
   756 			'show_ui'      => (bool) $taxonomy->show_ui,
   756 			'_builtin'     => (bool) $taxonomy->_builtin,
   757 			'_builtin'     => (bool) $taxonomy->_builtin,
   757 		);
   758 		);
   758 
   759 
   759 		if ( in_array( 'labels', $fields ) ) {
   760 		if ( in_array( 'labels', $fields, true ) ) {
   760 			$_taxonomy['labels'] = (array) $taxonomy->labels;
   761 			$_taxonomy['labels'] = (array) $taxonomy->labels;
   761 		}
   762 		}
   762 
   763 
   763 		if ( in_array( 'cap', $fields ) ) {
   764 		if ( in_array( 'cap', $fields, true ) ) {
   764 			$_taxonomy['cap'] = (array) $taxonomy->cap;
   765 			$_taxonomy['cap'] = (array) $taxonomy->cap;
   765 		}
   766 		}
   766 
   767 
   767 		if ( in_array( 'menu', $fields ) ) {
   768 		if ( in_array( 'menu', $fields, true ) ) {
   768 			$_taxonomy['show_in_menu'] = (bool) $_taxonomy->show_in_menu;
   769 			$_taxonomy['show_in_menu'] = (bool) $_taxonomy->show_in_menu;
   769 		}
   770 		}
   770 
   771 
   771 		if ( in_array( 'object_type', $fields ) ) {
   772 		if ( in_array( 'object_type', $fields, true ) ) {
   772 			$_taxonomy['object_type'] = array_unique( (array) $taxonomy->object_type );
   773 			$_taxonomy['object_type'] = array_unique( (array) $taxonomy->object_type );
   773 		}
   774 		}
   774 
   775 
   775 		/**
   776 		/**
   776 		 * Filters XML-RPC-prepared data for the given taxonomy.
   777 		 * Filters XML-RPC-prepared data for the given taxonomy.
   824 	 *
   825 	 *
   825 	 * @param string $date Date string to convert.
   826 	 * @param string $date Date string to convert.
   826 	 * @return IXR_Date IXR_Date object.
   827 	 * @return IXR_Date IXR_Date object.
   827 	 */
   828 	 */
   828 	protected function _convert_date( $date ) {
   829 	protected function _convert_date( $date ) {
   829 		if ( $date === '0000-00-00 00:00:00' ) {
   830 		if ( '0000-00-00 00:00:00' === $date ) {
   830 			return new IXR_Date( '00000000T00:00:00Z' );
   831 			return new IXR_Date( '00000000T00:00:00Z' );
   831 		}
   832 		}
   832 		return new IXR_Date( mysql2date( 'Ymd\TH:i:s', $date, false ) );
   833 		return new IXR_Date( mysql2date( 'Ymd\TH:i:s', $date, false ) );
   833 	}
   834 	}
   834 
   835 
   838 	 * @param string $date_gmt WordPress GMT date string.
   839 	 * @param string $date_gmt WordPress GMT date string.
   839 	 * @param string $date     Date string.
   840 	 * @param string $date     Date string.
   840 	 * @return IXR_Date IXR_Date object.
   841 	 * @return IXR_Date IXR_Date object.
   841 	 */
   842 	 */
   842 	protected function _convert_date_gmt( $date_gmt, $date ) {
   843 	protected function _convert_date_gmt( $date_gmt, $date ) {
   843 		if ( $date !== '0000-00-00 00:00:00' && $date_gmt === '0000-00-00 00:00:00' ) {
   844 		if ( '0000-00-00 00:00:00' !== $date && '0000-00-00 00:00:00' === $date_gmt ) {
   844 			return new IXR_Date( get_gmt_from_date( mysql2date( 'Y-m-d H:i:s', $date, false ), 'Ymd\TH:i:s' ) );
   845 			return new IXR_Date( get_gmt_from_date( mysql2date( 'Y-m-d H:i:s', $date, false ), 'Ymd\TH:i:s' ) );
   845 		}
   846 		}
   846 		return $this->_convert_date( $date_gmt );
   847 		return $this->_convert_date( $date_gmt );
   847 	}
   848 	}
   848 
   849 
   876 			'link'              => get_permalink( $post['ID'] ),
   877 			'link'              => get_permalink( $post['ID'] ),
   877 			'guid'              => $post['guid'],
   878 			'guid'              => $post['guid'],
   878 			'menu_order'        => intval( $post['menu_order'] ),
   879 			'menu_order'        => intval( $post['menu_order'] ),
   879 			'comment_status'    => $post['comment_status'],
   880 			'comment_status'    => $post['comment_status'],
   880 			'ping_status'       => $post['ping_status'],
   881 			'ping_status'       => $post['ping_status'],
   881 			'sticky'            => ( $post['post_type'] === 'post' && is_sticky( $post['ID'] ) ),
   882 			'sticky'            => ( 'post' === $post['post_type'] && is_sticky( $post['ID'] ) ),
   882 		);
   883 		);
   883 
   884 
   884 		// Thumbnail.
   885 		// Thumbnail.
   885 		$post_fields['post_thumbnail'] = array();
   886 		$post_fields['post_thumbnail'] = array();
   886 		$thumbnail_id                  = get_post_thumbnail_id( $post['ID'] );
   887 		$thumbnail_id                  = get_post_thumbnail_id( $post['ID'] );
   888 			$thumbnail_size                = current_theme_supports( 'post-thumbnail' ) ? 'post-thumbnail' : 'thumbnail';
   889 			$thumbnail_size                = current_theme_supports( 'post-thumbnail' ) ? 'post-thumbnail' : 'thumbnail';
   889 			$post_fields['post_thumbnail'] = $this->_prepare_media_item( get_post( $thumbnail_id ), $thumbnail_size );
   890 			$post_fields['post_thumbnail'] = $this->_prepare_media_item( get_post( $thumbnail_id ), $thumbnail_size );
   890 		}
   891 		}
   891 
   892 
   892 		// Consider future posts as published.
   893 		// Consider future posts as published.
   893 		if ( $post_fields['post_status'] === 'future' ) {
   894 		if ( 'future' === $post_fields['post_status'] ) {
   894 			$post_fields['post_status'] = 'publish';
   895 			$post_fields['post_status'] = 'publish';
   895 		}
   896 		}
   896 
   897 
   897 		// Fill in blank post format.
   898 		// Fill in blank post format.
   898 		$post_fields['post_format'] = get_post_format( $post['ID'] );
   899 		$post_fields['post_format'] = get_post_format( $post['ID'] );
   899 		if ( empty( $post_fields['post_format'] ) ) {
   900 		if ( empty( $post_fields['post_format'] ) ) {
   900 			$post_fields['post_format'] = 'standard';
   901 			$post_fields['post_format'] = 'standard';
   901 		}
   902 		}
   902 
   903 
   903 		// Merge requested $post_fields fields into $_post.
   904 		// Merge requested $post_fields fields into $_post.
   904 		if ( in_array( 'post', $fields ) ) {
   905 		if ( in_array( 'post', $fields, true ) ) {
   905 			$_post = array_merge( $_post, $post_fields );
   906 			$_post = array_merge( $_post, $post_fields );
   906 		} else {
   907 		} else {
   907 			$requested_fields = array_intersect_key( $post_fields, array_flip( $fields ) );
   908 			$requested_fields = array_intersect_key( $post_fields, array_flip( $fields ) );
   908 			$_post            = array_merge( $_post, $requested_fields );
   909 			$_post            = array_merge( $_post, $requested_fields );
   909 		}
   910 		}
   910 
   911 
   911 		$all_taxonomy_fields = in_array( 'taxonomies', $fields );
   912 		$all_taxonomy_fields = in_array( 'taxonomies', $fields, true );
   912 
   913 
   913 		if ( $all_taxonomy_fields || in_array( 'terms', $fields ) ) {
   914 		if ( $all_taxonomy_fields || in_array( 'terms', $fields, true ) ) {
   914 			$post_type_taxonomies = get_object_taxonomies( $post['post_type'], 'names' );
   915 			$post_type_taxonomies = get_object_taxonomies( $post['post_type'], 'names' );
   915 			$terms                = wp_get_object_terms( $post['ID'], $post_type_taxonomies );
   916 			$terms                = wp_get_object_terms( $post['ID'], $post_type_taxonomies );
   916 			$_post['terms']       = array();
   917 			$_post['terms']       = array();
   917 			foreach ( $terms as $term ) {
   918 			foreach ( $terms as $term ) {
   918 				$_post['terms'][] = $this->_prepare_term( $term );
   919 				$_post['terms'][] = $this->_prepare_term( $term );
   919 			}
   920 			}
   920 		}
   921 		}
   921 
   922 
   922 		if ( in_array( 'custom_fields', $fields ) ) {
   923 		if ( in_array( 'custom_fields', $fields, true ) ) {
   923 			$_post['custom_fields'] = $this->get_custom_fields( $post['ID'] );
   924 			$_post['custom_fields'] = $this->get_custom_fields( $post['ID'] );
   924 		}
   925 		}
   925 
   926 
   926 		if ( in_array( 'enclosure', $fields ) ) {
   927 		if ( in_array( 'enclosure', $fields, true ) ) {
   927 			$_post['enclosure'] = array();
   928 			$_post['enclosure'] = array();
   928 			$enclosures         = (array) get_post_meta( $post['ID'], 'enclosure' );
   929 			$enclosures         = (array) get_post_meta( $post['ID'], 'enclosure' );
   929 			if ( ! empty( $enclosures ) ) {
   930 			if ( ! empty( $enclosures ) ) {
   930 				$encdata                      = explode( "\n", $enclosures[0] );
   931 				$encdata                      = explode( "\n", $enclosures[0] );
   931 				$_post['enclosure']['url']    = trim( htmlspecialchars( $encdata[0] ) );
   932 				$_post['enclosure']['url']    = trim( htmlspecialchars( $encdata[0] ) );
   966 			'_builtin'     => (bool) $post_type->_builtin,
   967 			'_builtin'     => (bool) $post_type->_builtin,
   967 			'has_archive'  => (bool) $post_type->has_archive,
   968 			'has_archive'  => (bool) $post_type->has_archive,
   968 			'supports'     => get_all_post_type_supports( $post_type->name ),
   969 			'supports'     => get_all_post_type_supports( $post_type->name ),
   969 		);
   970 		);
   970 
   971 
   971 		if ( in_array( 'labels', $fields ) ) {
   972 		if ( in_array( 'labels', $fields, true ) ) {
   972 			$_post_type['labels'] = (array) $post_type->labels;
   973 			$_post_type['labels'] = (array) $post_type->labels;
   973 		}
   974 		}
   974 
   975 
   975 		if ( in_array( 'cap', $fields ) ) {
   976 		if ( in_array( 'cap', $fields, true ) ) {
   976 			$_post_type['cap']          = (array) $post_type->cap;
   977 			$_post_type['cap']          = (array) $post_type->cap;
   977 			$_post_type['map_meta_cap'] = (bool) $post_type->map_meta_cap;
   978 			$_post_type['map_meta_cap'] = (bool) $post_type->map_meta_cap;
   978 		}
   979 		}
   979 
   980 
   980 		if ( in_array( 'menu', $fields ) ) {
   981 		if ( in_array( 'menu', $fields, true ) ) {
   981 			$_post_type['menu_position'] = (int) $post_type->menu_position;
   982 			$_post_type['menu_position'] = (int) $post_type->menu_position;
   982 			$_post_type['menu_icon']     = $post_type->menu_icon;
   983 			$_post_type['menu_icon']     = $post_type->menu_icon;
   983 			$_post_type['show_in_menu']  = (bool) $post_type->show_in_menu;
   984 			$_post_type['show_in_menu']  = (bool) $post_type->show_in_menu;
   984 		}
   985 		}
   985 
   986 
   986 		if ( in_array( 'taxonomies', $fields ) ) {
   987 		if ( in_array( 'taxonomies', $fields, true ) ) {
   987 			$_post_type['taxonomies'] = get_object_taxonomies( $post_type->name, 'names' );
   988 			$_post_type['taxonomies'] = get_object_taxonomies( $post_type->name, 'names' );
   988 		}
   989 		}
   989 
   990 
   990 		/**
   991 		/**
   991 		 * Filters XML-RPC-prepared date for the given post type.
   992 		 * Filters XML-RPC-prepared date for the given post type.
  1128 		// Format page date.
  1129 		// Format page date.
  1129 		$comment_date_gmt = $this->_convert_date_gmt( $comment->comment_date_gmt, $comment->comment_date );
  1130 		$comment_date_gmt = $this->_convert_date_gmt( $comment->comment_date_gmt, $comment->comment_date );
  1130 
  1131 
  1131 		if ( '0' == $comment->comment_approved ) {
  1132 		if ( '0' == $comment->comment_approved ) {
  1132 			$comment_status = 'hold';
  1133 			$comment_status = 'hold';
  1133 		} elseif ( 'spam' == $comment->comment_approved ) {
  1134 		} elseif ( 'spam' === $comment->comment_approved ) {
  1134 			$comment_status = 'spam';
  1135 			$comment_status = 'spam';
  1135 		} elseif ( '1' == $comment->comment_approved ) {
  1136 		} elseif ( '1' == $comment->comment_approved ) {
  1136 			$comment_status = 'approve';
  1137 			$comment_status = 'approve';
  1137 		} else {
  1138 		} else {
  1138 			$comment_status = $comment->comment_approved;
  1139 			$comment_status = $comment->comment_approved;
  1187 			'url'          => $user->user_url,
  1188 			'url'          => $user->user_url,
  1188 			'display_name' => $user->display_name,
  1189 			'display_name' => $user->display_name,
  1189 			'roles'        => $user->roles,
  1190 			'roles'        => $user->roles,
  1190 		);
  1191 		);
  1191 
  1192 
  1192 		if ( in_array( 'all', $fields ) ) {
  1193 		if ( in_array( 'all', $fields, true ) ) {
  1193 			$_user = array_merge( $_user, $user_fields );
  1194 			$_user = array_merge( $_user, $user_fields );
  1194 		} else {
  1195 		} else {
  1195 			if ( in_array( 'basic', $fields ) ) {
  1196 			if ( in_array( 'basic', $fields, true ) ) {
  1196 				$basic_fields = array( 'username', 'email', 'registered', 'display_name', 'nicename' );
  1197 				$basic_fields = array( 'username', 'email', 'registered', 'display_name', 'nicename' );
  1197 				$fields       = array_merge( $fields, $basic_fields );
  1198 				$fields       = array_merge( $fields, $basic_fields );
  1198 			}
  1199 			}
  1199 			$requested_fields = array_intersect_key( $user_fields, array_flip( $fields ) );
  1200 			$requested_fields = array_intersect_key( $user_fields, array_flip( $fields ) );
  1200 			$_user            = array_merge( $_user, $requested_fields );
  1201 			$_user            = array_merge( $_user, $requested_fields );
  1217 	 *
  1218 	 *
  1218 	 * @since 3.4.0
  1219 	 * @since 3.4.0
  1219 	 *
  1220 	 *
  1220 	 * @link https://en.wikipedia.org/wiki/RSS_enclosure for information on RSS enclosures.
  1221 	 * @link https://en.wikipedia.org/wiki/RSS_enclosure for information on RSS enclosures.
  1221 	 *
  1222 	 *
  1222 	 * @param array  $args {
  1223 	 * @param array $args {
  1223 	 *     Method arguments. Note: top-level arguments must be ordered as documented.
  1224 	 *     Method arguments. Note: top-level arguments must be ordered as documented.
  1224 	 *
  1225 	 *
  1225 	 *     @type int    $blog_id        Blog ID (unused).
  1226 	 *     @type int    $blog_id        Blog ID (unused).
  1226 	 *     @type string $username       Username.
  1227 	 *     @type string $username       Username.
  1227 	 *     @type string $password       Password.
  1228 	 *     @type string $password       Password.
  1268 
  1269 
  1269 		$username       = $args[1];
  1270 		$username       = $args[1];
  1270 		$password       = $args[2];
  1271 		$password       = $args[2];
  1271 		$content_struct = $args[3];
  1272 		$content_struct = $args[3];
  1272 
  1273 
  1273 		if ( ! $user = $this->login( $username, $password ) ) {
  1274 		$user = $this->login( $username, $password );
  1274 			return $this->error;
  1275 		if ( ! $user ) {
  1275 		}
  1276 			return $this->error;
  1276 
  1277 		}
  1277 		// convert the date field back to IXR form
  1278 
       
  1279 		// Convert the date field back to IXR form.
  1278 		if ( isset( $content_struct['post_date'] ) && ! ( $content_struct['post_date'] instanceof IXR_Date ) ) {
  1280 		if ( isset( $content_struct['post_date'] ) && ! ( $content_struct['post_date'] instanceof IXR_Date ) ) {
  1279 			$content_struct['post_date'] = $this->_convert_date( $content_struct['post_date'] );
  1281 			$content_struct['post_date'] = $this->_convert_date( $content_struct['post_date'] );
  1280 		}
  1282 		}
  1281 
  1283 
  1282 		// ignore the existing GMT date if it is empty or a non-GMT date was supplied in $content_struct,
  1284 		/*
  1283 		// since _insert_post will ignore the non-GMT date if the GMT date is set
  1285 		 * Ignore the existing GMT date if it is empty or a non-GMT date was supplied in $content_struct,
       
  1286 		 * since _insert_post() will ignore the non-GMT date if the GMT date is set.
       
  1287 		 */
  1284 		if ( isset( $content_struct['post_date_gmt'] ) && ! ( $content_struct['post_date_gmt'] instanceof IXR_Date ) ) {
  1288 		if ( isset( $content_struct['post_date_gmt'] ) && ! ( $content_struct['post_date_gmt'] instanceof IXR_Date ) ) {
  1285 			if ( $content_struct['post_date_gmt'] == '0000-00-00 00:00:00' || isset( $content_struct['post_date'] ) ) {
  1289 			if ( '0000-00-00 00:00:00' === $content_struct['post_date_gmt'] || isset( $content_struct['post_date'] ) ) {
  1286 				unset( $content_struct['post_date_gmt'] );
  1290 				unset( $content_struct['post_date_gmt'] );
  1287 			} else {
  1291 			} else {
  1288 				$content_struct['post_date_gmt'] = $this->_convert_date( $content_struct['post_date_gmt'] );
  1292 				$content_struct['post_date_gmt'] = $this->_convert_date( $content_struct['post_date_gmt'] );
  1289 			}
  1293 			}
  1290 		}
  1294 		}
  1395 				return new IXR_Error( 401, __( 'Invalid post ID.' ) );
  1399 				return new IXR_Error( 401, __( 'Invalid post ID.' ) );
  1396 			}
  1400 			}
  1397 			if ( ! current_user_can( 'edit_post', $post_data['ID'] ) ) {
  1401 			if ( ! current_user_can( 'edit_post', $post_data['ID'] ) ) {
  1398 				return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit this post.' ) );
  1402 				return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit this post.' ) );
  1399 			}
  1403 			}
  1400 			if ( $post_data['post_type'] != get_post_type( $post_data['ID'] ) ) {
  1404 			if ( get_post_type( $post_data['ID'] ) !== $post_data['post_type'] ) {
  1401 				return new IXR_Error( 401, __( 'The post type may not be changed.' ) );
  1405 				return new IXR_Error( 401, __( 'The post type may not be changed.' ) );
  1402 			}
  1406 			}
  1403 		} else {
  1407 		} else {
  1404 			if ( ! current_user_can( $post_type->cap->create_posts ) || ! current_user_can( $post_type->cap->edit_posts ) ) {
  1408 			if ( ! current_user_can( $post_type->cap->create_posts ) || ! current_user_can( $post_type->cap->edit_posts ) ) {
  1405 				return new IXR_Error( 401, __( 'Sorry, you are not allowed to post on this site.' ) );
  1409 				return new IXR_Error( 401, __( 'Sorry, you are not allowed to post on this site.' ) );
  1445 			}
  1449 			}
  1446 		} else {
  1450 		} else {
  1447 			$post_data['post_author'] = $user->ID;
  1451 			$post_data['post_author'] = $user->ID;
  1448 		}
  1452 		}
  1449 
  1453 
  1450 		if ( isset( $post_data['comment_status'] ) && $post_data['comment_status'] != 'open' && $post_data['comment_status'] != 'closed' ) {
  1454 		if ( isset( $post_data['comment_status'] ) && 'open' !== $post_data['comment_status'] && 'closed' !== $post_data['comment_status'] ) {
  1451 			unset( $post_data['comment_status'] );
  1455 			unset( $post_data['comment_status'] );
  1452 		}
  1456 		}
  1453 
  1457 
  1454 		if ( isset( $post_data['ping_status'] ) && $post_data['ping_status'] != 'open' && $post_data['ping_status'] != 'closed' ) {
  1458 		if ( isset( $post_data['ping_status'] ) && 'open' !== $post_data['ping_status'] && 'closed' !== $post_data['ping_status'] ) {
  1455 			unset( $post_data['ping_status'] );
  1459 			unset( $post_data['ping_status'] );
  1456 		}
  1460 		}
  1457 
  1461 
  1458 		// Do some timestamp voodoo.
  1462 		// Do some timestamp voodoo.
  1459 		if ( ! empty( $post_data['post_date_gmt'] ) ) {
  1463 		if ( ! empty( $post_data['post_date_gmt'] ) ) {
  1465 
  1469 
  1466 		// Default to not flagging the post date to be edited unless it's intentional.
  1470 		// Default to not flagging the post date to be edited unless it's intentional.
  1467 		$post_data['edit_date'] = false;
  1471 		$post_data['edit_date'] = false;
  1468 
  1472 
  1469 		if ( ! empty( $dateCreated ) ) {
  1473 		if ( ! empty( $dateCreated ) ) {
  1470 			$post_data['post_date']     = get_date_from_gmt( iso8601_to_datetime( $dateCreated ) );
  1474 			$post_data['post_date']     = iso8601_to_datetime( $dateCreated );
  1471 			$post_data['post_date_gmt'] = iso8601_to_datetime( $dateCreated, 'GMT' );
  1475 			$post_data['post_date_gmt'] = iso8601_to_datetime( $dateCreated, 'gmt' );
  1472 
  1476 
  1473 			// Flag the post date to be edited.
  1477 			// Flag the post date to be edited.
  1474 			$post_data['edit_date'] = true;
  1478 			$post_data['edit_date'] = true;
  1475 		}
  1479 		}
  1476 
  1480 
  1477 		if ( ! isset( $post_data['ID'] ) ) {
  1481 		if ( ! isset( $post_data['ID'] ) ) {
  1478 			$post_data['ID'] = get_default_post_to_edit( $post_data['post_type'], true )->ID;
  1482 			$post_data['ID'] = get_default_post_to_edit( $post_data['post_type'], true )->ID;
  1479 		}
  1483 		}
  1480 		$post_ID = $post_data['ID'];
  1484 		$post_ID = $post_data['ID'];
  1481 
  1485 
  1482 		if ( $post_data['post_type'] == 'post' ) {
  1486 		if ( 'post' === $post_data['post_type'] ) {
  1483 			$error = $this->_toggle_sticky( $post_data, $update );
  1487 			$error = $this->_toggle_sticky( $post_data, $update );
  1484 			if ( $error ) {
  1488 			if ( $error ) {
  1485 				return $error;
  1489 				return $error;
  1486 			}
  1490 			}
  1487 		}
  1491 		}
  1488 
  1492 
  1489 		if ( isset( $post_data['post_thumbnail'] ) ) {
  1493 		if ( isset( $post_data['post_thumbnail'] ) ) {
  1490 			// empty value deletes, non-empty value adds/updates.
  1494 			// Empty value deletes, non-empty value adds/updates.
  1491 			if ( ! $post_data['post_thumbnail'] ) {
  1495 			if ( ! $post_data['post_thumbnail'] ) {
  1492 				delete_post_thumbnail( $post_ID );
  1496 				delete_post_thumbnail( $post_ID );
  1493 			} elseif ( ! get_post( absint( $post_data['post_thumbnail'] ) ) ) {
  1497 			} elseif ( ! get_post( absint( $post_data['post_thumbnail'] ) ) ) {
  1494 				return new IXR_Error( 404, __( 'Invalid attachment ID.' ) );
  1498 				return new IXR_Error( 404, __( 'Invalid attachment ID.' ) );
  1495 			}
  1499 			}
  1509 
  1513 
  1510 			// First validate the terms specified by ID.
  1514 			// First validate the terms specified by ID.
  1511 			if ( isset( $post_data['terms'] ) && is_array( $post_data['terms'] ) ) {
  1515 			if ( isset( $post_data['terms'] ) && is_array( $post_data['terms'] ) ) {
  1512 				$taxonomies = array_keys( $post_data['terms'] );
  1516 				$taxonomies = array_keys( $post_data['terms'] );
  1513 
  1517 
  1514 				// Validating term ids.
  1518 				// Validating term IDs.
  1515 				foreach ( $taxonomies as $taxonomy ) {
  1519 				foreach ( $taxonomies as $taxonomy ) {
  1516 					if ( ! array_key_exists( $taxonomy, $post_type_taxonomies ) ) {
  1520 					if ( ! array_key_exists( $taxonomy, $post_type_taxonomies ) ) {
  1517 						return new IXR_Error( 401, __( 'Sorry, one of the given taxonomies is not supported by the post type.' ) );
  1521 						return new IXR_Error( 401, __( 'Sorry, one of the given taxonomies is not supported by the post type.' ) );
  1518 					}
  1522 					}
  1519 
  1523 
  1553 					 * in the hierarchy share the same name.
  1557 					 * in the hierarchy share the same name.
  1554 					 */
  1558 					 */
  1555 					$ambiguous_terms = array();
  1559 					$ambiguous_terms = array();
  1556 					if ( is_taxonomy_hierarchical( $taxonomy ) ) {
  1560 					if ( is_taxonomy_hierarchical( $taxonomy ) ) {
  1557 						$tax_term_names = get_terms(
  1561 						$tax_term_names = get_terms(
  1558 							$taxonomy,
       
  1559 							array(
  1562 							array(
       
  1563 								'taxonomy'   => $taxonomy,
  1560 								'fields'     => 'names',
  1564 								'fields'     => 'names',
  1561 								'hide_empty' => false,
  1565 								'hide_empty' => false,
  1562 							)
  1566 							)
  1563 						);
  1567 						);
  1564 
  1568 
  1571 						$ambiguous_terms = array_keys( $ambiguous_tax_term_counts );
  1575 						$ambiguous_terms = array_keys( $ambiguous_tax_term_counts );
  1572 					}
  1576 					}
  1573 
  1577 
  1574 					$term_names = $post_data['terms_names'][ $taxonomy ];
  1578 					$term_names = $post_data['terms_names'][ $taxonomy ];
  1575 					foreach ( $term_names as $term_name ) {
  1579 					foreach ( $term_names as $term_name ) {
  1576 						if ( in_array( $term_name, $ambiguous_terms ) ) {
  1580 						if ( in_array( $term_name, $ambiguous_terms, true ) ) {
  1577 							return new IXR_Error( 401, __( 'Ambiguous term name used in a hierarchical taxonomy. Please use term ID instead.' ) );
  1581 							return new IXR_Error( 401, __( 'Ambiguous term name used in a hierarchical taxonomy. Please use term ID instead.' ) );
  1578 						}
  1582 						}
  1579 
  1583 
  1580 						$term = get_term_by( 'name', $term_name, $taxonomy );
  1584 						$term = get_term_by( 'name', $term_name, $taxonomy );
  1581 
  1585 
  1633 		if ( is_wp_error( $post_ID ) ) {
  1637 		if ( is_wp_error( $post_ID ) ) {
  1634 			return new IXR_Error( 500, $post_ID->get_error_message() );
  1638 			return new IXR_Error( 500, $post_ID->get_error_message() );
  1635 		}
  1639 		}
  1636 
  1640 
  1637 		if ( ! $post_ID ) {
  1641 		if ( ! $post_ID ) {
  1638 			return new IXR_Error( 401, __( 'Sorry, your entry could not be posted.' ) );
  1642 			if ( $update ) {
       
  1643 				return new IXR_Error( 401, __( 'Sorry, the post could not be updated.' ) );
       
  1644 			} else {
       
  1645 				return new IXR_Error( 401, __( 'Sorry, the post could not be created.' ) );
       
  1646 			}
  1639 		}
  1647 		}
  1640 
  1648 
  1641 		return strval( $post_ID );
  1649 		return strval( $post_ID );
  1642 	}
  1650 	}
  1643 
  1651 
  1647 	 * The $content_struct parameter only needs to contain fields that
  1655 	 * The $content_struct parameter only needs to contain fields that
  1648 	 * should be changed. All other fields will retain their existing values.
  1656 	 * should be changed. All other fields will retain their existing values.
  1649 	 *
  1657 	 *
  1650 	 * @since 3.4.0
  1658 	 * @since 3.4.0
  1651 	 *
  1659 	 *
  1652 	 * @param array  $args {
  1660 	 * @param array $args {
  1653 	 *     Method arguments. Note: arguments must be ordered as documented.
  1661 	 *     Method arguments. Note: arguments must be ordered as documented.
  1654 	 *
  1662 	 *
  1655 	 *     @type int    $blog_id        Blog ID (unused).
  1663 	 *     @type int    $blog_id        Blog ID (unused).
  1656 	 *     @type string $username       Username.
  1664 	 *     @type string $username       Username.
  1657 	 *     @type string $password       Password.
  1665 	 *     @type string $password       Password.
  1670 		$username       = $args[1];
  1678 		$username       = $args[1];
  1671 		$password       = $args[2];
  1679 		$password       = $args[2];
  1672 		$post_id        = (int) $args[3];
  1680 		$post_id        = (int) $args[3];
  1673 		$content_struct = $args[4];
  1681 		$content_struct = $args[4];
  1674 
  1682 
  1675 		if ( ! $user = $this->login( $username, $password ) ) {
  1683 		$user = $this->login( $username, $password );
       
  1684 		if ( ! $user ) {
  1676 			return $this->error;
  1685 			return $this->error;
  1677 		}
  1686 		}
  1678 
  1687 
  1679 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  1688 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  1680 		do_action( 'xmlrpc_call', 'wp.editPost' );
  1689 		do_action( 'xmlrpc_call', 'wp.editPost' );
  1697 
  1706 
  1698 		/*
  1707 		/*
  1699 		 * Ignore the existing GMT date if it is empty or a non-GMT date was supplied in $content_struct,
  1708 		 * Ignore the existing GMT date if it is empty or a non-GMT date was supplied in $content_struct,
  1700 		 * since _insert_post() will ignore the non-GMT date if the GMT date is set.
  1709 		 * since _insert_post() will ignore the non-GMT date if the GMT date is set.
  1701 		 */
  1710 		 */
  1702 		if ( $post['post_date_gmt'] == '0000-00-00 00:00:00' || isset( $content_struct['post_date'] ) ) {
  1711 		if ( '0000-00-00 00:00:00' === $post['post_date_gmt'] || isset( $content_struct['post_date'] ) ) {
  1703 			unset( $post['post_date_gmt'] );
  1712 			unset( $post['post_date_gmt'] );
  1704 		} else {
  1713 		} else {
  1705 			$post['post_date_gmt'] = $this->_convert_date( $post['post_date_gmt'] );
  1714 			$post['post_date_gmt'] = $this->_convert_date( $post['post_date_gmt'] );
  1706 		}
  1715 		}
  1707 
  1716 
       
  1717 		/*
       
  1718 		 * If the API client did not provide 'post_date', then we must not perpetuate the value that
       
  1719 		 * was stored in the database, or it will appear to be an intentional edit. Conveying it here
       
  1720 		 * as if it was coming from the API client will cause an otherwise zeroed out 'post_date_gmt'
       
  1721 		 * to get set with the value that was originally stored in the database when the draft was created.
       
  1722 		 */
       
  1723 		if ( ! isset( $content_struct['post_date'] ) ) {
       
  1724 			unset( $post['post_date'] );
       
  1725 		}
       
  1726 
  1708 		$this->escape( $post );
  1727 		$this->escape( $post );
  1709 		$merged_content_struct = array_merge( $post, $content_struct );
  1728 		$merged_content_struct = array_merge( $post, $content_struct );
  1710 
  1729 
  1711 		$retval = $this->_insert_post( $user, $merged_content_struct );
  1730 		$retval = $this->_insert_post( $user, $merged_content_struct );
  1712 		if ( $retval instanceof IXR_Error ) {
  1731 		if ( $retval instanceof IXR_Error ) {
  1721 	 *
  1740 	 *
  1722 	 * @since 3.4.0
  1741 	 * @since 3.4.0
  1723 	 *
  1742 	 *
  1724 	 * @see wp_delete_post()
  1743 	 * @see wp_delete_post()
  1725 	 *
  1744 	 *
  1726 	 * @param array  $args {
  1745 	 * @param array $args {
  1727 	 *     Method arguments. Note: arguments must be ordered as documented.
  1746 	 *     Method arguments. Note: arguments must be ordered as documented.
  1728 	 *
  1747 	 *
  1729 	 *     @type int    $blog_id  Blog ID (unused).
  1748 	 *     @type int    $blog_id  Blog ID (unused).
  1730 	 *     @type string $username Username.
  1749 	 *     @type string $username Username.
  1731 	 *     @type string $password Password.
  1750 	 *     @type string $password Password.
  1742 
  1761 
  1743 		$username = $args[1];
  1762 		$username = $args[1];
  1744 		$password = $args[2];
  1763 		$password = $args[2];
  1745 		$post_id  = (int) $args[3];
  1764 		$post_id  = (int) $args[3];
  1746 
  1765 
  1747 		if ( ! $user = $this->login( $username, $password ) ) {
  1766 		$user = $this->login( $username, $password );
       
  1767 		if ( ! $user ) {
  1748 			return $this->error;
  1768 			return $this->error;
  1749 		}
  1769 		}
  1750 
  1770 
  1751 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  1771 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  1752 		do_action( 'xmlrpc_call', 'wp.deletePost' );
  1772 		do_action( 'xmlrpc_call', 'wp.deletePost' );
  1761 		}
  1781 		}
  1762 
  1782 
  1763 		$result = wp_delete_post( $post_id );
  1783 		$result = wp_delete_post( $post_id );
  1764 
  1784 
  1765 		if ( ! $result ) {
  1785 		if ( ! $result ) {
  1766 			return new IXR_Error( 500, __( 'The post cannot be deleted.' ) );
  1786 			return new IXR_Error( 500, __( 'Sorry, the post could not be deleted.' ) );
  1767 		}
  1787 		}
  1768 
  1788 
  1769 		return true;
  1789 		return true;
  1770 	}
  1790 	}
  1771 
  1791 
  1841 			 * @param string $method Method name.
  1861 			 * @param string $method Method name.
  1842 			 */
  1862 			 */
  1843 			$fields = apply_filters( 'xmlrpc_default_post_fields', array( 'post', 'terms', 'custom_fields' ), 'wp.getPost' );
  1863 			$fields = apply_filters( 'xmlrpc_default_post_fields', array( 'post', 'terms', 'custom_fields' ), 'wp.getPost' );
  1844 		}
  1864 		}
  1845 
  1865 
  1846 		if ( ! $user = $this->login( $username, $password ) ) {
  1866 		$user = $this->login( $username, $password );
       
  1867 		if ( ! $user ) {
  1847 			return $this->error;
  1868 			return $this->error;
  1848 		}
  1869 		}
  1849 
  1870 
  1850 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  1871 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  1851 		do_action( 'xmlrpc_call', 'wp.getPost' );
  1872 		do_action( 'xmlrpc_call', 'wp.getPost' );
  1901 		} else {
  1922 		} else {
  1902 			/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  1923 			/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  1903 			$fields = apply_filters( 'xmlrpc_default_post_fields', array( 'post', 'terms', 'custom_fields' ), 'wp.getPosts' );
  1924 			$fields = apply_filters( 'xmlrpc_default_post_fields', array( 'post', 'terms', 'custom_fields' ), 'wp.getPosts' );
  1904 		}
  1925 		}
  1905 
  1926 
  1906 		if ( ! $user = $this->login( $username, $password ) ) {
  1927 		$user = $this->login( $username, $password );
       
  1928 		if ( ! $user ) {
  1907 			return $this->error;
  1929 			return $this->error;
  1908 		}
  1930 		}
  1909 
  1931 
  1910 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  1932 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  1911 		do_action( 'xmlrpc_call', 'wp.getPosts' );
  1933 		do_action( 'xmlrpc_call', 'wp.getPosts' );
  1999 
  2021 
  2000 		$username       = $args[1];
  2022 		$username       = $args[1];
  2001 		$password       = $args[2];
  2023 		$password       = $args[2];
  2002 		$content_struct = $args[3];
  2024 		$content_struct = $args[3];
  2003 
  2025 
  2004 		if ( ! $user = $this->login( $username, $password ) ) {
  2026 		$user = $this->login( $username, $password );
       
  2027 		if ( ! $user ) {
  2005 			return $this->error;
  2028 			return $this->error;
  2006 		}
  2029 		}
  2007 
  2030 
  2008 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2031 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2009 		do_action( 'xmlrpc_call', 'wp.newTerm' );
  2032 		do_action( 'xmlrpc_call', 'wp.newTerm' );
  2018 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to create terms in this taxonomy.' ) );
  2041 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to create terms in this taxonomy.' ) );
  2019 		}
  2042 		}
  2020 
  2043 
  2021 		$taxonomy = (array) $taxonomy;
  2044 		$taxonomy = (array) $taxonomy;
  2022 
  2045 
  2023 		// hold the data of the term
  2046 		// Hold the data of the term.
  2024 		$term_data = array();
  2047 		$term_data = array();
  2025 
  2048 
  2026 		$term_data['name'] = trim( $content_struct['name'] );
  2049 		$term_data['name'] = trim( $content_struct['name'] );
  2027 		if ( empty( $term_data['name'] ) ) {
  2050 		if ( empty( $term_data['name'] ) ) {
  2028 			return new IXR_Error( 403, __( 'The term name cannot be empty.' ) );
  2051 			return new IXR_Error( 403, __( 'The term name cannot be empty.' ) );
  2060 		if ( is_wp_error( $term ) ) {
  2083 		if ( is_wp_error( $term ) ) {
  2061 			return new IXR_Error( 500, $term->get_error_message() );
  2084 			return new IXR_Error( 500, $term->get_error_message() );
  2062 		}
  2085 		}
  2063 
  2086 
  2064 		if ( ! $term ) {
  2087 		if ( ! $term ) {
  2065 			return new IXR_Error( 500, __( 'Sorry, your term could not be created.' ) );
  2088 			return new IXR_Error( 500, __( 'Sorry, the term could not be created.' ) );
  2066 		}
  2089 		}
  2067 
  2090 
  2068 		// Add term meta.
  2091 		// Add term meta.
  2069 		if ( isset( $content_struct['custom_fields'] ) ) {
  2092 		if ( isset( $content_struct['custom_fields'] ) ) {
  2070 			$this->set_term_custom_fields( $term['term_id'], $content_struct['custom_fields'] );
  2093 			$this->set_term_custom_fields( $term['term_id'], $content_struct['custom_fields'] );
  2103 		$username       = $args[1];
  2126 		$username       = $args[1];
  2104 		$password       = $args[2];
  2127 		$password       = $args[2];
  2105 		$term_id        = (int) $args[3];
  2128 		$term_id        = (int) $args[3];
  2106 		$content_struct = $args[4];
  2129 		$content_struct = $args[4];
  2107 
  2130 
  2108 		if ( ! $user = $this->login( $username, $password ) ) {
  2131 		$user = $this->login( $username, $password );
       
  2132 		if ( ! $user ) {
  2109 			return $this->error;
  2133 			return $this->error;
  2110 		}
  2134 		}
  2111 
  2135 
  2112 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2136 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2113 		do_action( 'xmlrpc_call', 'wp.editTerm' );
  2137 		do_action( 'xmlrpc_call', 'wp.editTerm' );
  2118 
  2142 
  2119 		$taxonomy = get_taxonomy( $content_struct['taxonomy'] );
  2143 		$taxonomy = get_taxonomy( $content_struct['taxonomy'] );
  2120 
  2144 
  2121 		$taxonomy = (array) $taxonomy;
  2145 		$taxonomy = (array) $taxonomy;
  2122 
  2146 
  2123 		// hold the data of the term
  2147 		// Hold the data of the term.
  2124 		$term_data = array();
  2148 		$term_data = array();
  2125 
  2149 
  2126 		$term = get_term( $term_id, $content_struct['taxonomy'] );
  2150 		$term = get_term( $term_id, $content_struct['taxonomy'] );
  2127 
  2151 
  2128 		if ( is_wp_error( $term ) ) {
  2152 		if ( is_wp_error( $term ) ) {
  2195 	 *
  2219 	 *
  2196 	 * @since 3.4.0
  2220 	 * @since 3.4.0
  2197 	 *
  2221 	 *
  2198 	 * @see wp_delete_term()
  2222 	 * @see wp_delete_term()
  2199 	 *
  2223 	 *
  2200 	 * @param array  $args {
  2224 	 * @param array $args {
  2201 	 *     Method arguments. Note: arguments must be ordered as documented.
  2225 	 *     Method arguments. Note: arguments must be ordered as documented.
  2202 	 *
  2226 	 *
  2203 	 *     @type int    $blog_id      Blog ID (unused).
  2227 	 *     @type int    $blog_id      Blog ID (unused).
  2204 	 *     @type string $username     Username.
  2228 	 *     @type string $username     Username.
  2205 	 *     @type string $password     Password.
  2229 	 *     @type string $password     Password.
  2218 		$username = $args[1];
  2242 		$username = $args[1];
  2219 		$password = $args[2];
  2243 		$password = $args[2];
  2220 		$taxonomy = $args[3];
  2244 		$taxonomy = $args[3];
  2221 		$term_id  = (int) $args[4];
  2245 		$term_id  = (int) $args[4];
  2222 
  2246 
  2223 		if ( ! $user = $this->login( $username, $password ) ) {
  2247 		$user = $this->login( $username, $password );
       
  2248 		if ( ! $user ) {
  2224 			return $this->error;
  2249 			return $this->error;
  2225 		}
  2250 		}
  2226 
  2251 
  2227 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2252 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2228 		do_action( 'xmlrpc_call', 'wp.deleteTerm' );
  2253 		do_action( 'xmlrpc_call', 'wp.deleteTerm' );
  2264 	 *
  2289 	 *
  2265 	 * @since 3.4.0
  2290 	 * @since 3.4.0
  2266 	 *
  2291 	 *
  2267 	 * @see get_term()
  2292 	 * @see get_term()
  2268 	 *
  2293 	 *
  2269 	 * @param array  $args {
  2294 	 * @param array $args {
  2270 	 *     Method arguments. Note: arguments must be ordered as documented.
  2295 	 *     Method arguments. Note: arguments must be ordered as documented.
  2271 	 *
  2296 	 *
  2272 	 *     @type int    $blog_id  Blog ID (unused).
  2297 	 *     @type int    $blog_id  Blog ID (unused).
  2273 	 *     @type string $username Username.
  2298 	 *     @type string $username Username.
  2274 	 *     @type string $password Password.
  2299 	 *     @type string $password Password.
  2296 		$username = $args[1];
  2321 		$username = $args[1];
  2297 		$password = $args[2];
  2322 		$password = $args[2];
  2298 		$taxonomy = $args[3];
  2323 		$taxonomy = $args[3];
  2299 		$term_id  = (int) $args[4];
  2324 		$term_id  = (int) $args[4];
  2300 
  2325 
  2301 		if ( ! $user = $this->login( $username, $password ) ) {
  2326 		$user = $this->login( $username, $password );
       
  2327 		if ( ! $user ) {
  2302 			return $this->error;
  2328 			return $this->error;
  2303 		}
  2329 		}
  2304 
  2330 
  2305 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2331 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2306 		do_action( 'xmlrpc_call', 'wp.getTerm' );
  2332 		do_action( 'xmlrpc_call', 'wp.getTerm' );
  2336 	 * The optional $filter parameter modifies the query used to retrieve terms.
  2362 	 * The optional $filter parameter modifies the query used to retrieve terms.
  2337 	 * Accepted keys are 'number', 'offset', 'orderby', 'order', 'hide_empty', and 'search'.
  2363 	 * Accepted keys are 'number', 'offset', 'orderby', 'order', 'hide_empty', and 'search'.
  2338 	 *
  2364 	 *
  2339 	 * @see get_terms()
  2365 	 * @see get_terms()
  2340 	 *
  2366 	 *
  2341 	 * @param array  $args {
  2367 	 * @param array $args {
  2342 	 *     Method arguments. Note: arguments must be ordered as documented.
  2368 	 *     Method arguments. Note: arguments must be ordered as documented.
  2343 	 *
  2369 	 *
  2344 	 *     @type int    $blog_id  Blog ID (unused).
  2370 	 *     @type int    $blog_id  Blog ID (unused).
  2345 	 *     @type string $username Username.
  2371 	 *     @type string $username Username.
  2346 	 *     @type string $password Password.
  2372 	 *     @type string $password Password.
  2360 		$username = $args[1];
  2386 		$username = $args[1];
  2361 		$password = $args[2];
  2387 		$password = $args[2];
  2362 		$taxonomy = $args[3];
  2388 		$taxonomy = $args[3];
  2363 		$filter   = isset( $args[4] ) ? $args[4] : array();
  2389 		$filter   = isset( $args[4] ) ? $args[4] : array();
  2364 
  2390 
  2365 		if ( ! $user = $this->login( $username, $password ) ) {
  2391 		$user = $this->login( $username, $password );
       
  2392 		if ( ! $user ) {
  2366 			return $this->error;
  2393 			return $this->error;
  2367 		}
  2394 		}
  2368 
  2395 
  2369 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2396 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2370 		do_action( 'xmlrpc_call', 'wp.getTerms' );
  2397 		do_action( 'xmlrpc_call', 'wp.getTerms' );
  2377 
  2404 
  2378 		if ( ! current_user_can( $taxonomy->cap->assign_terms ) ) {
  2405 		if ( ! current_user_can( $taxonomy->cap->assign_terms ) ) {
  2379 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to assign terms in this taxonomy.' ) );
  2406 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to assign terms in this taxonomy.' ) );
  2380 		}
  2407 		}
  2381 
  2408 
  2382 		$query = array();
  2409 		$query = array( 'taxonomy' => $taxonomy->name );
  2383 
  2410 
  2384 		if ( isset( $filter['number'] ) ) {
  2411 		if ( isset( $filter['number'] ) ) {
  2385 			$query['number'] = absint( $filter['number'] );
  2412 			$query['number'] = absint( $filter['number'] );
  2386 		}
  2413 		}
  2387 
  2414 
  2405 
  2432 
  2406 		if ( isset( $filter['search'] ) ) {
  2433 		if ( isset( $filter['search'] ) ) {
  2407 			$query['search'] = $filter['search'];
  2434 			$query['search'] = $filter['search'];
  2408 		}
  2435 		}
  2409 
  2436 
  2410 		$terms = get_terms( $taxonomy->name, $query );
  2437 		$terms = get_terms( $query );
  2411 
  2438 
  2412 		if ( is_wp_error( $terms ) ) {
  2439 		if ( is_wp_error( $terms ) ) {
  2413 			return new IXR_Error( 500, $terms->get_error_message() );
  2440 			return new IXR_Error( 500, $terms->get_error_message() );
  2414 		}
  2441 		}
  2415 
  2442 
  2427 	 *
  2454 	 *
  2428 	 * @since 3.4.0
  2455 	 * @since 3.4.0
  2429 	 *
  2456 	 *
  2430 	 * @see get_taxonomy()
  2457 	 * @see get_taxonomy()
  2431 	 *
  2458 	 *
  2432 	 * @param array  $args {
  2459 	 * @param array $args {
  2433 	 *     Method arguments. Note: arguments must be ordered as documented.
  2460 	 *     Method arguments. Note: arguments must be ordered as documented.
  2434 	 *
  2461 	 *
  2435 	 *     @type int    $blog_id  Blog ID (unused).
  2462 	 *     @type int    $blog_id  Blog ID (unused).
  2436 	 *     @type string $username Username.
  2463 	 *     @type string $username Username.
  2437 	 *     @type string $password Password.
  2464 	 *     @type string $password Password.
  2465 			 * @param string $method The method name.
  2492 			 * @param string $method The method name.
  2466 			 */
  2493 			 */
  2467 			$fields = apply_filters( 'xmlrpc_default_taxonomy_fields', array( 'labels', 'cap', 'object_type' ), 'wp.getTaxonomy' );
  2494 			$fields = apply_filters( 'xmlrpc_default_taxonomy_fields', array( 'labels', 'cap', 'object_type' ), 'wp.getTaxonomy' );
  2468 		}
  2495 		}
  2469 
  2496 
  2470 		if ( ! $user = $this->login( $username, $password ) ) {
  2497 		$user = $this->login( $username, $password );
       
  2498 		if ( ! $user ) {
  2471 			return $this->error;
  2499 			return $this->error;
  2472 		}
  2500 		}
  2473 
  2501 
  2474 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2502 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2475 		do_action( 'xmlrpc_call', 'wp.getTaxonomy' );
  2503 		do_action( 'xmlrpc_call', 'wp.getTaxonomy' );
  2492 	 *
  2520 	 *
  2493 	 * @since 3.4.0
  2521 	 * @since 3.4.0
  2494 	 *
  2522 	 *
  2495 	 * @see get_taxonomies()
  2523 	 * @see get_taxonomies()
  2496 	 *
  2524 	 *
  2497 	 * @param array  $args {
  2525 	 * @param array $args {
  2498 	 *     Method arguments. Note: arguments must be ordered as documented.
  2526 	 *     Method arguments. Note: arguments must be ordered as documented.
  2499 	 *
  2527 	 *
  2500 	 *     @type int    $blog_id  Blog ID (unused).
  2528 	 *     @type int    $blog_id  Blog ID (unused).
  2501 	 *     @type string $username Username.
  2529 	 *     @type string $username Username.
  2502 	 *     @type string $password Password.
  2530 	 *     @type string $password Password.
  2522 		} else {
  2550 		} else {
  2523 			/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2551 			/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2524 			$fields = apply_filters( 'xmlrpc_default_taxonomy_fields', array( 'labels', 'cap', 'object_type' ), 'wp.getTaxonomies' );
  2552 			$fields = apply_filters( 'xmlrpc_default_taxonomy_fields', array( 'labels', 'cap', 'object_type' ), 'wp.getTaxonomies' );
  2525 		}
  2553 		}
  2526 
  2554 
  2527 		if ( ! $user = $this->login( $username, $password ) ) {
  2555 		$user = $this->login( $username, $password );
       
  2556 		if ( ! $user ) {
  2528 			return $this->error;
  2557 			return $this->error;
  2529 		}
  2558 		}
  2530 
  2559 
  2531 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2560 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2532 		do_action( 'xmlrpc_call', 'wp.getTaxonomies' );
  2561 		do_action( 'xmlrpc_call', 'wp.getTaxonomies' );
  2533 
  2562 
  2534 		$taxonomies = get_taxonomies( $filter, 'objects' );
  2563 		$taxonomies = get_taxonomies( $filter, 'objects' );
  2535 
  2564 
  2536 		// holds all the taxonomy data
  2565 		// Holds all the taxonomy data.
  2537 		$struct = array();
  2566 		$struct = array();
  2538 
  2567 
  2539 		foreach ( $taxonomies as $taxonomy ) {
  2568 		foreach ( $taxonomies as $taxonomy ) {
  2540 			// capability check for post_types
  2569 			// Capability check for post types.
  2541 			if ( ! current_user_can( $taxonomy->cap->assign_terms ) ) {
  2570 			if ( ! current_user_can( $taxonomy->cap->assign_terms ) ) {
  2542 				continue;
  2571 				continue;
  2543 			}
  2572 			}
  2544 
  2573 
  2545 			$struct[] = $this->_prepare_taxonomy( $taxonomy, $fields );
  2574 			$struct[] = $this->_prepare_taxonomy( $taxonomy, $fields );
  2559 	 * names can be used to specify multiple fields. The available conceptual
  2588 	 * names can be used to specify multiple fields. The available conceptual
  2560 	 * groups are 'basic' and 'all'.
  2589 	 * groups are 'basic' and 'all'.
  2561 	 *
  2590 	 *
  2562 	 * @uses get_userdata()
  2591 	 * @uses get_userdata()
  2563 	 *
  2592 	 *
  2564 	 * @param array  $args {
  2593 	 * @param array $args {
  2565 	 *     Method arguments. Note: arguments must be ordered as documented.
  2594 	 *     Method arguments. Note: arguments must be ordered as documented.
  2566 	 *
  2595 	 *
  2567 	 *     @type int    $blog_id (unused)
  2596 	 *     @type int    $blog_id (unused)
  2568 	 *     @type string $username
  2597 	 *     @type string $username
  2569 	 *     @type string $password
  2598 	 *     @type string $password
  2607 			 * @param string $method The method name.
  2636 			 * @param string $method The method name.
  2608 			 */
  2637 			 */
  2609 			$fields = apply_filters( 'xmlrpc_default_user_fields', array( 'all' ), 'wp.getUser' );
  2638 			$fields = apply_filters( 'xmlrpc_default_user_fields', array( 'all' ), 'wp.getUser' );
  2610 		}
  2639 		}
  2611 
  2640 
  2612 		if ( ! $user = $this->login( $username, $password ) ) {
  2641 		$user = $this->login( $username, $password );
       
  2642 		if ( ! $user ) {
  2613 			return $this->error;
  2643 			return $this->error;
  2614 		}
  2644 		}
  2615 
  2645 
  2616 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2646 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2617 		do_action( 'xmlrpc_call', 'wp.getUser' );
  2647 		do_action( 'xmlrpc_call', 'wp.getUser' );
  2640 	 * in the response array.
  2670 	 * in the response array.
  2641 	 *
  2671 	 *
  2642 	 * @uses get_users()
  2672 	 * @uses get_users()
  2643 	 * @see wp_getUser() for more on $fields and return values
  2673 	 * @see wp_getUser() for more on $fields and return values
  2644 	 *
  2674 	 *
  2645 	 * @param array  $args {
  2675 	 * @param array $args {
  2646 	 *     Method arguments. Note: arguments must be ordered as documented.
  2676 	 *     Method arguments. Note: arguments must be ordered as documented.
  2647 	 *
  2677 	 *
  2648 	 *     @type int    $blog_id (unused)
  2678 	 *     @type int    $blog_id (unused)
  2649 	 *     @type string $username
  2679 	 *     @type string $username
  2650 	 *     @type string $password
  2680 	 *     @type string $password
  2669 		} else {
  2699 		} else {
  2670 			/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2700 			/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2671 			$fields = apply_filters( 'xmlrpc_default_user_fields', array( 'all' ), 'wp.getUsers' );
  2701 			$fields = apply_filters( 'xmlrpc_default_user_fields', array( 'all' ), 'wp.getUsers' );
  2672 		}
  2702 		}
  2673 
  2703 
  2674 		if ( ! $user = $this->login( $username, $password ) ) {
  2704 		$user = $this->login( $username, $password );
       
  2705 		if ( ! $user ) {
  2675 			return $this->error;
  2706 			return $this->error;
  2676 		}
  2707 		}
  2677 
  2708 
  2678 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2709 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2679 		do_action( 'xmlrpc_call', 'wp.getUsers' );
  2710 		do_action( 'xmlrpc_call', 'wp.getUsers' );
  2721 	/**
  2752 	/**
  2722 	 * Retrieve information about the requesting user.
  2753 	 * Retrieve information about the requesting user.
  2723 	 *
  2754 	 *
  2724 	 * @uses get_userdata()
  2755 	 * @uses get_userdata()
  2725 	 *
  2756 	 *
  2726 	 * @param array  $args {
  2757 	 * @param array $args {
  2727 	 *     Method arguments. Note: arguments must be ordered as documented.
  2758 	 *     Method arguments. Note: arguments must be ordered as documented.
  2728 	 *
  2759 	 *
  2729 	 *     @type int    $blog_id (unused)
  2760 	 *     @type int    $blog_id (unused)
  2730 	 *     @type string $username
  2761 	 *     @type string $username
  2731 	 *     @type string $password
  2762 	 *     @type string $password
  2748 		} else {
  2779 		} else {
  2749 			/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2780 			/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2750 			$fields = apply_filters( 'xmlrpc_default_user_fields', array( 'all' ), 'wp.getProfile' );
  2781 			$fields = apply_filters( 'xmlrpc_default_user_fields', array( 'all' ), 'wp.getProfile' );
  2751 		}
  2782 		}
  2752 
  2783 
  2753 		if ( ! $user = $this->login( $username, $password ) ) {
  2784 		$user = $this->login( $username, $password );
       
  2785 		if ( ! $user ) {
  2754 			return $this->error;
  2786 			return $this->error;
  2755 		}
  2787 		}
  2756 
  2788 
  2757 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2789 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2758 		do_action( 'xmlrpc_call', 'wp.getProfile' );
  2790 		do_action( 'xmlrpc_call', 'wp.getProfile' );
  2769 	/**
  2801 	/**
  2770 	 * Edit user's profile.
  2802 	 * Edit user's profile.
  2771 	 *
  2803 	 *
  2772 	 * @uses wp_update_user()
  2804 	 * @uses wp_update_user()
  2773 	 *
  2805 	 *
  2774 	 * @param array  $args {
  2806 	 * @param array $args {
  2775 	 *     Method arguments. Note: arguments must be ordered as documented.
  2807 	 *     Method arguments. Note: arguments must be ordered as documented.
  2776 	 *
  2808 	 *
  2777 	 *     @type int    $blog_id (unused)
  2809 	 *     @type int    $blog_id (unused)
  2778 	 *     @type string $username
  2810 	 *     @type string $username
  2779 	 *     @type string $password
  2811 	 *     @type string $password
  2797 
  2829 
  2798 		$username       = $args[1];
  2830 		$username       = $args[1];
  2799 		$password       = $args[2];
  2831 		$password       = $args[2];
  2800 		$content_struct = $args[3];
  2832 		$content_struct = $args[3];
  2801 
  2833 
  2802 		if ( ! $user = $this->login( $username, $password ) ) {
  2834 		$user = $this->login( $username, $password );
       
  2835 		if ( ! $user ) {
  2803 			return $this->error;
  2836 			return $this->error;
  2804 		}
  2837 		}
  2805 
  2838 
  2806 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2839 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2807 		do_action( 'xmlrpc_call', 'wp.editProfile' );
  2840 		do_action( 'xmlrpc_call', 'wp.editProfile' );
  2808 
  2841 
  2809 		if ( ! current_user_can( 'edit_user', $user->ID ) ) {
  2842 		if ( ! current_user_can( 'edit_user', $user->ID ) ) {
  2810 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit your profile.' ) );
  2843 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit your profile.' ) );
  2811 		}
  2844 		}
  2812 
  2845 
  2813 		// holds data of the user
  2846 		// Holds data of the user.
  2814 		$user_data       = array();
  2847 		$user_data       = array();
  2815 		$user_data['ID'] = $user->ID;
  2848 		$user_data['ID'] = $user->ID;
  2816 
  2849 
  2817 		// only set the user details if it was given
  2850 		// Only set the user details if they were given.
  2818 		if ( isset( $content_struct['first_name'] ) ) {
  2851 		if ( isset( $content_struct['first_name'] ) ) {
  2819 			$user_data['first_name'] = $content_struct['first_name'];
  2852 			$user_data['first_name'] = $content_struct['first_name'];
  2820 		}
  2853 		}
  2821 
  2854 
  2822 		if ( isset( $content_struct['last_name'] ) ) {
  2855 		if ( isset( $content_struct['last_name'] ) ) {
  2848 		if ( is_wp_error( $result ) ) {
  2881 		if ( is_wp_error( $result ) ) {
  2849 			return new IXR_Error( 500, $result->get_error_message() );
  2882 			return new IXR_Error( 500, $result->get_error_message() );
  2850 		}
  2883 		}
  2851 
  2884 
  2852 		if ( ! $result ) {
  2885 		if ( ! $result ) {
  2853 			return new IXR_Error( 500, __( 'Sorry, the user cannot be updated.' ) );
  2886 			return new IXR_Error( 500, __( 'Sorry, the user could not be updated.' ) );
  2854 		}
  2887 		}
  2855 
  2888 
  2856 		return true;
  2889 		return true;
  2857 	}
  2890 	}
  2858 
  2891 
  2859 	/**
  2892 	/**
  2860 	 * Retrieve page.
  2893 	 * Retrieve page.
  2861 	 *
  2894 	 *
  2862 	 * @since 2.2.0
  2895 	 * @since 2.2.0
  2863 	 *
  2896 	 *
  2864 	 * @param array  $args {
  2897 	 * @param array $args {
  2865 	 *     Method arguments. Note: arguments must be ordered as documented.
  2898 	 *     Method arguments. Note: arguments must be ordered as documented.
  2866 	 *
  2899 	 *
  2867 	 *     @type int    $blog_id (unused)
  2900 	 *     @type int    $blog_id (unused)
  2868 	 *     @type int    $page_id
  2901 	 *     @type int    $page_id
  2869 	 *     @type string $username
  2902 	 *     @type string $username
  2876 
  2909 
  2877 		$page_id  = (int) $args[1];
  2910 		$page_id  = (int) $args[1];
  2878 		$username = $args[2];
  2911 		$username = $args[2];
  2879 		$password = $args[3];
  2912 		$password = $args[3];
  2880 
  2913 
  2881 		if ( ! $user = $this->login( $username, $password ) ) {
  2914 		$user = $this->login( $username, $password );
       
  2915 		if ( ! $user ) {
  2882 			return $this->error;
  2916 			return $this->error;
  2883 		}
  2917 		}
  2884 
  2918 
  2885 		$page = get_post( $page_id );
  2919 		$page = get_post( $page_id );
  2886 		if ( ! $page ) {
  2920 		if ( ! $page ) {
  2893 
  2927 
  2894 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2928 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  2895 		do_action( 'xmlrpc_call', 'wp.getPage' );
  2929 		do_action( 'xmlrpc_call', 'wp.getPage' );
  2896 
  2930 
  2897 		// If we found the page then format the data.
  2931 		// If we found the page then format the data.
  2898 		if ( $page->ID && ( $page->post_type == 'page' ) ) {
  2932 		if ( $page->ID && ( 'page' === $page->post_type ) ) {
  2899 			return $this->_prepare_page( $page );
  2933 			return $this->_prepare_page( $page );
  2900 		} else {
  2934 		} else {
  2901 			// If the page doesn't exist indicate that.
  2935 			// If the page doesn't exist, indicate that.
  2902 			return new IXR_Error( 404, __( 'Sorry, no such page.' ) );
  2936 			return new IXR_Error( 404, __( 'Sorry, no such page.' ) );
  2903 		}
  2937 		}
  2904 	}
  2938 	}
  2905 
  2939 
  2906 	/**
  2940 	/**
  2907 	 * Retrieve Pages.
  2941 	 * Retrieve Pages.
  2908 	 *
  2942 	 *
  2909 	 * @since 2.2.0
  2943 	 * @since 2.2.0
  2910 	 *
  2944 	 *
  2911 	 * @param array  $args {
  2945 	 * @param array $args {
  2912 	 *     Method arguments. Note: arguments must be ordered as documented.
  2946 	 *     Method arguments. Note: arguments must be ordered as documented.
  2913 	 *
  2947 	 *
  2914 	 *     @type int    $blog_id (unused)
  2948 	 *     @type int    $blog_id (unused)
  2915 	 *     @type string $username
  2949 	 *     @type string $username
  2916 	 *     @type string $password
  2950 	 *     @type string $password
  2923 
  2957 
  2924 		$username  = $args[1];
  2958 		$username  = $args[1];
  2925 		$password  = $args[2];
  2959 		$password  = $args[2];
  2926 		$num_pages = isset( $args[3] ) ? (int) $args[3] : 10;
  2960 		$num_pages = isset( $args[3] ) ? (int) $args[3] : 10;
  2927 
  2961 
  2928 		if ( ! $user = $this->login( $username, $password ) ) {
  2962 		$user = $this->login( $username, $password );
       
  2963 		if ( ! $user ) {
  2929 			return $this->error;
  2964 			return $this->error;
  2930 		}
  2965 		}
  2931 
  2966 
  2932 		if ( ! current_user_can( 'edit_pages' ) ) {
  2967 		if ( ! current_user_can( 'edit_pages' ) ) {
  2933 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit pages.' ) );
  2968 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit pages.' ) );
  2966 	 *
  3001 	 *
  2967 	 * @since 2.2.0
  3002 	 * @since 2.2.0
  2968 	 *
  3003 	 *
  2969 	 * @see wp_xmlrpc_server::mw_newPost()
  3004 	 * @see wp_xmlrpc_server::mw_newPost()
  2970 	 *
  3005 	 *
  2971 	 * @param array  $args {
  3006 	 * @param array $args {
  2972 	 *     Method arguments. Note: arguments must be ordered as documented.
  3007 	 *     Method arguments. Note: arguments must be ordered as documented.
  2973 	 *
  3008 	 *
  2974 	 *     @type int    $blog_id (unused)
  3009 	 *     @type int    $blog_id (unused)
  2975 	 *     @type string $username
  3010 	 *     @type string $username
  2976 	 *     @type string $password
  3011 	 *     @type string $password
  2977 	 *     @type array  $content_struct
  3012 	 *     @type array  $content_struct
  2978 	 * }
  3013 	 * }
  2979 	 * @return int|IXR_Error
  3014 	 * @return int|IXR_Error
  2980 	 */
  3015 	 */
  2981 	public function wp_newPage( $args ) {
  3016 	public function wp_newPage( $args ) {
  2982 		// Items not escaped here will be escaped in newPost.
  3017 		// Items not escaped here will be escaped in wp_newPost().
  2983 		$username = $this->escape( $args[1] );
  3018 		$username = $this->escape( $args[1] );
  2984 		$password = $this->escape( $args[2] );
  3019 		$password = $this->escape( $args[2] );
  2985 
  3020 
  2986 		if ( ! $user = $this->login( $username, $password ) ) {
  3021 		$user = $this->login( $username, $password );
       
  3022 		if ( ! $user ) {
  2987 			return $this->error;
  3023 			return $this->error;
  2988 		}
  3024 		}
  2989 
  3025 
  2990 		/** 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 */
  2991 		do_action( 'xmlrpc_call', 'wp.newPage' );
  3027 		do_action( 'xmlrpc_call', 'wp.newPage' );
  2992 
  3028 
  2993 		// Mark this as content for a page.
  3029 		// Mark this as content for a page.
  2994 		$args[3]['post_type'] = 'page';
  3030 		$args[3]['post_type'] = 'page';
  2995 
  3031 
  2996 		// Let mw_newPost do all of the heavy lifting.
  3032 		// Let mw_newPost() do all of the heavy lifting.
  2997 		return $this->mw_newPost( $args );
  3033 		return $this->mw_newPost( $args );
  2998 	}
  3034 	}
  2999 
  3035 
  3000 	/**
  3036 	/**
  3001 	 * Delete page.
  3037 	 * Delete page.
  3002 	 *
  3038 	 *
  3003 	 * @since 2.2.0
  3039 	 * @since 2.2.0
  3004 	 *
  3040 	 *
  3005 	 * @param array  $args {
  3041 	 * @param array $args {
  3006 	 *     Method arguments. Note: arguments must be ordered as documented.
  3042 	 *     Method arguments. Note: arguments must be ordered as documented.
  3007 	 *
  3043 	 *
  3008 	 *     @type int    $blog_id (unused)
  3044 	 *     @type int    $blog_id (unused)
  3009 	 *     @type string $username
  3045 	 *     @type string $username
  3010 	 *     @type string $password
  3046 	 *     @type string $password
  3017 
  3053 
  3018 		$username = $args[1];
  3054 		$username = $args[1];
  3019 		$password = $args[2];
  3055 		$password = $args[2];
  3020 		$page_id  = (int) $args[3];
  3056 		$page_id  = (int) $args[3];
  3021 
  3057 
  3022 		if ( ! $user = $this->login( $username, $password ) ) {
  3058 		$user = $this->login( $username, $password );
       
  3059 		if ( ! $user ) {
  3023 			return $this->error;
  3060 			return $this->error;
  3024 		}
  3061 		}
  3025 
  3062 
  3026 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3063 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3027 		do_action( 'xmlrpc_call', 'wp.deletePage' );
  3064 		do_action( 'xmlrpc_call', 'wp.deletePage' );
  3028 
  3065 
  3029 		// Get the current page based on the page_id and
  3066 		// Get the current page based on the 'page_id' and
  3030 		// make sure it is a page and not a post.
  3067 		// make sure it is a page and not a post.
  3031 		$actual_page = get_post( $page_id, ARRAY_A );
  3068 		$actual_page = get_post( $page_id, ARRAY_A );
  3032 		if ( ! $actual_page || ( $actual_page['post_type'] != 'page' ) ) {
  3069 		if ( ! $actual_page || ( 'page' !== $actual_page['post_type'] ) ) {
  3033 			return new IXR_Error( 404, __( 'Sorry, no such page.' ) );
  3070 			return new IXR_Error( 404, __( 'Sorry, no such page.' ) );
  3034 		}
  3071 		}
  3035 
  3072 
  3036 		// Make sure the user can delete pages.
  3073 		// Make sure the user can delete pages.
  3037 		if ( ! current_user_can( 'delete_page', $page_id ) ) {
  3074 		if ( ! current_user_can( 'delete_page', $page_id ) ) {
  3050 		 * @since 3.4.0
  3087 		 * @since 3.4.0
  3051 		 *
  3088 		 *
  3052 		 * @param int   $page_id ID of the deleted page.
  3089 		 * @param int   $page_id ID of the deleted page.
  3053 		 * @param array $args    An array of arguments to delete the page.
  3090 		 * @param array $args    An array of arguments to delete the page.
  3054 		 */
  3091 		 */
  3055 		do_action( 'xmlrpc_call_success_wp_deletePage', $page_id, $args );
  3092 		do_action( 'xmlrpc_call_success_wp_deletePage', $page_id, $args ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.NotLowercase
  3056 
  3093 
  3057 		return true;
  3094 		return true;
  3058 	}
  3095 	}
  3059 
  3096 
  3060 	/**
  3097 	/**
  3061 	 * Edit page.
  3098 	 * Edit page.
  3062 	 *
  3099 	 *
  3063 	 * @since 2.2.0
  3100 	 * @since 2.2.0
  3064 	 *
  3101 	 *
  3065 	 * @param array  $args {
  3102 	 * @param array $args {
  3066 	 *     Method arguments. Note: arguments must be ordered as documented.
  3103 	 *     Method arguments. Note: arguments must be ordered as documented.
  3067 	 *
  3104 	 *
  3068 	 *     @type int    $blog_id (unused)
  3105 	 *     @type int    $blog_id (unused)
  3069 	 *     @type int    $page_id
  3106 	 *     @type int    $page_id
  3070 	 *     @type string $username
  3107 	 *     @type string $username
  3073 	 *     @type string $publish
  3110 	 *     @type string $publish
  3074 	 * }
  3111 	 * }
  3075 	 * @return array|IXR_Error
  3112 	 * @return array|IXR_Error
  3076 	 */
  3113 	 */
  3077 	public function wp_editPage( $args ) {
  3114 	public function wp_editPage( $args ) {
  3078 		// Items will be escaped in mw_editPost.
  3115 		// Items will be escaped in mw_editPost().
  3079 		$page_id  = (int) $args[1];
  3116 		$page_id  = (int) $args[1];
  3080 		$username = $args[2];
  3117 		$username = $args[2];
  3081 		$password = $args[3];
  3118 		$password = $args[3];
  3082 		$content  = $args[4];
  3119 		$content  = $args[4];
  3083 		$publish  = $args[5];
  3120 		$publish  = $args[5];
  3084 
  3121 
  3085 		$escaped_username = $this->escape( $username );
  3122 		$escaped_username = $this->escape( $username );
  3086 		$escaped_password = $this->escape( $password );
  3123 		$escaped_password = $this->escape( $password );
  3087 
  3124 
  3088 		if ( ! $user = $this->login( $escaped_username, $escaped_password ) ) {
  3125 		$user = $this->login( $escaped_username, $escaped_password );
       
  3126 		if ( ! $user ) {
  3089 			return $this->error;
  3127 			return $this->error;
  3090 		}
  3128 		}
  3091 
  3129 
  3092 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3130 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3093 		do_action( 'xmlrpc_call', 'wp.editPage' );
  3131 		do_action( 'xmlrpc_call', 'wp.editPage' );
  3094 
  3132 
  3095 		// Get the page data and make sure it is a page.
  3133 		// Get the page data and make sure it is a page.
  3096 		$actual_page = get_post( $page_id, ARRAY_A );
  3134 		$actual_page = get_post( $page_id, ARRAY_A );
  3097 		if ( ! $actual_page || ( $actual_page['post_type'] != 'page' ) ) {
  3135 		if ( ! $actual_page || ( 'page' !== $actual_page['post_type'] ) ) {
  3098 			return new IXR_Error( 404, __( 'Sorry, no such page.' ) );
  3136 			return new IXR_Error( 404, __( 'Sorry, no such page.' ) );
  3099 		}
  3137 		}
  3100 
  3138 
  3101 		// Make sure the user is allowed to edit pages.
  3139 		// Make sure the user is allowed to edit pages.
  3102 		if ( ! current_user_can( 'edit_page', $page_id ) ) {
  3140 		if ( ! current_user_can( 'edit_page', $page_id ) ) {
  3104 		}
  3142 		}
  3105 
  3143 
  3106 		// Mark this as content for a page.
  3144 		// Mark this as content for a page.
  3107 		$content['post_type'] = 'page';
  3145 		$content['post_type'] = 'page';
  3108 
  3146 
  3109 		// Arrange args in the way mw_editPost understands.
  3147 		// Arrange args in the way mw_editPost() understands.
  3110 		$args = array(
  3148 		$args = array(
  3111 			$page_id,
  3149 			$page_id,
  3112 			$username,
  3150 			$username,
  3113 			$password,
  3151 			$password,
  3114 			$content,
  3152 			$content,
  3115 			$publish,
  3153 			$publish,
  3116 		);
  3154 		);
  3117 
  3155 
  3118 		// Let mw_editPost do all of the heavy lifting.
  3156 		// Let mw_editPost() do all of the heavy lifting.
  3119 		return $this->mw_editPost( $args );
  3157 		return $this->mw_editPost( $args );
  3120 	}
  3158 	}
  3121 
  3159 
  3122 	/**
  3160 	/**
  3123 	 * Retrieve page list.
  3161 	 * Retrieve page list.
  3124 	 *
  3162 	 *
  3125 	 * @since 2.2.0
  3163 	 * @since 2.2.0
  3126 	 *
  3164 	 *
  3127 	 * @global wpdb $wpdb WordPress database abstraction object.
  3165 	 * @global wpdb $wpdb WordPress database abstraction object.
  3128 	 *
  3166 	 *
  3129 	 * @param array  $args {
  3167 	 * @param array $args {
  3130 	 *     Method arguments. Note: arguments must be ordered as documented.
  3168 	 *     Method arguments. Note: arguments must be ordered as documented.
  3131 	 *
  3169 	 *
  3132 	 *     @type int    $blog_id (unused)
  3170 	 *     @type int    $blog_id (unused)
  3133 	 *     @type string $username
  3171 	 *     @type string $username
  3134 	 *     @type string $password
  3172 	 *     @type string $password
  3141 		$this->escape( $args );
  3179 		$this->escape( $args );
  3142 
  3180 
  3143 		$username = $args[1];
  3181 		$username = $args[1];
  3144 		$password = $args[2];
  3182 		$password = $args[2];
  3145 
  3183 
  3146 		if ( ! $user = $this->login( $username, $password ) ) {
  3184 		$user = $this->login( $username, $password );
       
  3185 		if ( ! $user ) {
  3147 			return $this->error;
  3186 			return $this->error;
  3148 		}
  3187 		}
  3149 
  3188 
  3150 		if ( ! current_user_can( 'edit_pages' ) ) {
  3189 		if ( ! current_user_can( 'edit_pages' ) ) {
  3151 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit pages.' ) );
  3190 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit pages.' ) );
  3152 		}
  3191 		}
  3153 
  3192 
  3154 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3193 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3155 		do_action( 'xmlrpc_call', 'wp.getPageList' );
  3194 		do_action( 'xmlrpc_call', 'wp.getPageList' );
  3156 
  3195 
  3157 		// Get list of pages ids and titles
  3196 		// Get list of page IDs and titles.
  3158 		$page_list = $wpdb->get_results(
  3197 		$page_list = $wpdb->get_results(
  3159 			"
  3198 			"
  3160 			SELECT ID page_id,
  3199 			SELECT ID page_id,
  3161 				post_title page_title,
  3200 				post_title page_title,
  3162 				post_parent page_parent_id,
  3201 				post_parent page_parent_id,
  3186 	/**
  3225 	/**
  3187 	 * Retrieve authors list.
  3226 	 * Retrieve authors list.
  3188 	 *
  3227 	 *
  3189 	 * @since 2.2.0
  3228 	 * @since 2.2.0
  3190 	 *
  3229 	 *
  3191 	 * @param array  $args {
  3230 	 * @param array $args {
  3192 	 *     Method arguments. Note: arguments must be ordered as documented.
  3231 	 *     Method arguments. Note: arguments must be ordered as documented.
  3193 	 *
  3232 	 *
  3194 	 *     @type int    $blog_id (unused)
  3233 	 *     @type int    $blog_id (unused)
  3195 	 *     @type string $username
  3234 	 *     @type string $username
  3196 	 *     @type string $password
  3235 	 *     @type string $password
  3201 		$this->escape( $args );
  3240 		$this->escape( $args );
  3202 
  3241 
  3203 		$username = $args[1];
  3242 		$username = $args[1];
  3204 		$password = $args[2];
  3243 		$password = $args[2];
  3205 
  3244 
  3206 		if ( ! $user = $this->login( $username, $password ) ) {
  3245 		$user = $this->login( $username, $password );
       
  3246 		if ( ! $user ) {
  3207 			return $this->error;
  3247 			return $this->error;
  3208 		}
  3248 		}
  3209 
  3249 
  3210 		if ( ! current_user_can( 'edit_posts' ) ) {
  3250 		if ( ! current_user_can( 'edit_posts' ) ) {
  3211 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit posts.' ) );
  3251 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit posts.' ) );
  3229 	/**
  3269 	/**
  3230 	 * Get list of all tags
  3270 	 * Get list of all tags
  3231 	 *
  3271 	 *
  3232 	 * @since 2.7.0
  3272 	 * @since 2.7.0
  3233 	 *
  3273 	 *
  3234 	 * @param array  $args {
  3274 	 * @param array $args {
  3235 	 *     Method arguments. Note: arguments must be ordered as documented.
  3275 	 *     Method arguments. Note: arguments must be ordered as documented.
  3236 	 *
  3276 	 *
  3237 	 *     @type int    $blog_id (unused)
  3277 	 *     @type int    $blog_id (unused)
  3238 	 *     @type string $username
  3278 	 *     @type string $username
  3239 	 *     @type string $password
  3279 	 *     @type string $password
  3244 		$this->escape( $args );
  3284 		$this->escape( $args );
  3245 
  3285 
  3246 		$username = $args[1];
  3286 		$username = $args[1];
  3247 		$password = $args[2];
  3287 		$password = $args[2];
  3248 
  3288 
  3249 		if ( ! $user = $this->login( $username, $password ) ) {
  3289 		$user = $this->login( $username, $password );
       
  3290 		if ( ! $user ) {
  3250 			return $this->error;
  3291 			return $this->error;
  3251 		}
  3292 		}
  3252 
  3293 
  3253 		if ( ! current_user_can( 'edit_posts' ) ) {
  3294 		if ( ! current_user_can( 'edit_posts' ) ) {
  3254 			return new IXR_Error( 401, __( 'Sorry, you must be able to edit posts on this site in order to view tags.' ) );
  3295 			return new IXR_Error( 401, __( 'Sorry, you must be able to edit posts on this site in order to view tags.' ) );
  3257 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3298 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3258 		do_action( 'xmlrpc_call', 'wp.getKeywords' );
  3299 		do_action( 'xmlrpc_call', 'wp.getKeywords' );
  3259 
  3300 
  3260 		$tags = array();
  3301 		$tags = array();
  3261 
  3302 
  3262 		if ( $all_tags = get_tags() ) {
  3303 		$all_tags = get_tags();
       
  3304 		if ( $all_tags ) {
  3263 			foreach ( (array) $all_tags as $tag ) {
  3305 			foreach ( (array) $all_tags as $tag ) {
  3264 				$struct             = array();
  3306 				$struct             = array();
  3265 				$struct['tag_id']   = $tag->term_id;
  3307 				$struct['tag_id']   = $tag->term_id;
  3266 				$struct['name']     = $tag->name;
  3308 				$struct['name']     = $tag->name;
  3267 				$struct['count']    = $tag->count;
  3309 				$struct['count']    = $tag->count;
  3279 	/**
  3321 	/**
  3280 	 * Create new category.
  3322 	 * Create new category.
  3281 	 *
  3323 	 *
  3282 	 * @since 2.2.0
  3324 	 * @since 2.2.0
  3283 	 *
  3325 	 *
  3284 	 * @param array  $args {
  3326 	 * @param array $args {
  3285 	 *     Method arguments. Note: arguments must be ordered as documented.
  3327 	 *     Method arguments. Note: arguments must be ordered as documented.
  3286 	 *
  3328 	 *
  3287 	 *     @type int    $blog_id (unused)
  3329 	 *     @type int    $blog_id (unused)
  3288 	 *     @type string $username
  3330 	 *     @type string $username
  3289 	 *     @type string $password
  3331 	 *     @type string $password
  3296 
  3338 
  3297 		$username = $args[1];
  3339 		$username = $args[1];
  3298 		$password = $args[2];
  3340 		$password = $args[2];
  3299 		$category = $args[3];
  3341 		$category = $args[3];
  3300 
  3342 
  3301 		if ( ! $user = $this->login( $username, $password ) ) {
  3343 		$user = $this->login( $username, $password );
       
  3344 		if ( ! $user ) {
  3302 			return $this->error;
  3345 			return $this->error;
  3303 		}
  3346 		}
  3304 
  3347 
  3305 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3348 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3306 		do_action( 'xmlrpc_call', 'wp.newCategory' );
  3349 		do_action( 'xmlrpc_call', 'wp.newCategory' );
  3308 		// Make sure the user is allowed to add a category.
  3351 		// Make sure the user is allowed to add a category.
  3309 		if ( ! current_user_can( 'manage_categories' ) ) {
  3352 		if ( ! current_user_can( 'manage_categories' ) ) {
  3310 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to add a category.' ) );
  3353 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to add a category.' ) );
  3311 		}
  3354 		}
  3312 
  3355 
  3313 		// If no slug was provided make it empty so that
  3356 		// If no slug was provided, make it empty
  3314 		// WordPress will generate one.
  3357 		// so that WordPress will generate one.
  3315 		if ( empty( $category['slug'] ) ) {
  3358 		if ( empty( $category['slug'] ) ) {
  3316 			$category['slug'] = '';
  3359 			$category['slug'] = '';
  3317 		}
  3360 		}
  3318 
  3361 
  3319 		// If no parent_id was provided make it empty
  3362 		// If no parent_id was provided, make it empty
  3320 		// so that it will be a top level page (no parent).
  3363 		// so that it will be a top-level page (no parent).
  3321 		if ( ! isset( $category['parent_id'] ) ) {
  3364 		if ( ! isset( $category['parent_id'] ) ) {
  3322 			$category['parent_id'] = '';
  3365 			$category['parent_id'] = '';
  3323 		}
  3366 		}
  3324 
  3367 
  3325 		// If no description was provided make it empty.
  3368 		// If no description was provided, make it empty.
  3326 		if ( empty( $category['description'] ) ) {
  3369 		if ( empty( $category['description'] ) ) {
  3327 			$category['description'] = '';
  3370 			$category['description'] = '';
  3328 		}
  3371 		}
  3329 
  3372 
  3330 		$new_category = array(
  3373 		$new_category = array(
  3334 			'category_description' => $category['description'],
  3377 			'category_description' => $category['description'],
  3335 		);
  3378 		);
  3336 
  3379 
  3337 		$cat_id = wp_insert_category( $new_category, true );
  3380 		$cat_id = wp_insert_category( $new_category, true );
  3338 		if ( is_wp_error( $cat_id ) ) {
  3381 		if ( is_wp_error( $cat_id ) ) {
  3339 			if ( 'term_exists' == $cat_id->get_error_code() ) {
  3382 			if ( 'term_exists' === $cat_id->get_error_code() ) {
  3340 				return (int) $cat_id->get_error_data();
  3383 				return (int) $cat_id->get_error_data();
  3341 			} else {
  3384 			} else {
  3342 				return new IXR_Error( 500, __( 'Sorry, the new category failed.' ) );
  3385 				return new IXR_Error( 500, __( 'Sorry, the category could not be created.' ) );
  3343 			}
  3386 			}
  3344 		} elseif ( ! $cat_id ) {
  3387 		} elseif ( ! $cat_id ) {
  3345 			return new IXR_Error( 500, __( 'Sorry, the new category failed.' ) );
  3388 			return new IXR_Error( 500, __( 'Sorry, the category could not be created.' ) );
  3346 		}
  3389 		}
  3347 
  3390 
  3348 		/**
  3391 		/**
  3349 		 * Fires after a new category has been successfully created via XML-RPC.
  3392 		 * Fires after a new category has been successfully created via XML-RPC.
  3350 		 *
  3393 		 *
  3351 		 * @since 3.4.0
  3394 		 * @since 3.4.0
  3352 		 *
  3395 		 *
  3353 		 * @param int   $cat_id ID of the new category.
  3396 		 * @param int   $cat_id ID of the new category.
  3354 		 * @param array $args   An array of new category arguments.
  3397 		 * @param array $args   An array of new category arguments.
  3355 		 */
  3398 		 */
  3356 		do_action( 'xmlrpc_call_success_wp_newCategory', $cat_id, $args );
  3399 		do_action( 'xmlrpc_call_success_wp_newCategory', $cat_id, $args ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.NotLowercase
  3357 
  3400 
  3358 		return $cat_id;
  3401 		return $cat_id;
  3359 	}
  3402 	}
  3360 
  3403 
  3361 	/**
  3404 	/**
  3362 	 * Remove category.
  3405 	 * Remove category.
  3363 	 *
  3406 	 *
  3364 	 * @since 2.5.0
  3407 	 * @since 2.5.0
  3365 	 *
  3408 	 *
  3366 	 * @param array  $args {
  3409 	 * @param array $args {
  3367 	 *     Method arguments. Note: arguments must be ordered as documented.
  3410 	 *     Method arguments. Note: arguments must be ordered as documented.
  3368 	 *
  3411 	 *
  3369 	 *     @type int    $blog_id (unused)
  3412 	 *     @type int    $blog_id (unused)
  3370 	 *     @type string $username
  3413 	 *     @type string $username
  3371 	 *     @type string $password
  3414 	 *     @type string $password
  3378 
  3421 
  3379 		$username    = $args[1];
  3422 		$username    = $args[1];
  3380 		$password    = $args[2];
  3423 		$password    = $args[2];
  3381 		$category_id = (int) $args[3];
  3424 		$category_id = (int) $args[3];
  3382 
  3425 
  3383 		if ( ! $user = $this->login( $username, $password ) ) {
  3426 		$user = $this->login( $username, $password );
       
  3427 		if ( ! $user ) {
  3384 			return $this->error;
  3428 			return $this->error;
  3385 		}
  3429 		}
  3386 
  3430 
  3387 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3431 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3388 		do_action( 'xmlrpc_call', 'wp.deleteCategory' );
  3432 		do_action( 'xmlrpc_call', 'wp.deleteCategory' );
  3400 			 * @since 3.4.0
  3444 			 * @since 3.4.0
  3401 			 *
  3445 			 *
  3402 			 * @param int   $category_id ID of the deleted category.
  3446 			 * @param int   $category_id ID of the deleted category.
  3403 			 * @param array $args        An array of arguments to delete the category.
  3447 			 * @param array $args        An array of arguments to delete the category.
  3404 			 */
  3448 			 */
  3405 			do_action( 'xmlrpc_call_success_wp_deleteCategory', $category_id, $args );
  3449 			do_action( 'xmlrpc_call_success_wp_deleteCategory', $category_id, $args ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.NotLowercase
  3406 		}
  3450 		}
  3407 
  3451 
  3408 		return $status;
  3452 		return $status;
  3409 	}
  3453 	}
  3410 
  3454 
  3411 	/**
  3455 	/**
  3412 	 * Retrieve category list.
  3456 	 * Retrieve category list.
  3413 	 *
  3457 	 *
  3414 	 * @since 2.2.0
  3458 	 * @since 2.2.0
  3415 	 *
  3459 	 *
  3416 	 * @param array  $args {
  3460 	 * @param array $args {
  3417 	 *     Method arguments. Note: arguments must be ordered as documented.
  3461 	 *     Method arguments. Note: arguments must be ordered as documented.
  3418 	 *
  3462 	 *
  3419 	 *     @type int    $blog_id (unused)
  3463 	 *     @type int    $blog_id (unused)
  3420 	 *     @type string $username
  3464 	 *     @type string $username
  3421 	 *     @type string $password
  3465 	 *     @type string $password
  3430 		$username    = $args[1];
  3474 		$username    = $args[1];
  3431 		$password    = $args[2];
  3475 		$password    = $args[2];
  3432 		$category    = $args[3];
  3476 		$category    = $args[3];
  3433 		$max_results = (int) $args[4];
  3477 		$max_results = (int) $args[4];
  3434 
  3478 
  3435 		if ( ! $user = $this->login( $username, $password ) ) {
  3479 		$user = $this->login( $username, $password );
       
  3480 		if ( ! $user ) {
  3436 			return $this->error;
  3481 			return $this->error;
  3437 		}
  3482 		}
  3438 
  3483 
  3439 		if ( ! current_user_can( 'edit_posts' ) ) {
  3484 		if ( ! current_user_can( 'edit_posts' ) ) {
  3440 			return new IXR_Error( 401, __( 'Sorry, you must be able to edit posts on this site in order to view categories.' ) );
  3485 			return new IXR_Error( 401, __( 'Sorry, you must be able to edit posts on this site in order to view categories.' ) );
  3462 	/**
  3507 	/**
  3463 	 * Retrieve comment.
  3508 	 * Retrieve comment.
  3464 	 *
  3509 	 *
  3465 	 * @since 2.7.0
  3510 	 * @since 2.7.0
  3466 	 *
  3511 	 *
  3467 	 * @param array  $args {
  3512 	 * @param array $args {
  3468 	 *     Method arguments. Note: arguments must be ordered as documented.
  3513 	 *     Method arguments. Note: arguments must be ordered as documented.
  3469 	 *
  3514 	 *
  3470 	 *     @type int    $blog_id (unused)
  3515 	 *     @type int    $blog_id (unused)
  3471 	 *     @type string $username
  3516 	 *     @type string $username
  3472 	 *     @type string $password
  3517 	 *     @type string $password
  3479 
  3524 
  3480 		$username   = $args[1];
  3525 		$username   = $args[1];
  3481 		$password   = $args[2];
  3526 		$password   = $args[2];
  3482 		$comment_id = (int) $args[3];
  3527 		$comment_id = (int) $args[3];
  3483 
  3528 
  3484 		if ( ! $user = $this->login( $username, $password ) ) {
  3529 		$user = $this->login( $username, $password );
       
  3530 		if ( ! $user ) {
  3485 			return $this->error;
  3531 			return $this->error;
  3486 		}
  3532 		}
  3487 
  3533 
  3488 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3534 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3489 		do_action( 'xmlrpc_call', 'wp.getComment' );
  3535 		do_action( 'xmlrpc_call', 'wp.getComment' );
  3490 
  3536 
  3491 		if ( ! $comment = get_comment( $comment_id ) ) {
  3537 		$comment = get_comment( $comment_id );
       
  3538 		if ( ! $comment ) {
  3492 			return new IXR_Error( 404, __( 'Invalid comment ID.' ) );
  3539 			return new IXR_Error( 404, __( 'Invalid comment ID.' ) );
  3493 		}
  3540 		}
  3494 
  3541 
  3495 		if ( ! current_user_can( 'edit_comment', $comment_id ) ) {
  3542 		if ( ! current_user_can( 'edit_comment', $comment_id ) ) {
  3496 			return new IXR_Error( 403, __( 'Sorry, you are not allowed to moderate or edit this comment.' ) );
  3543 			return new IXR_Error( 403, __( 'Sorry, you are not allowed to moderate or edit this comment.' ) );
  3513 	 * - 'number' - Default is 10. Total number of media items to retrieve.
  3560 	 * - 'number' - Default is 10. Total number of media items to retrieve.
  3514 	 * - 'offset' - Default is 0. See WP_Query::query() for more.
  3561 	 * - 'offset' - Default is 0. See WP_Query::query() for more.
  3515 	 *
  3562 	 *
  3516 	 * @since 2.7.0
  3563 	 * @since 2.7.0
  3517 	 *
  3564 	 *
  3518 	 * @param array  $args {
  3565 	 * @param array $args {
  3519 	 *     Method arguments. Note: arguments must be ordered as documented.
  3566 	 *     Method arguments. Note: arguments must be ordered as documented.
  3520 	 *
  3567 	 *
  3521 	 *     @type int    $blog_id (unused)
  3568 	 *     @type int    $blog_id (unused)
  3522 	 *     @type string $username
  3569 	 *     @type string $username
  3523 	 *     @type string $password
  3570 	 *     @type string $password
  3530 
  3577 
  3531 		$username = $args[1];
  3578 		$username = $args[1];
  3532 		$password = $args[2];
  3579 		$password = $args[2];
  3533 		$struct   = isset( $args[3] ) ? $args[3] : array();
  3580 		$struct   = isset( $args[3] ) ? $args[3] : array();
  3534 
  3581 
  3535 		if ( ! $user = $this->login( $username, $password ) ) {
  3582 		$user = $this->login( $username, $password );
       
  3583 		if ( ! $user ) {
  3536 			return $this->error;
  3584 			return $this->error;
  3537 		}
  3585 		}
  3538 
  3586 
  3539 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3587 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3540 		do_action( 'xmlrpc_call', 'wp.getComments' );
  3588 		do_action( 'xmlrpc_call', 'wp.getComments' );
  3594 	}
  3642 	}
  3595 
  3643 
  3596 	/**
  3644 	/**
  3597 	 * Delete a comment.
  3645 	 * Delete a comment.
  3598 	 *
  3646 	 *
  3599 	 * By default, the comment will be moved to the trash instead of deleted.
  3647 	 * By default, the comment will be moved to the Trash instead of deleted.
  3600 	 * See wp_delete_comment() for more information on this behavior.
  3648 	 * See wp_delete_comment() for more information on this behavior.
  3601 	 *
  3649 	 *
  3602 	 * @since 2.7.0
  3650 	 * @since 2.7.0
  3603 	 *
  3651 	 *
  3604 	 * @param array  $args {
  3652 	 * @param array $args {
  3605 	 *     Method arguments. Note: arguments must be ordered as documented.
  3653 	 *     Method arguments. Note: arguments must be ordered as documented.
  3606 	 *
  3654 	 *
  3607 	 *     @type int    $blog_id (unused)
  3655 	 *     @type int    $blog_id (unused)
  3608 	 *     @type string $username
  3656 	 *     @type string $username
  3609 	 *     @type string $password
  3657 	 *     @type string $password
  3616 
  3664 
  3617 		$username   = $args[1];
  3665 		$username   = $args[1];
  3618 		$password   = $args[2];
  3666 		$password   = $args[2];
  3619 		$comment_ID = (int) $args[3];
  3667 		$comment_ID = (int) $args[3];
  3620 
  3668 
  3621 		if ( ! $user = $this->login( $username, $password ) ) {
  3669 		$user = $this->login( $username, $password );
       
  3670 		if ( ! $user ) {
  3622 			return $this->error;
  3671 			return $this->error;
  3623 		}
  3672 		}
  3624 
  3673 
  3625 		if ( ! get_comment( $comment_ID ) ) {
  3674 		if ( ! get_comment( $comment_ID ) ) {
  3626 			return new IXR_Error( 404, __( 'Invalid comment ID.' ) );
  3675 			return new IXR_Error( 404, __( 'Invalid comment ID.' ) );
  3642 			 * @since 3.4.0
  3691 			 * @since 3.4.0
  3643 			 *
  3692 			 *
  3644 			 * @param int   $comment_ID ID of the deleted comment.
  3693 			 * @param int   $comment_ID ID of the deleted comment.
  3645 			 * @param array $args       An array of arguments to delete the comment.
  3694 			 * @param array $args       An array of arguments to delete the comment.
  3646 			 */
  3695 			 */
  3647 			do_action( 'xmlrpc_call_success_wp_deleteComment', $comment_ID, $args );
  3696 			do_action( 'xmlrpc_call_success_wp_deleteComment', $comment_ID, $args ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.NotLowercase
  3648 		}
  3697 		}
  3649 
  3698 
  3650 		return $status;
  3699 		return $status;
  3651 	}
  3700 	}
  3652 
  3701 
  3664 	 *  - 'date_created_gmt'
  3713 	 *  - 'date_created_gmt'
  3665 	 *  - 'status'. Common statuses are 'approve', 'hold', 'spam'. See get_comment_statuses() for more details
  3714 	 *  - 'status'. Common statuses are 'approve', 'hold', 'spam'. See get_comment_statuses() for more details
  3666 	 *
  3715 	 *
  3667 	 * @since 2.7.0
  3716 	 * @since 2.7.0
  3668 	 *
  3717 	 *
  3669 	 * @param array  $args {
  3718 	 * @param array $args {
  3670 	 *     Method arguments. Note: arguments must be ordered as documented.
  3719 	 *     Method arguments. Note: arguments must be ordered as documented.
  3671 	 *
  3720 	 *
  3672 	 *     @type int    $blog_id (unused)
  3721 	 *     @type int    $blog_id (unused)
  3673 	 *     @type string $username
  3722 	 *     @type string $username
  3674 	 *     @type string $password
  3723 	 *     @type string $password
  3683 		$username       = $args[1];
  3732 		$username       = $args[1];
  3684 		$password       = $args[2];
  3733 		$password       = $args[2];
  3685 		$comment_ID     = (int) $args[3];
  3734 		$comment_ID     = (int) $args[3];
  3686 		$content_struct = $args[4];
  3735 		$content_struct = $args[4];
  3687 
  3736 
  3688 		if ( ! $user = $this->login( $username, $password ) ) {
  3737 		$user = $this->login( $username, $password );
       
  3738 		if ( ! $user ) {
  3689 			return $this->error;
  3739 			return $this->error;
  3690 		}
  3740 		}
  3691 
  3741 
  3692 		if ( ! get_comment( $comment_ID ) ) {
  3742 		if ( ! get_comment( $comment_ID ) ) {
  3693 			return new IXR_Error( 404, __( 'Invalid comment ID.' ) );
  3743 			return new IXR_Error( 404, __( 'Invalid comment ID.' ) );
  3705 
  3755 
  3706 		if ( isset( $content_struct['status'] ) ) {
  3756 		if ( isset( $content_struct['status'] ) ) {
  3707 			$statuses = get_comment_statuses();
  3757 			$statuses = get_comment_statuses();
  3708 			$statuses = array_keys( $statuses );
  3758 			$statuses = array_keys( $statuses );
  3709 
  3759 
  3710 			if ( ! in_array( $content_struct['status'], $statuses ) ) {
  3760 			if ( ! in_array( $content_struct['status'], $statuses, true ) ) {
  3711 				return new IXR_Error( 401, __( 'Invalid comment status.' ) );
  3761 				return new IXR_Error( 401, __( 'Invalid comment status.' ) );
  3712 			}
  3762 			}
  3713 
  3763 
  3714 			$comment['comment_approved'] = $content_struct['status'];
  3764 			$comment['comment_approved'] = $content_struct['status'];
  3715 		}
  3765 		}
  3716 
  3766 
  3717 		// Do some timestamp voodoo
  3767 		// Do some timestamp voodoo.
  3718 		if ( ! empty( $content_struct['date_created_gmt'] ) ) {
  3768 		if ( ! empty( $content_struct['date_created_gmt'] ) ) {
  3719 			// We know this is supposed to be GMT, so we're going to slap that Z on there by force
  3769 			// We know this is supposed to be GMT, so we're going to slap that Z on there by force.
  3720 			$dateCreated                 = rtrim( $content_struct['date_created_gmt']->getIso(), 'Z' ) . 'Z';
  3770 			$dateCreated                 = rtrim( $content_struct['date_created_gmt']->getIso(), 'Z' ) . 'Z';
  3721 			$comment['comment_date']     = get_date_from_gmt( iso8601_to_datetime( $dateCreated ) );
  3771 			$comment['comment_date']     = get_date_from_gmt( $dateCreated );
  3722 			$comment['comment_date_gmt'] = iso8601_to_datetime( $dateCreated, 'GMT' );
  3772 			$comment['comment_date_gmt'] = iso8601_to_datetime( $dateCreated, 'gmt' );
  3723 		}
  3773 		}
  3724 
  3774 
  3725 		if ( isset( $content_struct['content'] ) ) {
  3775 		if ( isset( $content_struct['content'] ) ) {
  3726 			$comment['comment_content'] = $content_struct['content'];
  3776 			$comment['comment_content'] = $content_struct['content'];
  3727 		}
  3777 		}
  3736 
  3786 
  3737 		if ( isset( $content_struct['author_email'] ) ) {
  3787 		if ( isset( $content_struct['author_email'] ) ) {
  3738 			$comment['comment_author_email'] = $content_struct['author_email'];
  3788 			$comment['comment_author_email'] = $content_struct['author_email'];
  3739 		}
  3789 		}
  3740 
  3790 
  3741 		$result = wp_update_comment( $comment );
  3791 		$result = wp_update_comment( $comment, true );
  3742 		if ( is_wp_error( $result ) ) {
  3792 		if ( is_wp_error( $result ) ) {
  3743 			return new IXR_Error( 500, $result->get_error_message() );
  3793 			return new IXR_Error( 500, $result->get_error_message() );
  3744 		}
  3794 		}
  3745 
  3795 
  3746 		if ( ! $result ) {
  3796 		if ( ! $result ) {
  3747 			return new IXR_Error( 500, __( 'Sorry, the comment could not be edited.' ) );
  3797 			return new IXR_Error( 500, __( 'Sorry, the comment could not be updated.' ) );
  3748 		}
  3798 		}
  3749 
  3799 
  3750 		/**
  3800 		/**
  3751 		 * Fires after a comment has been successfully updated via XML-RPC.
  3801 		 * Fires after a comment has been successfully updated via XML-RPC.
  3752 		 *
  3802 		 *
  3753 		 * @since 3.4.0
  3803 		 * @since 3.4.0
  3754 		 *
  3804 		 *
  3755 		 * @param int   $comment_ID ID of the updated comment.
  3805 		 * @param int   $comment_ID ID of the updated comment.
  3756 		 * @param array $args       An array of arguments to update the comment.
  3806 		 * @param array $args       An array of arguments to update the comment.
  3757 		 */
  3807 		 */
  3758 		do_action( 'xmlrpc_call_success_wp_editComment', $comment_ID, $args );
  3808 		do_action( 'xmlrpc_call_success_wp_editComment', $comment_ID, $args ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.NotLowercase
  3759 
  3809 
  3760 		return true;
  3810 		return true;
  3761 	}
  3811 	}
  3762 
  3812 
  3763 	/**
  3813 	/**
  3764 	 * Create new comment.
  3814 	 * Create new comment.
  3765 	 *
  3815 	 *
  3766 	 * @since 2.7.0
  3816 	 * @since 2.7.0
  3767 	 *
  3817 	 *
  3768 	 * @param array  $args {
  3818 	 * @param array $args {
  3769 	 *     Method arguments. Note: arguments must be ordered as documented.
  3819 	 *     Method arguments. Note: arguments must be ordered as documented.
  3770 	 *
  3820 	 *
  3771 	 *     @type int        $blog_id (unused)
  3821 	 *     @type int        $blog_id (unused)
  3772 	 *     @type string     $username
  3822 	 *     @type string     $username
  3773 	 *     @type string     $password
  3823 	 *     @type string     $password
  3797 		$user = $this->login( $username, $password );
  3847 		$user = $this->login( $username, $password );
  3798 
  3848 
  3799 		if ( ! $user ) {
  3849 		if ( ! $user ) {
  3800 			$logged_in = false;
  3850 			$logged_in = false;
  3801 			if ( $allow_anon && get_option( 'comment_registration' ) ) {
  3851 			if ( $allow_anon && get_option( 'comment_registration' ) ) {
  3802 				return new IXR_Error( 403, __( 'You must be registered to comment.' ) );
  3852 				return new IXR_Error( 403, __( 'Sorry, you must be logged in to comment.' ) );
  3803 			} elseif ( ! $allow_anon ) {
  3853 			} elseif ( ! $allow_anon ) {
  3804 				return $this->error;
  3854 				return $this->error;
  3805 			}
  3855 			}
  3806 		} else {
  3856 		} else {
  3807 			$logged_in = true;
  3857 			$logged_in = true;
  3860 			}
  3910 			}
  3861 
  3911 
  3862 			$comment['user_ID'] = 0;
  3912 			$comment['user_ID'] = 0;
  3863 
  3913 
  3864 			if ( get_option( 'require_name_email' ) ) {
  3914 			if ( get_option( 'require_name_email' ) ) {
  3865 				if ( 6 > strlen( $comment['comment_author_email'] ) || '' == $comment['comment_author'] ) {
  3915 				if ( strlen( $comment['comment_author_email'] < 6 ) || '' === $comment['comment_author'] ) {
  3866 					return new IXR_Error( 403, __( 'Comment author name and email are required.' ) );
  3916 					return new IXR_Error( 403, __( 'Comment author name and email are required.' ) );
  3867 				} elseif ( ! is_email( $comment['comment_author_email'] ) ) {
  3917 				} elseif ( ! is_email( $comment['comment_author_email'] ) ) {
  3868 					return new IXR_Error( 403, __( 'A valid email address is required.' ) );
  3918 					return new IXR_Error( 403, __( 'A valid email address is required.' ) );
  3869 				}
  3919 				}
  3870 			}
  3920 			}
  3890 		 * @since 3.4.0
  3940 		 * @since 3.4.0
  3891 		 *
  3941 		 *
  3892 		 * @param int   $comment_ID ID of the new comment.
  3942 		 * @param int   $comment_ID ID of the new comment.
  3893 		 * @param array $args       An array of new comment arguments.
  3943 		 * @param array $args       An array of new comment arguments.
  3894 		 */
  3944 		 */
  3895 		do_action( 'xmlrpc_call_success_wp_newComment', $comment_ID, $args );
  3945 		do_action( 'xmlrpc_call_success_wp_newComment', $comment_ID, $args ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.NotLowercase
  3896 
  3946 
  3897 		return $comment_ID;
  3947 		return $comment_ID;
  3898 	}
  3948 	}
  3899 
  3949 
  3900 	/**
  3950 	/**
  3901 	 * Retrieve all of the comment status.
  3951 	 * Retrieve all of the comment status.
  3902 	 *
  3952 	 *
  3903 	 * @since 2.7.0
  3953 	 * @since 2.7.0
  3904 	 *
  3954 	 *
  3905 	 * @param array  $args {
  3955 	 * @param array $args {
  3906 	 *     Method arguments. Note: arguments must be ordered as documented.
  3956 	 *     Method arguments. Note: arguments must be ordered as documented.
  3907 	 *
  3957 	 *
  3908 	 *     @type int    $blog_id (unused)
  3958 	 *     @type int    $blog_id (unused)
  3909 	 *     @type string $username
  3959 	 *     @type string $username
  3910 	 *     @type string $password
  3960 	 *     @type string $password
  3915 		$this->escape( $args );
  3965 		$this->escape( $args );
  3916 
  3966 
  3917 		$username = $args[1];
  3967 		$username = $args[1];
  3918 		$password = $args[2];
  3968 		$password = $args[2];
  3919 
  3969 
  3920 		if ( ! $user = $this->login( $username, $password ) ) {
  3970 		$user = $this->login( $username, $password );
       
  3971 		if ( ! $user ) {
  3921 			return $this->error;
  3972 			return $this->error;
  3922 		}
  3973 		}
  3923 
  3974 
  3924 		if ( ! current_user_can( 'publish_posts' ) ) {
  3975 		if ( ! current_user_can( 'publish_posts' ) ) {
  3925 			return new IXR_Error( 403, __( 'Sorry, you are not allowed to access details about this site.' ) );
  3976 			return new IXR_Error( 403, __( 'Sorry, you are not allowed to access details about this site.' ) );
  3934 	/**
  3985 	/**
  3935 	 * Retrieve comment count.
  3986 	 * Retrieve comment count.
  3936 	 *
  3987 	 *
  3937 	 * @since 2.5.0
  3988 	 * @since 2.5.0
  3938 	 *
  3989 	 *
  3939 	 * @param array  $args {
  3990 	 * @param array $args {
  3940 	 *     Method arguments. Note: arguments must be ordered as documented.
  3991 	 *     Method arguments. Note: arguments must be ordered as documented.
  3941 	 *
  3992 	 *
  3942 	 *     @type int    $blog_id (unused)
  3993 	 *     @type int    $blog_id (unused)
  3943 	 *     @type string $username
  3994 	 *     @type string $username
  3944 	 *     @type string $password
  3995 	 *     @type string $password
  3951 
  4002 
  3952 		$username = $args[1];
  4003 		$username = $args[1];
  3953 		$password = $args[2];
  4004 		$password = $args[2];
  3954 		$post_id  = (int) $args[3];
  4005 		$post_id  = (int) $args[3];
  3955 
  4006 
  3956 		if ( ! $user = $this->login( $username, $password ) ) {
  4007 		$user = $this->login( $username, $password );
       
  4008 		if ( ! $user ) {
  3957 			return $this->error;
  4009 			return $this->error;
  3958 		}
  4010 		}
  3959 
  4011 
  3960 		$post = get_post( $post_id, ARRAY_A );
  4012 		$post = get_post( $post_id, ARRAY_A );
  3961 		if ( empty( $post['ID'] ) ) {
  4013 		if ( empty( $post['ID'] ) ) {
  3982 	/**
  4034 	/**
  3983 	 * Retrieve post statuses.
  4035 	 * Retrieve post statuses.
  3984 	 *
  4036 	 *
  3985 	 * @since 2.5.0
  4037 	 * @since 2.5.0
  3986 	 *
  4038 	 *
  3987 	 * @param array  $args {
  4039 	 * @param array $args {
  3988 	 *     Method arguments. Note: arguments must be ordered as documented.
  4040 	 *     Method arguments. Note: arguments must be ordered as documented.
  3989 	 *
  4041 	 *
  3990 	 *     @type int    $blog_id (unused)
  4042 	 *     @type int    $blog_id (unused)
  3991 	 *     @type string $username
  4043 	 *     @type string $username
  3992 	 *     @type string $password
  4044 	 *     @type string $password
  3997 		$this->escape( $args );
  4049 		$this->escape( $args );
  3998 
  4050 
  3999 		$username = $args[1];
  4051 		$username = $args[1];
  4000 		$password = $args[2];
  4052 		$password = $args[2];
  4001 
  4053 
  4002 		if ( ! $user = $this->login( $username, $password ) ) {
  4054 		$user = $this->login( $username, $password );
       
  4055 		if ( ! $user ) {
  4003 			return $this->error;
  4056 			return $this->error;
  4004 		}
  4057 		}
  4005 
  4058 
  4006 		if ( ! current_user_can( 'edit_posts' ) ) {
  4059 		if ( ! current_user_can( 'edit_posts' ) ) {
  4007 			return new IXR_Error( 403, __( 'Sorry, you are not allowed to access details about this site.' ) );
  4060 			return new IXR_Error( 403, __( 'Sorry, you are not allowed to access details about this site.' ) );
  4016 	/**
  4069 	/**
  4017 	 * Retrieve page statuses.
  4070 	 * Retrieve page statuses.
  4018 	 *
  4071 	 *
  4019 	 * @since 2.5.0
  4072 	 * @since 2.5.0
  4020 	 *
  4073 	 *
  4021 	 * @param array  $args {
  4074 	 * @param array $args {
  4022 	 *     Method arguments. Note: arguments must be ordered as documented.
  4075 	 *     Method arguments. Note: arguments must be ordered as documented.
  4023 	 *
  4076 	 *
  4024 	 *     @type int    $blog_id (unused)
  4077 	 *     @type int    $blog_id (unused)
  4025 	 *     @type string $username
  4078 	 *     @type string $username
  4026 	 *     @type string $password
  4079 	 *     @type string $password
  4031 		$this->escape( $args );
  4084 		$this->escape( $args );
  4032 
  4085 
  4033 		$username = $args[1];
  4086 		$username = $args[1];
  4034 		$password = $args[2];
  4087 		$password = $args[2];
  4035 
  4088 
  4036 		if ( ! $user = $this->login( $username, $password ) ) {
  4089 		$user = $this->login( $username, $password );
       
  4090 		if ( ! $user ) {
  4037 			return $this->error;
  4091 			return $this->error;
  4038 		}
  4092 		}
  4039 
  4093 
  4040 		if ( ! current_user_can( 'edit_pages' ) ) {
  4094 		if ( ! current_user_can( 'edit_pages' ) ) {
  4041 			return new IXR_Error( 403, __( 'Sorry, you are not allowed to access details about this site.' ) );
  4095 			return new IXR_Error( 403, __( 'Sorry, you are not allowed to access details about this site.' ) );
  4050 	/**
  4104 	/**
  4051 	 * Retrieve page templates.
  4105 	 * Retrieve page templates.
  4052 	 *
  4106 	 *
  4053 	 * @since 2.6.0
  4107 	 * @since 2.6.0
  4054 	 *
  4108 	 *
  4055 	 * @param array  $args {
  4109 	 * @param array $args {
  4056 	 *     Method arguments. Note: arguments must be ordered as documented.
  4110 	 *     Method arguments. Note: arguments must be ordered as documented.
  4057 	 *
  4111 	 *
  4058 	 *     @type int    $blog_id (unused)
  4112 	 *     @type int    $blog_id (unused)
  4059 	 *     @type string $username
  4113 	 *     @type string $username
  4060 	 *     @type string $password
  4114 	 *     @type string $password
  4065 		$this->escape( $args );
  4119 		$this->escape( $args );
  4066 
  4120 
  4067 		$username = $args[1];
  4121 		$username = $args[1];
  4068 		$password = $args[2];
  4122 		$password = $args[2];
  4069 
  4123 
  4070 		if ( ! $user = $this->login( $username, $password ) ) {
  4124 		$user = $this->login( $username, $password );
       
  4125 		if ( ! $user ) {
  4071 			return $this->error;
  4126 			return $this->error;
  4072 		}
  4127 		}
  4073 
  4128 
  4074 		if ( ! current_user_can( 'edit_pages' ) ) {
  4129 		if ( ! current_user_can( 'edit_pages' ) ) {
  4075 			return new IXR_Error( 403, __( 'Sorry, you are not allowed to access details about this site.' ) );
  4130 			return new IXR_Error( 403, __( 'Sorry, you are not allowed to access details about this site.' ) );
  4084 	/**
  4139 	/**
  4085 	 * Retrieve blog options.
  4140 	 * Retrieve blog options.
  4086 	 *
  4141 	 *
  4087 	 * @since 2.6.0
  4142 	 * @since 2.6.0
  4088 	 *
  4143 	 *
  4089 	 * @param array  $args {
  4144 	 * @param array $args {
  4090 	 *     Method arguments. Note: arguments must be ordered as documented.
  4145 	 *     Method arguments. Note: arguments must be ordered as documented.
  4091 	 *
  4146 	 *
  4092 	 *     @type int    $blog_id (unused)
  4147 	 *     @type int    $blog_id (unused)
  4093 	 *     @type string $username
  4148 	 *     @type string $username
  4094 	 *     @type string $password
  4149 	 *     @type string $password
  4101 
  4156 
  4102 		$username = $args[1];
  4157 		$username = $args[1];
  4103 		$password = $args[2];
  4158 		$password = $args[2];
  4104 		$options  = isset( $args[3] ) ? (array) $args[3] : array();
  4159 		$options  = isset( $args[3] ) ? (array) $args[3] : array();
  4105 
  4160 
  4106 		if ( ! $user = $this->login( $username, $password ) ) {
  4161 		$user = $this->login( $username, $password );
  4107 			return $this->error;
  4162 		if ( ! $user ) {
  4108 		}
  4163 			return $this->error;
  4109 
  4164 		}
  4110 		// If no specific options where asked for, return all of them
  4165 
       
  4166 		// If no specific options where asked for, return all of them.
  4111 		if ( count( $options ) == 0 ) {
  4167 		if ( count( $options ) == 0 ) {
  4112 			$options = array_keys( $this->blog_options );
  4168 			$options = array_keys( $this->blog_options );
  4113 		}
  4169 		}
  4114 
  4170 
  4115 		return $this->_getOptions( $options );
  4171 		return $this->_getOptions( $options );
  4127 		$data       = array();
  4183 		$data       = array();
  4128 		$can_manage = current_user_can( 'manage_options' );
  4184 		$can_manage = current_user_can( 'manage_options' );
  4129 		foreach ( $options as $option ) {
  4185 		foreach ( $options as $option ) {
  4130 			if ( array_key_exists( $option, $this->blog_options ) ) {
  4186 			if ( array_key_exists( $option, $this->blog_options ) ) {
  4131 				$data[ $option ] = $this->blog_options[ $option ];
  4187 				$data[ $option ] = $this->blog_options[ $option ];
  4132 				//Is the value static or dynamic?
  4188 				// Is the value static or dynamic?
  4133 				if ( isset( $data[ $option ]['option'] ) ) {
  4189 				if ( isset( $data[ $option ]['option'] ) ) {
  4134 					$data[ $option ]['value'] = get_option( $data[ $option ]['option'] );
  4190 					$data[ $option ]['value'] = get_option( $data[ $option ]['option'] );
  4135 					unset( $data[ $option ]['option'] );
  4191 					unset( $data[ $option ]['option'] );
  4136 				}
  4192 				}
  4137 
  4193 
  4147 	/**
  4203 	/**
  4148 	 * Update blog options.
  4204 	 * Update blog options.
  4149 	 *
  4205 	 *
  4150 	 * @since 2.6.0
  4206 	 * @since 2.6.0
  4151 	 *
  4207 	 *
  4152 	 * @param array  $args {
  4208 	 * @param array $args {
  4153 	 *     Method arguments. Note: arguments must be ordered as documented.
  4209 	 *     Method arguments. Note: arguments must be ordered as documented.
  4154 	 *
  4210 	 *
  4155 	 *     @type int    $blog_id (unused)
  4211 	 *     @type int    $blog_id (unused)
  4156 	 *     @type string $username
  4212 	 *     @type string $username
  4157 	 *     @type string $password
  4213 	 *     @type string $password
  4164 
  4220 
  4165 		$username = $args[1];
  4221 		$username = $args[1];
  4166 		$password = $args[2];
  4222 		$password = $args[2];
  4167 		$options  = (array) $args[3];
  4223 		$options  = (array) $args[3];
  4168 
  4224 
  4169 		if ( ! $user = $this->login( $username, $password ) ) {
  4225 		$user = $this->login( $username, $password );
       
  4226 		if ( ! $user ) {
  4170 			return $this->error;
  4227 			return $this->error;
  4171 		}
  4228 		}
  4172 
  4229 
  4173 		if ( ! current_user_can( 'manage_options' ) ) {
  4230 		if ( ! current_user_can( 'manage_options' ) ) {
  4174 			return new IXR_Error( 403, __( 'Sorry, you are not allowed to update options.' ) );
  4231 			return new IXR_Error( 403, __( 'Sorry, you are not allowed to update options.' ) );
  4179 			$option_names[] = $o_name;
  4236 			$option_names[] = $o_name;
  4180 			if ( ! array_key_exists( $o_name, $this->blog_options ) ) {
  4237 			if ( ! array_key_exists( $o_name, $this->blog_options ) ) {
  4181 				continue;
  4238 				continue;
  4182 			}
  4239 			}
  4183 
  4240 
  4184 			if ( $this->blog_options[ $o_name ]['readonly'] == true ) {
  4241 			if ( true == $this->blog_options[ $o_name ]['readonly'] ) {
  4185 				continue;
  4242 				continue;
  4186 			}
  4243 			}
  4187 
  4244 
  4188 			update_option( $this->blog_options[ $o_name ]['option'], wp_unslash( $o_value ) );
  4245 			update_option( $this->blog_options[ $o_name ]['option'], wp_unslash( $o_value ) );
  4189 		}
  4246 		}
  4190 
  4247 
  4191 		//Now return the updated values
  4248 		// Now return the updated values.
  4192 		return $this->_getOptions( $option_names );
  4249 		return $this->_getOptions( $option_names );
  4193 	}
  4250 	}
  4194 
  4251 
  4195 	/**
  4252 	/**
  4196 	 * Retrieve a media item by ID
  4253 	 * Retrieve a media item by ID
  4197 	 *
  4254 	 *
  4198 	 * @since 3.1.0
  4255 	 * @since 3.1.0
  4199 	 *
  4256 	 *
  4200 	 * @param array  $args {
  4257 	 * @param array $args {
  4201 	 *     Method arguments. Note: arguments must be ordered as documented.
  4258 	 *     Method arguments. Note: arguments must be ordered as documented.
  4202 	 *
  4259 	 *
  4203 	 *     @type int    $blog_id (unused)
  4260 	 *     @type int    $blog_id (unused)
  4204 	 *     @type string $username
  4261 	 *     @type string $username
  4205 	 *     @type string $password
  4262 	 *     @type string $password
  4220 
  4277 
  4221 		$username      = $args[1];
  4278 		$username      = $args[1];
  4222 		$password      = $args[2];
  4279 		$password      = $args[2];
  4223 		$attachment_id = (int) $args[3];
  4280 		$attachment_id = (int) $args[3];
  4224 
  4281 
  4225 		if ( ! $user = $this->login( $username, $password ) ) {
  4282 		$user = $this->login( $username, $password );
       
  4283 		if ( ! $user ) {
  4226 			return $this->error;
  4284 			return $this->error;
  4227 		}
  4285 		}
  4228 
  4286 
  4229 		if ( ! current_user_can( 'upload_files' ) ) {
  4287 		if ( ! current_user_can( 'upload_files' ) ) {
  4230 			return new IXR_Error( 403, __( 'Sorry, you are not allowed to upload files.' ) );
  4288 			return new IXR_Error( 403, __( 'Sorry, you are not allowed to upload files.' ) );
  4231 		}
  4289 		}
  4232 
  4290 
  4233 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4291 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4234 		do_action( 'xmlrpc_call', 'wp.getMediaItem' );
  4292 		do_action( 'xmlrpc_call', 'wp.getMediaItem' );
  4235 
  4293 
  4236 		if ( ! $attachment = get_post( $attachment_id ) ) {
  4294 		$attachment = get_post( $attachment_id );
       
  4295 		if ( ! $attachment ) {
  4237 			return new IXR_Error( 404, __( 'Invalid attachment ID.' ) );
  4296 			return new IXR_Error( 404, __( 'Invalid attachment ID.' ) );
  4238 		}
  4297 		}
  4239 
  4298 
  4240 		return $this->_prepare_media_item( $attachment );
  4299 		return $this->_prepare_media_item( $attachment );
  4241 	}
  4300 	}
  4254 	 * - 'parent_id' - Default is ''. The post where the media item is attached. Empty string shows all media items. 0 shows unattached media items.
  4313 	 * - 'parent_id' - Default is ''. The post where the media item is attached. Empty string shows all media items. 0 shows unattached media items.
  4255 	 * - 'mime_type' - Default is ''. Filter by mime type (e.g., 'image/jpeg', 'application/pdf')
  4314 	 * - 'mime_type' - Default is ''. Filter by mime type (e.g., 'image/jpeg', 'application/pdf')
  4256 	 *
  4315 	 *
  4257 	 * @since 3.1.0
  4316 	 * @since 3.1.0
  4258 	 *
  4317 	 *
  4259 	 * @param array  $args {
  4318 	 * @param array $args {
  4260 	 *     Method arguments. Note: arguments must be ordered as documented.
  4319 	 *     Method arguments. Note: arguments must be ordered as documented.
  4261 	 *
  4320 	 *
  4262 	 *     @type int    $blog_id (unused)
  4321 	 *     @type int    $blog_id (unused)
  4263 	 *     @type string $username
  4322 	 *     @type string $username
  4264 	 *     @type string $password
  4323 	 *     @type string $password
  4271 
  4330 
  4272 		$username = $args[1];
  4331 		$username = $args[1];
  4273 		$password = $args[2];
  4332 		$password = $args[2];
  4274 		$struct   = isset( $args[3] ) ? $args[3] : array();
  4333 		$struct   = isset( $args[3] ) ? $args[3] : array();
  4275 
  4334 
  4276 		if ( ! $user = $this->login( $username, $password ) ) {
  4335 		$user = $this->login( $username, $password );
       
  4336 		if ( ! $user ) {
  4277 			return $this->error;
  4337 			return $this->error;
  4278 		}
  4338 		}
  4279 
  4339 
  4280 		if ( ! current_user_can( 'upload_files' ) ) {
  4340 		if ( ! current_user_can( 'upload_files' ) ) {
  4281 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to upload files.' ) );
  4341 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to upload files.' ) );
  4311 	/**
  4371 	/**
  4312 	 * Retrieves a list of post formats used by the site.
  4372 	 * Retrieves a list of post formats used by the site.
  4313 	 *
  4373 	 *
  4314 	 * @since 3.1.0
  4374 	 * @since 3.1.0
  4315 	 *
  4375 	 *
  4316 	 * @param array  $args {
  4376 	 * @param array $args {
  4317 	 *     Method arguments. Note: arguments must be ordered as documented.
  4377 	 *     Method arguments. Note: arguments must be ordered as documented.
  4318 	 *
  4378 	 *
  4319 	 *     @type int    $blog_id (unused)
  4379 	 *     @type int    $blog_id (unused)
  4320 	 *     @type string $username
  4380 	 *     @type string $username
  4321 	 *     @type string $password
  4381 	 *     @type string $password
  4326 		$this->escape( $args );
  4386 		$this->escape( $args );
  4327 
  4387 
  4328 		$username = $args[1];
  4388 		$username = $args[1];
  4329 		$password = $args[2];
  4389 		$password = $args[2];
  4330 
  4390 
  4331 		if ( ! $user = $this->login( $username, $password ) ) {
  4391 		$user = $this->login( $username, $password );
       
  4392 		if ( ! $user ) {
  4332 			return $this->error;
  4393 			return $this->error;
  4333 		}
  4394 		}
  4334 
  4395 
  4335 		if ( ! current_user_can( 'edit_posts' ) ) {
  4396 		if ( ! current_user_can( 'edit_posts' ) ) {
  4336 			return new IXR_Error( 403, __( 'Sorry, you are not allowed to access details about this site.' ) );
  4397 			return new IXR_Error( 403, __( 'Sorry, you are not allowed to access details about this site.' ) );
  4339 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4400 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4340 		do_action( 'xmlrpc_call', 'wp.getPostFormats' );
  4401 		do_action( 'xmlrpc_call', 'wp.getPostFormats' );
  4341 
  4402 
  4342 		$formats = get_post_format_strings();
  4403 		$formats = get_post_format_strings();
  4343 
  4404 
  4344 		// find out if they want a list of currently supports formats
  4405 		// Find out if they want a list of currently supports formats.
  4345 		if ( isset( $args[3] ) && is_array( $args[3] ) ) {
  4406 		if ( isset( $args[3] ) && is_array( $args[3] ) ) {
  4346 			if ( $args[3]['show-supported'] ) {
  4407 			if ( $args[3]['show-supported'] ) {
  4347 				if ( current_theme_supports( 'post-formats' ) ) {
  4408 				if ( current_theme_supports( 'post-formats' ) ) {
  4348 					$supported = get_theme_support( 'post-formats' );
  4409 					$supported = get_theme_support( 'post-formats' );
  4349 
  4410 
  4364 	 *
  4425 	 *
  4365 	 * @since 3.4.0
  4426 	 * @since 3.4.0
  4366 	 *
  4427 	 *
  4367 	 * @see get_post_type_object()
  4428 	 * @see get_post_type_object()
  4368 	 *
  4429 	 *
  4369 	 * @param array  $args {
  4430 	 * @param array $args {
  4370 	 *     Method arguments. Note: arguments must be ordered as documented.
  4431 	 *     Method arguments. Note: arguments must be ordered as documented.
  4371 	 *
  4432 	 *
  4372 	 *     @type int    $blog_id (unused)
  4433 	 *     @type int    $blog_id (unused)
  4373 	 *     @type string $username
  4434 	 *     @type string $username
  4374 	 *     @type string $password
  4435 	 *     @type string $password
  4409 			 * @param string $method The method name.
  4470 			 * @param string $method The method name.
  4410 			 */
  4471 			 */
  4411 			$fields = apply_filters( 'xmlrpc_default_posttype_fields', array( 'labels', 'cap', 'taxonomies' ), 'wp.getPostType' );
  4472 			$fields = apply_filters( 'xmlrpc_default_posttype_fields', array( 'labels', 'cap', 'taxonomies' ), 'wp.getPostType' );
  4412 		}
  4473 		}
  4413 
  4474 
  4414 		if ( ! $user = $this->login( $username, $password ) ) {
  4475 		$user = $this->login( $username, $password );
       
  4476 		if ( ! $user ) {
  4415 			return $this->error;
  4477 			return $this->error;
  4416 		}
  4478 		}
  4417 
  4479 
  4418 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4480 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4419 		do_action( 'xmlrpc_call', 'wp.getPostType' );
  4481 		do_action( 'xmlrpc_call', 'wp.getPostType' );
  4436 	 *
  4498 	 *
  4437 	 * @since 3.4.0
  4499 	 * @since 3.4.0
  4438 	 *
  4500 	 *
  4439 	 * @see get_post_types()
  4501 	 * @see get_post_types()
  4440 	 *
  4502 	 *
  4441 	 * @param array  $args {
  4503 	 * @param array $args {
  4442 	 *     Method arguments. Note: arguments must be ordered as documented.
  4504 	 *     Method arguments. Note: arguments must be ordered as documented.
  4443 	 *
  4505 	 *
  4444 	 *     @type int    $blog_id (unused)
  4506 	 *     @type int    $blog_id (unused)
  4445 	 *     @type string $username
  4507 	 *     @type string $username
  4446 	 *     @type string $password
  4508 	 *     @type string $password
  4465 		} else {
  4527 		} else {
  4466 			/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4528 			/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4467 			$fields = apply_filters( 'xmlrpc_default_posttype_fields', array( 'labels', 'cap', 'taxonomies' ), 'wp.getPostTypes' );
  4529 			$fields = apply_filters( 'xmlrpc_default_posttype_fields', array( 'labels', 'cap', 'taxonomies' ), 'wp.getPostTypes' );
  4468 		}
  4530 		}
  4469 
  4531 
  4470 		if ( ! $user = $this->login( $username, $password ) ) {
  4532 		$user = $this->login( $username, $password );
       
  4533 		if ( ! $user ) {
  4471 			return $this->error;
  4534 			return $this->error;
  4472 		}
  4535 		}
  4473 
  4536 
  4474 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4537 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4475 		do_action( 'xmlrpc_call', 'wp.getPostTypes' );
  4538 		do_action( 'xmlrpc_call', 'wp.getPostTypes' );
  4498 	 * in the response array.
  4561 	 * in the response array.
  4499 	 *
  4562 	 *
  4500 	 * @uses wp_get_post_revisions()
  4563 	 * @uses wp_get_post_revisions()
  4501 	 * @see wp_getPost() for more on $fields
  4564 	 * @see wp_getPost() for more on $fields
  4502 	 *
  4565 	 *
  4503 	 * @param array  $args {
  4566 	 * @param array $args {
  4504 	 *     Method arguments. Note: arguments must be ordered as documented.
  4567 	 *     Method arguments. Note: arguments must be ordered as documented.
  4505 	 *
  4568 	 *
  4506 	 *     @type int    $blog_id (unused)
  4569 	 *     @type int    $blog_id (unused)
  4507 	 *     @type string $username
  4570 	 *     @type string $username
  4508 	 *     @type string $password
  4571 	 *     @type string $password
  4534 			 * @param string $method The method name.
  4597 			 * @param string $method The method name.
  4535 			 */
  4598 			 */
  4536 			$fields = apply_filters( 'xmlrpc_default_revision_fields', array( 'post_date', 'post_date_gmt' ), 'wp.getRevisions' );
  4599 			$fields = apply_filters( 'xmlrpc_default_revision_fields', array( 'post_date', 'post_date_gmt' ), 'wp.getRevisions' );
  4537 		}
  4600 		}
  4538 
  4601 
  4539 		if ( ! $user = $this->login( $username, $password ) ) {
  4602 		$user = $this->login( $username, $password );
       
  4603 		if ( ! $user ) {
  4540 			return $this->error;
  4604 			return $this->error;
  4541 		}
  4605 		}
  4542 
  4606 
  4543 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4607 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4544 		do_action( 'xmlrpc_call', 'wp.getRevisions' );
  4608 		do_action( 'xmlrpc_call', 'wp.getRevisions' );
  4545 
  4609 
  4546 		if ( ! $post = get_post( $post_id ) ) {
  4610 		$post = get_post( $post_id );
       
  4611 		if ( ! $post ) {
  4547 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  4612 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  4548 		}
  4613 		}
  4549 
  4614 
  4550 		if ( ! current_user_can( 'edit_post', $post_id ) ) {
  4615 		if ( ! current_user_can( 'edit_post', $post_id ) ) {
  4551 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit posts.' ) );
  4616 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit posts.' ) );
  4567 		foreach ( $revisions as $revision ) {
  4632 		foreach ( $revisions as $revision ) {
  4568 			if ( ! current_user_can( 'read_post', $revision->ID ) ) {
  4633 			if ( ! current_user_can( 'read_post', $revision->ID ) ) {
  4569 				continue;
  4634 				continue;
  4570 			}
  4635 			}
  4571 
  4636 
  4572 			// Skip autosaves
  4637 			// Skip autosaves.
  4573 			if ( wp_is_post_autosave( $revision ) ) {
  4638 			if ( wp_is_post_autosave( $revision ) ) {
  4574 				continue;
  4639 				continue;
  4575 			}
  4640 			}
  4576 
  4641 
  4577 			$struct[] = $this->_prepare_post( get_object_vars( $revision ), $fields );
  4642 			$struct[] = $this->_prepare_post( get_object_vars( $revision ), $fields );
  4585 	 *
  4650 	 *
  4586 	 * @since 3.5.0
  4651 	 * @since 3.5.0
  4587 	 *
  4652 	 *
  4588 	 * @uses wp_restore_post_revision()
  4653 	 * @uses wp_restore_post_revision()
  4589 	 *
  4654 	 *
  4590 	 * @param array  $args {
  4655 	 * @param array $args {
  4591 	 *     Method arguments. Note: arguments must be ordered as documented.
  4656 	 *     Method arguments. Note: arguments must be ordered as documented.
  4592 	 *
  4657 	 *
  4593 	 *     @type int    $blog_id (unused)
  4658 	 *     @type int    $blog_id (unused)
  4594 	 *     @type string $username
  4659 	 *     @type string $username
  4595 	 *     @type string $password
  4660 	 *     @type string $password
  4606 
  4671 
  4607 		$username    = $args[1];
  4672 		$username    = $args[1];
  4608 		$password    = $args[2];
  4673 		$password    = $args[2];
  4609 		$revision_id = (int) $args[3];
  4674 		$revision_id = (int) $args[3];
  4610 
  4675 
  4611 		if ( ! $user = $this->login( $username, $password ) ) {
  4676 		$user = $this->login( $username, $password );
       
  4677 		if ( ! $user ) {
  4612 			return $this->error;
  4678 			return $this->error;
  4613 		}
  4679 		}
  4614 
  4680 
  4615 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4681 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4616 		do_action( 'xmlrpc_call', 'wp.restoreRevision' );
  4682 		do_action( 'xmlrpc_call', 'wp.restoreRevision' );
  4617 
  4683 
  4618 		if ( ! $revision = wp_get_post_revision( $revision_id ) ) {
  4684 		$revision = wp_get_post_revision( $revision_id );
       
  4685 		if ( ! $revision ) {
  4619 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  4686 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  4620 		}
  4687 		}
  4621 
  4688 
  4622 		if ( wp_is_post_autosave( $revision ) ) {
  4689 		if ( wp_is_post_autosave( $revision ) ) {
  4623 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  4690 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  4624 		}
  4691 		}
  4625 
  4692 
  4626 		if ( ! $post = get_post( $revision->post_parent ) ) {
  4693 		$post = get_post( $revision->post_parent );
       
  4694 		if ( ! $post ) {
  4627 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  4695 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  4628 		}
  4696 		}
  4629 
  4697 
  4630 		if ( ! current_user_can( 'edit_post', $revision->post_parent ) ) {
  4698 		if ( ! current_user_can( 'edit_post', $revision->post_parent ) ) {
  4631 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit this post.' ) );
  4699 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit this post.' ) );
  4639 		$post = wp_restore_post_revision( $revision_id );
  4707 		$post = wp_restore_post_revision( $revision_id );
  4640 
  4708 
  4641 		return (bool) $post;
  4709 		return (bool) $post;
  4642 	}
  4710 	}
  4643 
  4711 
  4644 	/* Blogger API functions.
  4712 	/*
  4645 	 * specs on http://plant.blogger.com/api and https://groups.yahoo.com/group/bloggerDev/
  4713 	 * Blogger API functions.
       
  4714 	 * Specs on http://plant.blogger.com/api and https://groups.yahoo.com/group/bloggerDev/
  4646 	 */
  4715 	 */
  4647 
  4716 
  4648 	/**
  4717 	/**
  4649 	 * Retrieve blogs that user owns.
  4718 	 * Retrieve blogs that user owns.
  4650 	 *
  4719 	 *
  4651 	 * Will make more sense once we support multiple blogs.
  4720 	 * Will make more sense once we support multiple blogs.
  4652 	 *
  4721 	 *
  4653 	 * @since 1.5.0
  4722 	 * @since 1.5.0
  4654 	 *
  4723 	 *
  4655 	 * @param array  $args {
  4724 	 * @param array $args {
  4656 	 *     Method arguments. Note: arguments must be ordered as documented.
  4725 	 *     Method arguments. Note: arguments must be ordered as documented.
  4657 	 *
  4726 	 *
  4658 	 *     @type int    $blog_id (unused)
  4727 	 *     @type int    $blog_id (unused)
  4659 	 *     @type string $username
  4728 	 *     @type string $username
  4660 	 *     @type string $password
  4729 	 *     @type string $password
  4673 		$this->escape( $args );
  4742 		$this->escape( $args );
  4674 
  4743 
  4675 		$username = $args[1];
  4744 		$username = $args[1];
  4676 		$password = $args[2];
  4745 		$password = $args[2];
  4677 
  4746 
  4678 		if ( ! $user = $this->login( $username, $password ) ) {
  4747 		$user = $this->login( $username, $password );
       
  4748 		if ( ! $user ) {
  4679 			return $this->error;
  4749 			return $this->error;
  4680 		}
  4750 		}
  4681 
  4751 
  4682 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4752 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4683 		do_action( 'xmlrpc_call', 'blogger.getUsersBlogs' );
  4753 		do_action( 'xmlrpc_call', 'blogger.getUsersBlogs' );
  4739 	 *
  4809 	 *
  4740 	 * Gives your client some info about you, so you don't have to.
  4810 	 * Gives your client some info about you, so you don't have to.
  4741 	 *
  4811 	 *
  4742 	 * @since 1.5.0
  4812 	 * @since 1.5.0
  4743 	 *
  4813 	 *
  4744 	 * @param array  $args {
  4814 	 * @param array $args {
  4745 	 *     Method arguments. Note: arguments must be ordered as documented.
  4815 	 *     Method arguments. Note: arguments must be ordered as documented.
  4746 	 *
  4816 	 *
  4747 	 *     @type int    $blog_id (unused)
  4817 	 *     @type int    $blog_id (unused)
  4748 	 *     @type string $username
  4818 	 *     @type string $username
  4749 	 *     @type string $password
  4819 	 *     @type string $password
  4754 		$this->escape( $args );
  4824 		$this->escape( $args );
  4755 
  4825 
  4756 		$username = $args[1];
  4826 		$username = $args[1];
  4757 		$password = $args[2];
  4827 		$password = $args[2];
  4758 
  4828 
  4759 		if ( ! $user = $this->login( $username, $password ) ) {
  4829 		$user = $this->login( $username, $password );
       
  4830 		if ( ! $user ) {
  4760 			return $this->error;
  4831 			return $this->error;
  4761 		}
  4832 		}
  4762 
  4833 
  4763 		if ( ! current_user_can( 'edit_posts' ) ) {
  4834 		if ( ! current_user_can( 'edit_posts' ) ) {
  4764 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to access user data on this site.' ) );
  4835 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to access user data on this site.' ) );
  4781 	/**
  4852 	/**
  4782 	 * Retrieve post.
  4853 	 * Retrieve post.
  4783 	 *
  4854 	 *
  4784 	 * @since 1.5.0
  4855 	 * @since 1.5.0
  4785 	 *
  4856 	 *
  4786 	 * @param array  $args {
  4857 	 * @param array $args {
  4787 	 *     Method arguments. Note: arguments must be ordered as documented.
  4858 	 *     Method arguments. Note: arguments must be ordered as documented.
  4788 	 *
  4859 	 *
  4789 	 *     @type int    $blog_id (unused)
  4860 	 *     @type int    $blog_id (unused)
  4790 	 *     @type int    $post_ID
  4861 	 *     @type int    $post_ID
  4791 	 *     @type string $username
  4862 	 *     @type string $username
  4798 
  4869 
  4799 		$post_ID  = (int) $args[1];
  4870 		$post_ID  = (int) $args[1];
  4800 		$username = $args[2];
  4871 		$username = $args[2];
  4801 		$password = $args[3];
  4872 		$password = $args[3];
  4802 
  4873 
  4803 		if ( ! $user = $this->login( $username, $password ) ) {
  4874 		$user = $this->login( $username, $password );
       
  4875 		if ( ! $user ) {
  4804 			return $this->error;
  4876 			return $this->error;
  4805 		}
  4877 		}
  4806 
  4878 
  4807 		$post_data = get_post( $post_ID, ARRAY_A );
  4879 		$post_data = get_post( $post_ID, ARRAY_A );
  4808 		if ( ! $post_data ) {
  4880 		if ( ! $post_data ) {
  4835 	/**
  4907 	/**
  4836 	 * Retrieve list of recent posts.
  4908 	 * Retrieve list of recent posts.
  4837 	 *
  4909 	 *
  4838 	 * @since 1.5.0
  4910 	 * @since 1.5.0
  4839 	 *
  4911 	 *
  4840 	 * @param array  $args {
  4912 	 * @param array $args {
  4841 	 *     Method arguments. Note: arguments must be ordered as documented.
  4913 	 *     Method arguments. Note: arguments must be ordered as documented.
  4842 	 *
  4914 	 *
  4843 	 *     @type string $appkey (unused)
  4915 	 *     @type string $appkey (unused)
  4844 	 *     @type int    $blog_id (unused)
  4916 	 *     @type int    $blog_id (unused)
  4845 	 *     @type string $username
  4917 	 *     @type string $username
  4850 	 */
  4922 	 */
  4851 	public function blogger_getRecentPosts( $args ) {
  4923 	public function blogger_getRecentPosts( $args ) {
  4852 
  4924 
  4853 		$this->escape( $args );
  4925 		$this->escape( $args );
  4854 
  4926 
  4855 		// $args[0] = appkey - ignored
  4927 		// $args[0] = appkey - ignored.
  4856 		$username = $args[2];
  4928 		$username = $args[2];
  4857 		$password = $args[3];
  4929 		$password = $args[3];
  4858 		if ( isset( $args[4] ) ) {
  4930 		if ( isset( $args[4] ) ) {
  4859 			$query = array( 'numberposts' => absint( $args[4] ) );
  4931 			$query = array( 'numberposts' => absint( $args[4] ) );
  4860 		} else {
  4932 		} else {
  4861 			$query = array();
  4933 			$query = array();
  4862 		}
  4934 		}
  4863 
  4935 
  4864 		if ( ! $user = $this->login( $username, $password ) ) {
  4936 		$user = $this->login( $username, $password );
       
  4937 		if ( ! $user ) {
  4865 			return $this->error;
  4938 			return $this->error;
  4866 		}
  4939 		}
  4867 
  4940 
  4868 		if ( ! current_user_can( 'edit_posts' ) ) {
  4941 		if ( ! current_user_can( 'edit_posts' ) ) {
  4869 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit posts.' ) );
  4942 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit posts.' ) );
  4911 	 *
  4984 	 *
  4912 	 * @param array $args Unused.
  4985 	 * @param array $args Unused.
  4913 	 * @return IXR_Error Error object.
  4986 	 * @return IXR_Error Error object.
  4914 	 */
  4987 	 */
  4915 	public function blogger_getTemplate( $args ) {
  4988 	public function blogger_getTemplate( $args ) {
  4916 		return new IXR_Error( 403, __( 'Sorry, that file cannot be edited.' ) );
  4989 		return new IXR_Error( 403, __( 'Sorry, this method is not supported.' ) );
  4917 	}
  4990 	}
  4918 
  4991 
  4919 	/**
  4992 	/**
  4920 	 * Deprecated.
  4993 	 * Deprecated.
  4921 	 *
  4994 	 *
  4924 	 *
  4997 	 *
  4925 	 * @param array $args Unused.
  4998 	 * @param array $args Unused.
  4926 	 * @return IXR_Error Error object.
  4999 	 * @return IXR_Error Error object.
  4927 	 */
  5000 	 */
  4928 	public function blogger_setTemplate( $args ) {
  5001 	public function blogger_setTemplate( $args ) {
  4929 		return new IXR_Error( 403, __( 'Sorry, that file cannot be edited.' ) );
  5002 		return new IXR_Error( 403, __( 'Sorry, this method is not supported.' ) );
  4930 	}
  5003 	}
  4931 
  5004 
  4932 	/**
  5005 	/**
  4933 	 * Creates new post.
  5006 	 * Creates new post.
  4934 	 *
  5007 	 *
  4952 		$username = $args[2];
  5025 		$username = $args[2];
  4953 		$password = $args[3];
  5026 		$password = $args[3];
  4954 		$content  = $args[4];
  5027 		$content  = $args[4];
  4955 		$publish  = $args[5];
  5028 		$publish  = $args[5];
  4956 
  5029 
  4957 		if ( ! $user = $this->login( $username, $password ) ) {
  5030 		$user = $this->login( $username, $password );
       
  5031 		if ( ! $user ) {
  4958 			return $this->error;
  5032 			return $this->error;
  4959 		}
  5033 		}
  4960 
  5034 
  4961 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  5035 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  4962 		do_action( 'xmlrpc_call', 'blogger.newPost' );
  5036 		do_action( 'xmlrpc_call', 'blogger.newPost' );
  4983 		if ( is_wp_error( $post_ID ) ) {
  5057 		if ( is_wp_error( $post_ID ) ) {
  4984 			return new IXR_Error( 500, $post_ID->get_error_message() );
  5058 			return new IXR_Error( 500, $post_ID->get_error_message() );
  4985 		}
  5059 		}
  4986 
  5060 
  4987 		if ( ! $post_ID ) {
  5061 		if ( ! $post_ID ) {
  4988 			return new IXR_Error( 500, __( 'Sorry, your entry could not be posted.' ) );
  5062 			return new IXR_Error( 500, __( 'Sorry, the post could not be created.' ) );
  4989 		}
  5063 		}
  4990 
  5064 
  4991 		$this->attach_uploads( $post_ID, $post_content );
  5065 		$this->attach_uploads( $post_ID, $post_content );
  4992 
  5066 
  4993 		/**
  5067 		/**
  4996 		 * @since 3.4.0
  5070 		 * @since 3.4.0
  4997 		 *
  5071 		 *
  4998 		 * @param int   $post_ID ID of the new post.
  5072 		 * @param int   $post_ID ID of the new post.
  4999 		 * @param array $args    An array of new post arguments.
  5073 		 * @param array $args    An array of new post arguments.
  5000 		 */
  5074 		 */
  5001 		do_action( 'xmlrpc_call_success_blogger_newPost', $post_ID, $args );
  5075 		do_action( 'xmlrpc_call_success_blogger_newPost', $post_ID, $args ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.NotLowercase
  5002 
  5076 
  5003 		return $post_ID;
  5077 		return $post_ID;
  5004 	}
  5078 	}
  5005 
  5079 
  5006 	/**
  5080 	/**
  5007 	 * Edit a post.
  5081 	 * Edit a post.
  5008 	 *
  5082 	 *
  5009 	 * @since 1.5.0
  5083 	 * @since 1.5.0
  5010 	 *
  5084 	 *
  5011 	 * @param array  $args {
  5085 	 * @param array $args {
  5012 	 *     Method arguments. Note: arguments must be ordered as documented.
  5086 	 *     Method arguments. Note: arguments must be ordered as documented.
  5013 	 *
  5087 	 *
  5014 	 *     @type int    $blog_id (unused)
  5088 	 *     @type int    $blog_id (unused)
  5015 	 *     @type int    $post_ID
  5089 	 *     @type int    $post_ID
  5016 	 *     @type string $username
  5090 	 *     @type string $username
  5028 		$username = $args[2];
  5102 		$username = $args[2];
  5029 		$password = $args[3];
  5103 		$password = $args[3];
  5030 		$content  = $args[4];
  5104 		$content  = $args[4];
  5031 		$publish  = $args[5];
  5105 		$publish  = $args[5];
  5032 
  5106 
  5033 		if ( ! $user = $this->login( $username, $password ) ) {
  5107 		$user = $this->login( $username, $password );
       
  5108 		if ( ! $user ) {
  5034 			return $this->error;
  5109 			return $this->error;
  5035 		}
  5110 		}
  5036 
  5111 
  5037 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  5112 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  5038 		do_action( 'xmlrpc_call', 'blogger.editPost' );
  5113 		do_action( 'xmlrpc_call', 'blogger.editPost' );
  5039 
  5114 
  5040 		$actual_post = get_post( $post_ID, ARRAY_A );
  5115 		$actual_post = get_post( $post_ID, ARRAY_A );
  5041 
  5116 
  5042 		if ( ! $actual_post || $actual_post['post_type'] != 'post' ) {
  5117 		if ( ! $actual_post || 'post' !== $actual_post['post_type'] ) {
  5043 			return new IXR_Error( 404, __( 'Sorry, no such post.' ) );
  5118 			return new IXR_Error( 404, __( 'Sorry, no such post.' ) );
  5044 		}
  5119 		}
  5045 
  5120 
  5046 		$this->escape( $actual_post );
  5121 		$this->escape( $actual_post );
  5047 
  5122 
  5048 		if ( ! current_user_can( 'edit_post', $post_ID ) ) {
  5123 		if ( ! current_user_can( 'edit_post', $post_ID ) ) {
  5049 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit this post.' ) );
  5124 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit this post.' ) );
  5050 		}
  5125 		}
  5051 		if ( 'publish' == $actual_post['post_status'] && ! current_user_can( 'publish_posts' ) ) {
  5126 		if ( 'publish' === $actual_post['post_status'] && ! current_user_can( 'publish_posts' ) ) {
  5052 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to publish this post.' ) );
  5127 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to publish this post.' ) );
  5053 		}
  5128 		}
  5054 
  5129 
  5055 		$postdata                  = array();
  5130 		$postdata                  = array();
  5056 		$postdata['ID']            = $actual_post['ID'];
  5131 		$postdata['ID']            = $actual_post['ID'];
  5062 		$postdata['post_status']   = $publish ? 'publish' : 'draft';
  5137 		$postdata['post_status']   = $publish ? 'publish' : 'draft';
  5063 
  5138 
  5064 		$result = wp_update_post( $postdata );
  5139 		$result = wp_update_post( $postdata );
  5065 
  5140 
  5066 		if ( ! $result ) {
  5141 		if ( ! $result ) {
  5067 			return new IXR_Error( 500, __( 'For some strange yet very annoying reason, this post could not be edited.' ) );
  5142 			return new IXR_Error( 500, __( 'Sorry, the post could not be updated.' ) );
  5068 		}
  5143 		}
  5069 		$this->attach_uploads( $actual_post['ID'], $postdata['post_content'] );
  5144 		$this->attach_uploads( $actual_post['ID'], $postdata['post_content'] );
  5070 
  5145 
  5071 		/**
  5146 		/**
  5072 		 * Fires after a post has been successfully updated via the XML-RPC Blogger API.
  5147 		 * Fires after a post has been successfully updated via the XML-RPC Blogger API.
  5074 		 * @since 3.4.0
  5149 		 * @since 3.4.0
  5075 		 *
  5150 		 *
  5076 		 * @param int   $post_ID ID of the updated post.
  5151 		 * @param int   $post_ID ID of the updated post.
  5077 		 * @param array $args    An array of arguments for the post to edit.
  5152 		 * @param array $args    An array of arguments for the post to edit.
  5078 		 */
  5153 		 */
  5079 		do_action( 'xmlrpc_call_success_blogger_editPost', $post_ID, $args );
  5154 		do_action( 'xmlrpc_call_success_blogger_editPost', $post_ID, $args ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.NotLowercase
  5080 
  5155 
  5081 		return true;
  5156 		return true;
  5082 	}
  5157 	}
  5083 
  5158 
  5084 	/**
  5159 	/**
  5085 	 * Remove a post.
  5160 	 * Remove a post.
  5086 	 *
  5161 	 *
  5087 	 * @since 1.5.0
  5162 	 * @since 1.5.0
  5088 	 *
  5163 	 *
  5089 	 * @param array  $args {
  5164 	 * @param array $args {
  5090 	 *     Method arguments. Note: arguments must be ordered as documented.
  5165 	 *     Method arguments. Note: arguments must be ordered as documented.
  5091 	 *
  5166 	 *
  5092 	 *     @type int    $blog_id (unused)
  5167 	 *     @type int    $blog_id (unused)
  5093 	 *     @type int    $post_ID
  5168 	 *     @type int    $post_ID
  5094 	 *     @type string $username
  5169 	 *     @type string $username
  5101 
  5176 
  5102 		$post_ID  = (int) $args[1];
  5177 		$post_ID  = (int) $args[1];
  5103 		$username = $args[2];
  5178 		$username = $args[2];
  5104 		$password = $args[3];
  5179 		$password = $args[3];
  5105 
  5180 
  5106 		if ( ! $user = $this->login( $username, $password ) ) {
  5181 		$user = $this->login( $username, $password );
       
  5182 		if ( ! $user ) {
  5107 			return $this->error;
  5183 			return $this->error;
  5108 		}
  5184 		}
  5109 
  5185 
  5110 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  5186 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  5111 		do_action( 'xmlrpc_call', 'blogger.deletePost' );
  5187 		do_action( 'xmlrpc_call', 'blogger.deletePost' );
  5112 
  5188 
  5113 		$actual_post = get_post( $post_ID, ARRAY_A );
  5189 		$actual_post = get_post( $post_ID, ARRAY_A );
  5114 
  5190 
  5115 		if ( ! $actual_post || $actual_post['post_type'] != 'post' ) {
  5191 		if ( ! $actual_post || 'post' !== $actual_post['post_type'] ) {
  5116 			return new IXR_Error( 404, __( 'Sorry, no such post.' ) );
  5192 			return new IXR_Error( 404, __( 'Sorry, no such post.' ) );
  5117 		}
  5193 		}
  5118 
  5194 
  5119 		if ( ! current_user_can( 'delete_post', $post_ID ) ) {
  5195 		if ( ! current_user_can( 'delete_post', $post_ID ) ) {
  5120 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to delete this post.' ) );
  5196 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to delete this post.' ) );
  5121 		}
  5197 		}
  5122 
  5198 
  5123 		$result = wp_delete_post( $post_ID );
  5199 		$result = wp_delete_post( $post_ID );
  5124 
  5200 
  5125 		if ( ! $result ) {
  5201 		if ( ! $result ) {
  5126 			return new IXR_Error( 500, __( 'The post cannot be deleted.' ) );
  5202 			return new IXR_Error( 500, __( 'Sorry, the post could not be deleted.' ) );
  5127 		}
  5203 		}
  5128 
  5204 
  5129 		/**
  5205 		/**
  5130 		 * Fires after a post has been successfully deleted via the XML-RPC Blogger API.
  5206 		 * Fires after a post has been successfully deleted via the XML-RPC Blogger API.
  5131 		 *
  5207 		 *
  5132 		 * @since 3.4.0
  5208 		 * @since 3.4.0
  5133 		 *
  5209 		 *
  5134 		 * @param int   $post_ID ID of the deleted post.
  5210 		 * @param int   $post_ID ID of the deleted post.
  5135 		 * @param array $args    An array of arguments to delete the post.
  5211 		 * @param array $args    An array of arguments to delete the post.
  5136 		 */
  5212 		 */
  5137 		do_action( 'xmlrpc_call_success_blogger_deletePost', $post_ID, $args );
  5213 		do_action( 'xmlrpc_call_success_blogger_deletePost', $post_ID, $args ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.NotLowercase
  5138 
  5214 
  5139 		return true;
  5215 		return true;
  5140 	}
  5216 	}
  5141 
  5217 
  5142 	/* MetaWeblog API functions
  5218 	/*
  5143 	 * specs on wherever Dave Winer wants them to be
  5219 	 * MetaWeblog API functions.
       
  5220 	 * Specs on wherever Dave Winer wants them to be.
  5144 	 */
  5221 	 */
  5145 
  5222 
  5146 	/**
  5223 	/**
  5147 	 * Create a new post.
  5224 	 * Create a new post.
  5148 	 *
  5225 	 *
  5168 	 *  - dateCreated
  5245 	 *  - dateCreated
  5169 	 *  - wp_post_thumbnail
  5246 	 *  - wp_post_thumbnail
  5170 	 *
  5247 	 *
  5171 	 * @since 1.5.0
  5248 	 * @since 1.5.0
  5172 	 *
  5249 	 *
  5173 	 * @param array  $args {
  5250 	 * @param array $args {
  5174 	 *     Method arguments. Note: arguments must be ordered as documented.
  5251 	 *     Method arguments. Note: arguments must be ordered as documented.
  5175 	 *
  5252 	 *
  5176 	 *     @type int    $blog_id (unused)
  5253 	 *     @type int    $blog_id (unused)
  5177 	 *     @type string $username
  5254 	 *     @type string $username
  5178 	 *     @type string $password
  5255 	 *     @type string $password
  5187 		$username       = $args[1];
  5264 		$username       = $args[1];
  5188 		$password       = $args[2];
  5265 		$password       = $args[2];
  5189 		$content_struct = $args[3];
  5266 		$content_struct = $args[3];
  5190 		$publish        = isset( $args[4] ) ? $args[4] : 0;
  5267 		$publish        = isset( $args[4] ) ? $args[4] : 0;
  5191 
  5268 
  5192 		if ( ! $user = $this->login( $username, $password ) ) {
  5269 		$user = $this->login( $username, $password );
       
  5270 		if ( ! $user ) {
  5193 			return $this->error;
  5271 			return $this->error;
  5194 		}
  5272 		}
  5195 
  5273 
  5196 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  5274 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  5197 		do_action( 'xmlrpc_call', 'metaWeblog.newPost' );
  5275 		do_action( 'xmlrpc_call', 'metaWeblog.newPost' );
  5198 
  5276 
  5199 		$page_template = '';
  5277 		$page_template = '';
  5200 		if ( ! empty( $content_struct['post_type'] ) ) {
  5278 		if ( ! empty( $content_struct['post_type'] ) ) {
  5201 			if ( $content_struct['post_type'] == 'page' ) {
  5279 			if ( 'page' === $content_struct['post_type'] ) {
  5202 				if ( $publish ) {
  5280 				if ( $publish ) {
  5203 					$cap = 'publish_pages';
  5281 					$cap = 'publish_pages';
  5204 				} elseif ( isset( $content_struct['page_status'] ) && 'publish' == $content_struct['page_status'] ) {
  5282 				} elseif ( isset( $content_struct['page_status'] ) && 'publish' === $content_struct['page_status'] ) {
  5205 					$cap = 'publish_pages';
  5283 					$cap = 'publish_pages';
  5206 				} else {
  5284 				} else {
  5207 					$cap = 'edit_pages';
  5285 					$cap = 'edit_pages';
  5208 				}
  5286 				}
  5209 				$error_message = __( 'Sorry, you are not allowed to publish pages on this site.' );
  5287 				$error_message = __( 'Sorry, you are not allowed to publish pages on this site.' );
  5210 				$post_type     = 'page';
  5288 				$post_type     = 'page';
  5211 				if ( ! empty( $content_struct['wp_page_template'] ) ) {
  5289 				if ( ! empty( $content_struct['wp_page_template'] ) ) {
  5212 					$page_template = $content_struct['wp_page_template'];
  5290 					$page_template = $content_struct['wp_page_template'];
  5213 				}
  5291 				}
  5214 			} elseif ( $content_struct['post_type'] == 'post' ) {
  5292 			} elseif ( 'post' === $content_struct['post_type'] ) {
  5215 				if ( $publish ) {
  5293 				if ( $publish ) {
  5216 					$cap = 'publish_posts';
  5294 					$cap = 'publish_posts';
  5217 				} elseif ( isset( $content_struct['post_status'] ) && 'publish' == $content_struct['post_status'] ) {
  5295 				} elseif ( isset( $content_struct['post_status'] ) && 'publish' === $content_struct['post_status'] ) {
  5218 					$cap = 'publish_posts';
  5296 					$cap = 'publish_posts';
  5219 				} else {
  5297 				} else {
  5220 					$cap = 'edit_posts';
  5298 					$cap = 'edit_posts';
  5221 				}
  5299 				}
  5222 				$error_message = __( 'Sorry, you are not allowed to publish posts on this site.' );
  5300 				$error_message = __( 'Sorry, you are not allowed to publish posts on this site.' );
  5223 				$post_type     = 'post';
  5301 				$post_type     = 'post';
  5224 			} else {
  5302 			} else {
  5225 				// No other post_type values are allowed here
  5303 				// No other 'post_type' values are allowed here.
  5226 				return new IXR_Error( 401, __( 'Invalid post type.' ) );
  5304 				return new IXR_Error( 401, __( 'Invalid post type.' ) );
  5227 			}
  5305 			}
  5228 		} else {
  5306 		} else {
  5229 			if ( $publish ) {
  5307 			if ( $publish ) {
  5230 				$cap = 'publish_posts';
  5308 				$cap = 'publish_posts';
  5231 			} elseif ( isset( $content_struct['post_status'] ) && 'publish' == $content_struct['post_status'] ) {
  5309 			} elseif ( isset( $content_struct['post_status'] ) && 'publish' === $content_struct['post_status'] ) {
  5232 				$cap = 'publish_posts';
  5310 				$cap = 'publish_posts';
  5233 			} else {
  5311 			} else {
  5234 				$cap = 'edit_posts';
  5312 				$cap = 'edit_posts';
  5235 			}
  5313 			}
  5236 			$error_message = __( 'Sorry, you are not allowed to publish posts on this site.' );
  5314 			$error_message = __( 'Sorry, you are not allowed to publish posts on this site.' );
  5242 		}
  5320 		}
  5243 		if ( ! current_user_can( $cap ) ) {
  5321 		if ( ! current_user_can( $cap ) ) {
  5244 			return new IXR_Error( 401, $error_message );
  5322 			return new IXR_Error( 401, $error_message );
  5245 		}
  5323 		}
  5246 
  5324 
  5247 		// Check for a valid post format if one was given
  5325 		// Check for a valid post format if one was given.
  5248 		if ( isset( $content_struct['wp_post_format'] ) ) {
  5326 		if ( isset( $content_struct['wp_post_format'] ) ) {
  5249 			$content_struct['wp_post_format'] = sanitize_key( $content_struct['wp_post_format'] );
  5327 			$content_struct['wp_post_format'] = sanitize_key( $content_struct['wp_post_format'] );
  5250 			if ( ! array_key_exists( $content_struct['wp_post_format'], get_post_format_strings() ) ) {
  5328 			if ( ! array_key_exists( $content_struct['wp_post_format'], get_post_format_strings() ) ) {
  5251 				return new IXR_Error( 404, __( 'Invalid post format.' ) );
  5329 				return new IXR_Error( 404, __( 'Invalid post format.' ) );
  5252 			}
  5330 			}
  5253 		}
  5331 		}
  5254 
  5332 
  5255 		// Let WordPress generate the post_name (slug) unless
  5333 		// Let WordPress generate the 'post_name' (slug) unless
  5256 		// one has been provided.
  5334 		// one has been provided.
  5257 		$post_name = '';
  5335 		$post_name = '';
  5258 		if ( isset( $content_struct['wp_slug'] ) ) {
  5336 		if ( isset( $content_struct['wp_slug'] ) ) {
  5259 			$post_name = $content_struct['wp_slug'];
  5337 			$post_name = $content_struct['wp_slug'];
  5260 		}
  5338 		}
  5264 			$post_password = $content_struct['wp_password'];
  5342 			$post_password = $content_struct['wp_password'];
  5265 		} else {
  5343 		} else {
  5266 			$post_password = '';
  5344 			$post_password = '';
  5267 		}
  5345 		}
  5268 
  5346 
  5269 		// Only set a post parent if one was provided.
  5347 		// Only set a post parent if one was given.
  5270 		if ( isset( $content_struct['wp_page_parent_id'] ) ) {
  5348 		if ( isset( $content_struct['wp_page_parent_id'] ) ) {
  5271 			$post_parent = $content_struct['wp_page_parent_id'];
  5349 			$post_parent = $content_struct['wp_page_parent_id'];
  5272 		} else {
  5350 		} else {
  5273 			$post_parent = 0;
  5351 			$post_parent = 0;
  5274 		}
  5352 		}
  5275 
  5353 
  5276 		// Only set the menu_order if it was provided.
  5354 		// Only set the 'menu_order' if it was given.
  5277 		if ( isset( $content_struct['wp_page_order'] ) ) {
  5355 		if ( isset( $content_struct['wp_page_order'] ) ) {
  5278 			$menu_order = $content_struct['wp_page_order'];
  5356 			$menu_order = $content_struct['wp_page_order'];
  5279 		} else {
  5357 		} else {
  5280 			$menu_order = 0;
  5358 			$menu_order = 0;
  5281 		}
  5359 		}
  5400 			if ( is_array( $to_ping ) ) {
  5478 			if ( is_array( $to_ping ) ) {
  5401 				$to_ping = implode( ' ', $to_ping );
  5479 				$to_ping = implode( ' ', $to_ping );
  5402 			}
  5480 			}
  5403 		}
  5481 		}
  5404 
  5482 
  5405 		// Do some timestamp voodoo
  5483 		// Do some timestamp voodoo.
  5406 		if ( ! empty( $content_struct['date_created_gmt'] ) ) {
  5484 		if ( ! empty( $content_struct['date_created_gmt'] ) ) {
  5407 			// We know this is supposed to be GMT, so we're going to slap that Z on there by force
  5485 			// We know this is supposed to be GMT, so we're going to slap that Z on there by force.
  5408 			$dateCreated = rtrim( $content_struct['date_created_gmt']->getIso(), 'Z' ) . 'Z';
  5486 			$dateCreated = rtrim( $content_struct['date_created_gmt']->getIso(), 'Z' ) . 'Z';
  5409 		} elseif ( ! empty( $content_struct['dateCreated'] ) ) {
  5487 		} elseif ( ! empty( $content_struct['dateCreated'] ) ) {
  5410 			$dateCreated = $content_struct['dateCreated']->getIso();
  5488 			$dateCreated = $content_struct['dateCreated']->getIso();
  5411 		}
  5489 		}
  5412 
  5490 
  5413 		if ( ! empty( $dateCreated ) ) {
  5491 		if ( ! empty( $dateCreated ) ) {
  5414 			$post_date     = get_date_from_gmt( iso8601_to_datetime( $dateCreated ) );
  5492 			$post_date     = iso8601_to_datetime( $dateCreated );
  5415 			$post_date_gmt = iso8601_to_datetime( $dateCreated, 'GMT' );
  5493 			$post_date_gmt = iso8601_to_datetime( $dateCreated, 'gmt' );
  5416 		} else {
  5494 		} else {
  5417 			$post_date     = '';
  5495 			$post_date     = '';
  5418 			$post_date_gmt = '';
  5496 			$post_date_gmt = '';
  5419 		}
  5497 		}
  5420 
  5498 
  5429 			}
  5507 			}
  5430 		}
  5508 		}
  5431 
  5509 
  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' );
  5510 		$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' );
  5433 
  5511 
  5434 		$post_ID = $postdata['ID'] = get_default_post_to_edit( $post_type, true )->ID;
  5512 		$post_ID        = get_default_post_to_edit( $post_type, true )->ID;
  5435 
  5513 		$postdata['ID'] = $post_ID;
  5436 		// Only posts can be sticky
  5514 
  5437 		if ( $post_type == 'post' && isset( $content_struct['sticky'] ) ) {
  5515 		// Only posts can be sticky.
       
  5516 		if ( 'post' === $post_type && isset( $content_struct['sticky'] ) ) {
  5438 			$data           = $postdata;
  5517 			$data           = $postdata;
  5439 			$data['sticky'] = $content_struct['sticky'];
  5518 			$data['sticky'] = $content_struct['sticky'];
  5440 			$error          = $this->_toggle_sticky( $data );
  5519 			$error          = $this->_toggle_sticky( $data );
  5441 			if ( $error ) {
  5520 			if ( $error ) {
  5442 				return $error;
  5521 				return $error;
  5453 			}
  5532 			}
  5454 
  5533 
  5455 			unset( $content_struct['wp_post_thumbnail'] );
  5534 			unset( $content_struct['wp_post_thumbnail'] );
  5456 		}
  5535 		}
  5457 
  5536 
  5458 		// Handle enclosures
  5537 		// Handle enclosures.
  5459 		$thisEnclosure = isset( $content_struct['enclosure'] ) ? $content_struct['enclosure'] : null;
  5538 		$thisEnclosure = isset( $content_struct['enclosure'] ) ? $content_struct['enclosure'] : null;
  5460 		$this->add_enclosure_if_new( $post_ID, $thisEnclosure );
  5539 		$this->add_enclosure_if_new( $post_ID, $thisEnclosure );
  5461 
  5540 
  5462 		$this->attach_uploads( $post_ID, $post_content );
  5541 		$this->attach_uploads( $post_ID, $post_content );
  5463 
  5542 
  5464 		// Handle post formats if assigned, value is validated earlier
  5543 		// Handle post formats if assigned, value is validated earlier
  5465 		// in this function
  5544 		// in this function.
  5466 		if ( isset( $content_struct['wp_post_format'] ) ) {
  5545 		if ( isset( $content_struct['wp_post_format'] ) ) {
  5467 			set_post_format( $post_ID, $content_struct['wp_post_format'] );
  5546 			set_post_format( $post_ID, $content_struct['wp_post_format'] );
  5468 		}
  5547 		}
  5469 
  5548 
  5470 		$post_ID = wp_insert_post( $postdata, true );
  5549 		$post_ID = wp_insert_post( $postdata, true );
  5471 		if ( is_wp_error( $post_ID ) ) {
  5550 		if ( is_wp_error( $post_ID ) ) {
  5472 			return new IXR_Error( 500, $post_ID->get_error_message() );
  5551 			return new IXR_Error( 500, $post_ID->get_error_message() );
  5473 		}
  5552 		}
  5474 
  5553 
  5475 		if ( ! $post_ID ) {
  5554 		if ( ! $post_ID ) {
  5476 			return new IXR_Error( 500, __( 'Sorry, your entry could not be posted.' ) );
  5555 			return new IXR_Error( 500, __( 'Sorry, the post could not be created.' ) );
  5477 		}
  5556 		}
  5478 
  5557 
  5479 		/**
  5558 		/**
  5480 		 * Fires after a new post has been successfully created via the XML-RPC MovableType API.
  5559 		 * Fires after a new post has been successfully created via the XML-RPC MovableType API.
  5481 		 *
  5560 		 *
  5482 		 * @since 3.4.0
  5561 		 * @since 3.4.0
  5483 		 *
  5562 		 *
  5484 		 * @param int   $post_ID ID of the new post.
  5563 		 * @param int   $post_ID ID of the new post.
  5485 		 * @param array $args    An array of arguments to create the new post.
  5564 		 * @param array $args    An array of arguments to create the new post.
  5486 		 */
  5565 		 */
  5487 		do_action( 'xmlrpc_call_success_mw_newPost', $post_ID, $args );
  5566 		do_action( 'xmlrpc_call_success_mw_newPost', $post_ID, $args ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.NotLowercase
  5488 
  5567 
  5489 		return strval( $post_ID );
  5568 		return strval( $post_ID );
  5490 	}
  5569 	}
  5491 
  5570 
  5492 	/**
  5571 	/**
  5497 	 * @param integer $post_ID   Post ID.
  5576 	 * @param integer $post_ID   Post ID.
  5498 	 * @param array   $enclosure Enclosure data.
  5577 	 * @param array   $enclosure Enclosure data.
  5499 	 */
  5578 	 */
  5500 	public function add_enclosure_if_new( $post_ID, $enclosure ) {
  5579 	public function add_enclosure_if_new( $post_ID, $enclosure ) {
  5501 		if ( is_array( $enclosure ) && isset( $enclosure['url'] ) && isset( $enclosure['length'] ) && isset( $enclosure['type'] ) ) {
  5580 		if ( is_array( $enclosure ) && isset( $enclosure['url'] ) && isset( $enclosure['length'] ) && isset( $enclosure['type'] ) ) {
  5502 			$encstring = $enclosure['url'] . "\n" . $enclosure['length'] . "\n" . $enclosure['type'] . "\n";
  5581 			$encstring  = $enclosure['url'] . "\n" . $enclosure['length'] . "\n" . $enclosure['type'] . "\n";
  5503 			$found     = false;
  5582 			$found      = false;
  5504 			if ( $enclosures = get_post_meta( $post_ID, 'enclosure' ) ) {
  5583 			$enclosures = get_post_meta( $post_ID, 'enclosure' );
       
  5584 			if ( $enclosures ) {
  5505 				foreach ( $enclosures as $enc ) {
  5585 				foreach ( $enclosures as $enc ) {
  5506 					// This method used to omit the trailing new line. #23219
  5586 					// This method used to omit the trailing new line. #23219
  5507 					if ( rtrim( $enc, "\n" ) == rtrim( $encstring, "\n" ) ) {
  5587 					if ( rtrim( $enc, "\n" ) == rtrim( $encstring, "\n" ) ) {
  5508 						$found = true;
  5588 						$found = true;
  5509 						break;
  5589 						break;
  5521 	 *
  5601 	 *
  5522 	 * @since 2.1.0
  5602 	 * @since 2.1.0
  5523 	 *
  5603 	 *
  5524 	 * @global wpdb $wpdb WordPress database abstraction object.
  5604 	 * @global wpdb $wpdb WordPress database abstraction object.
  5525 	 *
  5605 	 *
  5526 	 * @param int $post_ID Post ID.
  5606 	 * @param int    $post_ID      Post ID.
  5527 	 * @param string $post_content Post Content for attachment.
  5607 	 * @param string $post_content Post Content for attachment.
  5528 	 */
  5608 	 */
  5529 	public function attach_uploads( $post_ID, $post_content ) {
  5609 	public function attach_uploads( $post_ID, $post_content ) {
  5530 		global $wpdb;
  5610 		global $wpdb;
  5531 
  5611 
  5532 		// find any unattached files
  5612 		// Find any unattached files.
  5533 		$attachments = $wpdb->get_results( "SELECT ID, guid FROM {$wpdb->posts} WHERE post_parent = '0' AND post_type = 'attachment'" );
  5613 		$attachments = $wpdb->get_results( "SELECT ID, guid FROM {$wpdb->posts} WHERE post_parent = '0' AND post_type = 'attachment'" );
  5534 		if ( is_array( $attachments ) ) {
  5614 		if ( is_array( $attachments ) ) {
  5535 			foreach ( $attachments as $file ) {
  5615 			foreach ( $attachments as $file ) {
  5536 				if ( ! empty( $file->guid ) && strpos( $post_content, $file->guid ) !== false ) {
  5616 				if ( ! empty( $file->guid ) && strpos( $post_content, $file->guid ) !== false ) {
  5537 					$wpdb->update( $wpdb->posts, array( 'post_parent' => $post_ID ), array( 'ID' => $file->ID ) );
  5617 					$wpdb->update( $wpdb->posts, array( 'post_parent' => $post_ID ), array( 'ID' => $file->ID ) );
  5543 	/**
  5623 	/**
  5544 	 * Edit a post.
  5624 	 * Edit a post.
  5545 	 *
  5625 	 *
  5546 	 * @since 1.5.0
  5626 	 * @since 1.5.0
  5547 	 *
  5627 	 *
  5548 	 * @param array  $args {
  5628 	 * @param array $args {
  5549 	 *     Method arguments. Note: arguments must be ordered as documented.
  5629 	 *     Method arguments. Note: arguments must be ordered as documented.
  5550 	 *
  5630 	 *
  5551 	 *     @type int    $blog_id (unused)
  5631 	 *     @type int    $blog_id (unused)
  5552 	 *     @type string $username
  5632 	 *     @type string $username
  5553 	 *     @type string $password
  5633 	 *     @type string $password
  5563 		$username       = $args[1];
  5643 		$username       = $args[1];
  5564 		$password       = $args[2];
  5644 		$password       = $args[2];
  5565 		$content_struct = $args[3];
  5645 		$content_struct = $args[3];
  5566 		$publish        = isset( $args[4] ) ? $args[4] : 0;
  5646 		$publish        = isset( $args[4] ) ? $args[4] : 0;
  5567 
  5647 
  5568 		if ( ! $user = $this->login( $username, $password ) ) {
  5648 		$user = $this->login( $username, $password );
       
  5649 		if ( ! $user ) {
  5569 			return $this->error;
  5650 			return $this->error;
  5570 		}
  5651 		}
  5571 
  5652 
  5572 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  5653 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  5573 		do_action( 'xmlrpc_call', 'metaWeblog.editPost' );
  5654 		do_action( 'xmlrpc_call', 'metaWeblog.editPost' );
  5574 
  5655 
  5575 		$postdata = get_post( $post_ID, ARRAY_A );
  5656 		$postdata = get_post( $post_ID, ARRAY_A );
  5576 
  5657 
  5577 		/*
  5658 		/*
  5578 		 * If there is no post data for the give post id, stop now and return an error.
  5659 		 * If there is no post data for the give post ID, stop now and return an error.
  5579 		 * Otherwise a new post will be created (which was the old behavior).
  5660 		 * Otherwise a new post will be created (which was the old behavior).
  5580 		 */
  5661 		 */
  5581 		if ( ! $postdata || empty( $postdata['ID'] ) ) {
  5662 		if ( ! $postdata || empty( $postdata['ID'] ) ) {
  5582 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  5663 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  5583 		}
  5664 		}
  5585 		if ( ! current_user_can( 'edit_post', $post_ID ) ) {
  5666 		if ( ! current_user_can( 'edit_post', $post_ID ) ) {
  5586 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit this post.' ) );
  5667 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit this post.' ) );
  5587 		}
  5668 		}
  5588 
  5669 
  5589 		// Use wp.editPost to edit post types other than post and page.
  5670 		// Use wp.editPost to edit post types other than post and page.
  5590 		if ( ! in_array( $postdata['post_type'], array( 'post', 'page' ) ) ) {
  5671 		if ( ! in_array( $postdata['post_type'], array( 'post', 'page' ), true ) ) {
  5591 			return new IXR_Error( 401, __( 'Invalid post type.' ) );
  5672 			return new IXR_Error( 401, __( 'Invalid post type.' ) );
  5592 		}
  5673 		}
  5593 
  5674 
  5594 		// Thwart attempt to change the post type.
  5675 		// Thwart attempt to change the post type.
  5595 		if ( ! empty( $content_struct['post_type'] ) && ( $content_struct['post_type'] != $postdata['post_type'] ) ) {
  5676 		if ( ! empty( $content_struct['post_type'] ) && ( $content_struct['post_type'] != $postdata['post_type'] ) ) {
  5596 			return new IXR_Error( 401, __( 'The post type may not be changed.' ) );
  5677 			return new IXR_Error( 401, __( 'The post type may not be changed.' ) );
  5597 		}
  5678 		}
  5598 
  5679 
  5599 		// Check for a valid post format if one was given
  5680 		// Check for a valid post format if one was given.
  5600 		if ( isset( $content_struct['wp_post_format'] ) ) {
  5681 		if ( isset( $content_struct['wp_post_format'] ) ) {
  5601 			$content_struct['wp_post_format'] = sanitize_key( $content_struct['wp_post_format'] );
  5682 			$content_struct['wp_post_format'] = sanitize_key( $content_struct['wp_post_format'] );
  5602 			if ( ! array_key_exists( $content_struct['wp_post_format'], get_post_format_strings() ) ) {
  5683 			if ( ! array_key_exists( $content_struct['wp_post_format'], get_post_format_strings() ) ) {
  5603 				return new IXR_Error( 404, __( 'Invalid post format.' ) );
  5684 				return new IXR_Error( 404, __( 'Invalid post format.' ) );
  5604 			}
  5685 			}
  5631 		// Only set a post parent if one was given.
  5712 		// Only set a post parent if one was given.
  5632 		if ( isset( $content_struct['wp_page_parent_id'] ) ) {
  5713 		if ( isset( $content_struct['wp_page_parent_id'] ) ) {
  5633 			$post_parent = $content_struct['wp_page_parent_id'];
  5714 			$post_parent = $content_struct['wp_page_parent_id'];
  5634 		}
  5715 		}
  5635 
  5716 
  5636 		// Only set the menu_order if it was given.
  5717 		// Only set the 'menu_order' if it was given.
  5637 		if ( isset( $content_struct['wp_page_order'] ) ) {
  5718 		if ( isset( $content_struct['wp_page_order'] ) ) {
  5638 			$menu_order = $content_struct['wp_page_order'];
  5719 			$menu_order = $content_struct['wp_page_order'];
  5639 		}
  5720 		}
  5640 
  5721 
  5641 		$page_template = null;
  5722 		$page_template = null;
  5642 		if ( ! empty( $content_struct['wp_page_template'] ) && 'page' == $post_type ) {
  5723 		if ( ! empty( $content_struct['wp_page_template'] ) && 'page' === $post_type ) {
  5643 			$page_template = $content_struct['wp_page_template'];
  5724 			$page_template = $content_struct['wp_page_template'];
  5644 		}
  5725 		}
  5645 
  5726 
  5646 		$post_author = $postdata['post_author'];
  5727 		$post_author = $postdata['post_author'];
  5647 
  5728 
  5648 		// Only set the post_author if one is set.
  5729 		// If an author id was provided then use it instead.
  5649 		if ( isset( $content_struct['wp_author_id'] ) ) {
  5730 		if ( isset( $content_struct['wp_author_id'] ) ) {
  5650 			// Check permissions if attempting to switch author to or from another user.
  5731 			// Check permissions if attempting to switch author to or from another user.
  5651 			if ( $user->ID != $content_struct['wp_author_id'] || $user->ID != $post_author ) {
  5732 			if ( $user->ID != $content_struct['wp_author_id'] || $user->ID != $post_author ) {
  5652 				switch ( $post_type ) {
  5733 				switch ( $post_type ) {
  5653 					case 'post':
  5734 					case 'post':
  5763 			}
  5844 			}
  5764 		}
  5845 		}
  5765 
  5846 
  5766 		$tags_input = isset( $content_struct['mt_keywords'] ) ? $content_struct['mt_keywords'] : null;
  5847 		$tags_input = isset( $content_struct['mt_keywords'] ) ? $content_struct['mt_keywords'] : null;
  5767 
  5848 
  5768 		if ( 'publish' == $post_status || 'private' == $post_status ) {
  5849 		if ( 'publish' === $post_status || 'private' === $post_status ) {
  5769 			if ( 'page' == $post_type && ! current_user_can( 'publish_pages' ) ) {
  5850 			if ( 'page' === $post_type && ! current_user_can( 'publish_pages' ) ) {
  5770 				return new IXR_Error( 401, __( 'Sorry, you are not allowed to publish this page.' ) );
  5851 				return new IXR_Error( 401, __( 'Sorry, you are not allowed to publish this page.' ) );
  5771 			} elseif ( ! current_user_can( 'publish_posts' ) ) {
  5852 			} elseif ( ! current_user_can( 'publish_posts' ) ) {
  5772 				return new IXR_Error( 401, __( 'Sorry, you are not allowed to publish this post.' ) );
  5853 				return new IXR_Error( 401, __( 'Sorry, you are not allowed to publish this post.' ) );
  5773 			}
  5854 			}
  5774 		}
  5855 		}
  5795 
  5876 
  5796 		// Default to not flagging the post date to be edited unless it's intentional.
  5877 		// Default to not flagging the post date to be edited unless it's intentional.
  5797 		$edit_date = false;
  5878 		$edit_date = false;
  5798 
  5879 
  5799 		if ( ! empty( $dateCreated ) ) {
  5880 		if ( ! empty( $dateCreated ) ) {
  5800 			$post_date     = get_date_from_gmt( iso8601_to_datetime( $dateCreated ) );
  5881 			$post_date     = iso8601_to_datetime( $dateCreated );
  5801 			$post_date_gmt = iso8601_to_datetime( $dateCreated, 'GMT' );
  5882 			$post_date_gmt = iso8601_to_datetime( $dateCreated, 'gmt' );
  5802 
  5883 
  5803 			// Flag the post date to be edited.
  5884 			// Flag the post date to be edited.
  5804 			$edit_date = true;
  5885 			$edit_date = true;
  5805 		} else {
  5886 		} else {
  5806 			$post_date     = $postdata['post_date'];
  5887 			$post_date     = $postdata['post_date'];
  5814 		if ( is_wp_error( $result ) ) {
  5895 		if ( is_wp_error( $result ) ) {
  5815 			return new IXR_Error( 500, $result->get_error_message() );
  5896 			return new IXR_Error( 500, $result->get_error_message() );
  5816 		}
  5897 		}
  5817 
  5898 
  5818 		if ( ! $result ) {
  5899 		if ( ! $result ) {
  5819 			return new IXR_Error( 500, __( 'Sorry, your entry could not be edited.' ) );
  5900 			return new IXR_Error( 500, __( 'Sorry, the post could not be updated.' ) );
  5820 		}
  5901 		}
  5821 
  5902 
  5822 		// Only posts can be sticky
  5903 		// Only posts can be sticky.
  5823 		if ( $post_type == 'post' && isset( $content_struct['sticky'] ) ) {
  5904 		if ( 'post' === $post_type && isset( $content_struct['sticky'] ) ) {
  5824 			$data              = $newpost;
  5905 			$data              = $newpost;
  5825 			$data['sticky']    = $content_struct['sticky'];
  5906 			$data['sticky']    = $content_struct['sticky'];
  5826 			$data['post_type'] = 'post';
  5907 			$data['post_type'] = 'post';
  5827 			$error             = $this->_toggle_sticky( $data, true );
  5908 			$error             = $this->_toggle_sticky( $data, true );
  5828 			if ( $error ) {
  5909 			if ( $error ) {
  5864 		 * @since 3.4.0
  5945 		 * @since 3.4.0
  5865 		 *
  5946 		 *
  5866 		 * @param int   $post_ID ID of the updated post.
  5947 		 * @param int   $post_ID ID of the updated post.
  5867 		 * @param array $args    An array of arguments to update the post.
  5948 		 * @param array $args    An array of arguments to update the post.
  5868 		 */
  5949 		 */
  5869 		do_action( 'xmlrpc_call_success_mw_editPost', $post_ID, $args );
  5950 		do_action( 'xmlrpc_call_success_mw_editPost', $post_ID, $args ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.NotLowercase
  5870 
  5951 
  5871 		return true;
  5952 		return true;
  5872 	}
  5953 	}
  5873 
  5954 
  5874 	/**
  5955 	/**
  5875 	 * Retrieve post.
  5956 	 * Retrieve post.
  5876 	 *
  5957 	 *
  5877 	 * @since 1.5.0
  5958 	 * @since 1.5.0
  5878 	 *
  5959 	 *
  5879 	 * @param array  $args {
  5960 	 * @param array $args {
  5880 	 *     Method arguments. Note: arguments must be ordered as documented.
  5961 	 *     Method arguments. Note: arguments must be ordered as documented.
  5881 	 *
  5962 	 *
  5882 	 *     @type int    $blog_id (unused)
  5963 	 *     @type int    $blog_id (unused)
  5883 	 *     @type int    $post_ID
  5964 	 *     @type int    $post_ID
  5884 	 *     @type string $username
  5965 	 *     @type string $username
  5891 
  5972 
  5892 		$post_ID  = (int) $args[0];
  5973 		$post_ID  = (int) $args[0];
  5893 		$username = $args[1];
  5974 		$username = $args[1];
  5894 		$password = $args[2];
  5975 		$password = $args[2];
  5895 
  5976 
  5896 		if ( ! $user = $this->login( $username, $password ) ) {
  5977 		$user = $this->login( $username, $password );
       
  5978 		if ( ! $user ) {
  5897 			return $this->error;
  5979 			return $this->error;
  5898 		}
  5980 		}
  5899 
  5981 
  5900 		$postdata = get_post( $post_ID, ARRAY_A );
  5982 		$postdata = get_post( $post_ID, ARRAY_A );
  5901 		if ( ! $postdata ) {
  5983 		if ( ! $postdata ) {
  5907 		}
  5989 		}
  5908 
  5990 
  5909 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  5991 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  5910 		do_action( 'xmlrpc_call', 'metaWeblog.getPost' );
  5992 		do_action( 'xmlrpc_call', 'metaWeblog.getPost' );
  5911 
  5993 
  5912 		if ( $postdata['post_date'] != '' ) {
  5994 		if ( '' !== $postdata['post_date'] ) {
  5913 			$post_date         = $this->_convert_date( $postdata['post_date'] );
  5995 			$post_date         = $this->_convert_date( $postdata['post_date'] );
  5914 			$post_date_gmt     = $this->_convert_date_gmt( $postdata['post_date_gmt'], $postdata['post_date'] );
  5996 			$post_date_gmt     = $this->_convert_date_gmt( $postdata['post_date_gmt'], $postdata['post_date'] );
  5915 			$post_modified     = $this->_convert_date( $postdata['post_modified'] );
  5997 			$post_modified     = $this->_convert_date( $postdata['post_modified'] );
  5916 			$post_modified_gmt = $this->_convert_date_gmt( $postdata['post_modified_gmt'], $postdata['post_modified'] );
  5998 			$post_modified_gmt = $this->_convert_date_gmt( $postdata['post_modified_gmt'], $postdata['post_modified'] );
  5917 
  5999 
  5936 			$link = get_permalink( $postdata['ID'] );
  6018 			$link = get_permalink( $postdata['ID'] );
  5937 
  6019 
  5938 			// Get the author info.
  6020 			// Get the author info.
  5939 			$author = get_userdata( $postdata['post_author'] );
  6021 			$author = get_userdata( $postdata['post_author'] );
  5940 
  6022 
  5941 			$allow_comments = ( 'open' == $postdata['comment_status'] ) ? 1 : 0;
  6023 			$allow_comments = ( 'open' === $postdata['comment_status'] ) ? 1 : 0;
  5942 			$allow_pings    = ( 'open' == $postdata['ping_status'] ) ? 1 : 0;
  6024 			$allow_pings    = ( 'open' === $postdata['ping_status'] ) ? 1 : 0;
  5943 
  6025 
  5944 			// Consider future posts as published
  6026 			// Consider future posts as published.
  5945 			if ( $postdata['post_status'] === 'future' ) {
  6027 			if ( 'future' === $postdata['post_status'] ) {
  5946 				$postdata['post_status'] = 'publish';
  6028 				$postdata['post_status'] = 'publish';
  5947 			}
  6029 			}
  5948 
  6030 
  5949 			// Get post format
  6031 			// Get post format.
  5950 			$post_format = get_post_format( $post_ID );
  6032 			$post_format = get_post_format( $post_ID );
  5951 			if ( empty( $post_format ) ) {
  6033 			if ( empty( $post_format ) ) {
  5952 				$post_format = 'standard';
  6034 				$post_format = 'standard';
  5953 			}
  6035 			}
  5954 
  6036 
  5957 				$sticky = true;
  6039 				$sticky = true;
  5958 			}
  6040 			}
  5959 
  6041 
  5960 			$enclosure = array();
  6042 			$enclosure = array();
  5961 			foreach ( (array) get_post_custom( $post_ID ) as $key => $val ) {
  6043 			foreach ( (array) get_post_custom( $post_ID ) as $key => $val ) {
  5962 				if ( $key == 'enclosure' ) {
  6044 				if ( 'enclosure' === $key ) {
  5963 					foreach ( (array) $val as $enc ) {
  6045 					foreach ( (array) $val as $enc ) {
  5964 						$encdata             = explode( "\n", $enc );
  6046 						$encdata             = explode( "\n", $enc );
  5965 						$enclosure['url']    = trim( htmlspecialchars( $encdata[0] ) );
  6047 						$enclosure['url']    = trim( htmlspecialchars( $encdata[0] ) );
  5966 						$enclosure['length'] = (int) trim( $encdata[1] );
  6048 						$enclosure['length'] = (int) trim( $encdata[1] );
  5967 						$enclosure['type']   = trim( $encdata[2] );
  6049 						$enclosure['type']   = trim( $encdata[2] );
  5976 				'postid'                 => $postdata['ID'],
  6058 				'postid'                 => $postdata['ID'],
  5977 				'description'            => $post['main'],
  6059 				'description'            => $post['main'],
  5978 				'title'                  => $postdata['post_title'],
  6060 				'title'                  => $postdata['post_title'],
  5979 				'link'                   => $link,
  6061 				'link'                   => $link,
  5980 				'permaLink'              => $link,
  6062 				'permaLink'              => $link,
  5981 				// commented out because no other tool seems to use this
  6063 				// Commented out because no other tool seems to use this.
  5982 				//	      'content' => $entry['post_content'],
  6064 				// 'content' => $entry['post_content'],
  5983 				'categories'             => $categories,
  6065 				'categories'             => $categories,
  5984 				'mt_excerpt'             => $postdata['post_excerpt'],
  6066 				'mt_excerpt'             => $postdata['post_excerpt'],
  5985 				'mt_text_more'           => $post['extended'],
  6067 				'mt_text_more'           => $post['extended'],
  5986 				'wp_more_text'           => $post['more_text'],
  6068 				'wp_more_text'           => $post['more_text'],
  5987 				'mt_allow_comments'      => $allow_comments,
  6069 				'mt_allow_comments'      => $allow_comments,
  6015 	/**
  6097 	/**
  6016 	 * Retrieve list of recent posts.
  6098 	 * Retrieve list of recent posts.
  6017 	 *
  6099 	 *
  6018 	 * @since 1.5.0
  6100 	 * @since 1.5.0
  6019 	 *
  6101 	 *
  6020 	 * @param array  $args {
  6102 	 * @param array $args {
  6021 	 *     Method arguments. Note: arguments must be ordered as documented.
  6103 	 *     Method arguments. Note: arguments must be ordered as documented.
  6022 	 *
  6104 	 *
  6023 	 *     @type int    $blog_id (unused)
  6105 	 *     @type int    $blog_id (unused)
  6024 	 *     @type string $username
  6106 	 *     @type string $username
  6025 	 *     @type string $password
  6107 	 *     @type string $password
  6036 			$query = array( 'numberposts' => absint( $args[3] ) );
  6118 			$query = array( 'numberposts' => absint( $args[3] ) );
  6037 		} else {
  6119 		} else {
  6038 			$query = array();
  6120 			$query = array();
  6039 		}
  6121 		}
  6040 
  6122 
  6041 		if ( ! $user = $this->login( $username, $password ) ) {
  6123 		$user = $this->login( $username, $password );
       
  6124 		if ( ! $user ) {
  6042 			return $this->error;
  6125 			return $this->error;
  6043 		}
  6126 		}
  6044 
  6127 
  6045 		if ( ! current_user_can( 'edit_posts' ) ) {
  6128 		if ( ! current_user_can( 'edit_posts' ) ) {
  6046 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit posts.' ) );
  6129 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit posts.' ) );
  6087 			$link = get_permalink( $entry['ID'] );
  6170 			$link = get_permalink( $entry['ID'] );
  6088 
  6171 
  6089 			// Get the post author info.
  6172 			// Get the post author info.
  6090 			$author = get_userdata( $entry['post_author'] );
  6173 			$author = get_userdata( $entry['post_author'] );
  6091 
  6174 
  6092 			$allow_comments = ( 'open' == $entry['comment_status'] ) ? 1 : 0;
  6175 			$allow_comments = ( 'open' === $entry['comment_status'] ) ? 1 : 0;
  6093 			$allow_pings    = ( 'open' == $entry['ping_status'] ) ? 1 : 0;
  6176 			$allow_pings    = ( 'open' === $entry['ping_status'] ) ? 1 : 0;
  6094 
  6177 
  6095 			// Consider future posts as published
  6178 			// Consider future posts as published.
  6096 			if ( $entry['post_status'] === 'future' ) {
  6179 			if ( 'future' === $entry['post_status'] ) {
  6097 				$entry['post_status'] = 'publish';
  6180 				$entry['post_status'] = 'publish';
  6098 			}
  6181 			}
  6099 
  6182 
  6100 			// Get post format
  6183 			// Get post format.
  6101 			$post_format = get_post_format( $entry['ID'] );
  6184 			$post_format = get_post_format( $entry['ID'] );
  6102 			if ( empty( $post_format ) ) {
  6185 			if ( empty( $post_format ) ) {
  6103 				$post_format = 'standard';
  6186 				$post_format = 'standard';
  6104 			}
  6187 			}
  6105 
  6188 
  6109 				'postid'                 => (string) $entry['ID'],
  6192 				'postid'                 => (string) $entry['ID'],
  6110 				'description'            => $post['main'],
  6193 				'description'            => $post['main'],
  6111 				'title'                  => $entry['post_title'],
  6194 				'title'                  => $entry['post_title'],
  6112 				'link'                   => $link,
  6195 				'link'                   => $link,
  6113 				'permaLink'              => $link,
  6196 				'permaLink'              => $link,
  6114 				// commented out because no other tool seems to use this
  6197 				// Commented out because no other tool seems to use this.
  6115 				// 'content' => $entry['post_content'],
  6198 				// 'content' => $entry['post_content'],
  6116 				'categories'             => $categories,
  6199 				'categories'             => $categories,
  6117 				'mt_excerpt'             => $entry['post_excerpt'],
  6200 				'mt_excerpt'             => $entry['post_excerpt'],
  6118 				'mt_text_more'           => $post['extended'],
  6201 				'mt_text_more'           => $post['extended'],
  6119 				'wp_more_text'           => $post['more_text'],
  6202 				'wp_more_text'           => $post['more_text'],
  6128 				'post_status'            => $entry['post_status'],
  6211 				'post_status'            => $entry['post_status'],
  6129 				'custom_fields'          => $this->get_custom_fields( $entry['ID'] ),
  6212 				'custom_fields'          => $this->get_custom_fields( $entry['ID'] ),
  6130 				'wp_post_format'         => $post_format,
  6213 				'wp_post_format'         => $post_format,
  6131 				'date_modified'          => $post_modified,
  6214 				'date_modified'          => $post_modified,
  6132 				'date_modified_gmt'      => $post_modified_gmt,
  6215 				'date_modified_gmt'      => $post_modified_gmt,
  6133 				'sticky'                 => ( $entry['post_type'] === 'post' && is_sticky( $entry['ID'] ) ),
  6216 				'sticky'                 => ( 'post' === $entry['post_type'] && is_sticky( $entry['ID'] ) ),
  6134 				'wp_post_thumbnail'      => get_post_thumbnail_id( $entry['ID'] ),
  6217 				'wp_post_thumbnail'      => get_post_thumbnail_id( $entry['ID'] ),
  6135 			);
  6218 			);
  6136 		}
  6219 		}
  6137 
  6220 
  6138 		return $recent_posts;
  6221 		return $recent_posts;
  6141 	/**
  6224 	/**
  6142 	 * Retrieve the list of categories on a given blog.
  6225 	 * Retrieve the list of categories on a given blog.
  6143 	 *
  6226 	 *
  6144 	 * @since 1.5.0
  6227 	 * @since 1.5.0
  6145 	 *
  6228 	 *
  6146 	 * @param array  $args {
  6229 	 * @param array $args {
  6147 	 *     Method arguments. Note: arguments must be ordered as documented.
  6230 	 *     Method arguments. Note: arguments must be ordered as documented.
  6148 	 *
  6231 	 *
  6149 	 *     @type int    $blog_id (unused)
  6232 	 *     @type int    $blog_id (unused)
  6150 	 *     @type string $username
  6233 	 *     @type string $username
  6151 	 *     @type string $password
  6234 	 *     @type string $password
  6156 		$this->escape( $args );
  6239 		$this->escape( $args );
  6157 
  6240 
  6158 		$username = $args[1];
  6241 		$username = $args[1];
  6159 		$password = $args[2];
  6242 		$password = $args[2];
  6160 
  6243 
  6161 		if ( ! $user = $this->login( $username, $password ) ) {
  6244 		$user = $this->login( $username, $password );
       
  6245 		if ( ! $user ) {
  6162 			return $this->error;
  6246 			return $this->error;
  6163 		}
  6247 		}
  6164 
  6248 
  6165 		if ( ! current_user_can( 'edit_posts' ) ) {
  6249 		if ( ! current_user_can( 'edit_posts' ) ) {
  6166 			return new IXR_Error( 401, __( 'Sorry, you must be able to edit posts on this site in order to view categories.' ) );
  6250 			return new IXR_Error( 401, __( 'Sorry, you must be able to edit posts on this site in order to view categories.' ) );
  6169 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  6253 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  6170 		do_action( 'xmlrpc_call', 'metaWeblog.getCategories' );
  6254 		do_action( 'xmlrpc_call', 'metaWeblog.getCategories' );
  6171 
  6255 
  6172 		$categories_struct = array();
  6256 		$categories_struct = array();
  6173 
  6257 
  6174 		if ( $cats = get_categories( array( 'get' => 'all' ) ) ) {
  6258 		$cats = get_categories( array( 'get' => 'all' ) );
       
  6259 		if ( $cats ) {
  6175 			foreach ( $cats as $cat ) {
  6260 			foreach ( $cats as $cat ) {
  6176 				$struct                        = array();
  6261 				$struct                        = array();
  6177 				$struct['categoryId']          = $cat->term_id;
  6262 				$struct['categoryId']          = $cat->term_id;
  6178 				$struct['parentId']            = $cat->parent;
  6263 				$struct['parentId']            = $cat->parent;
  6179 				$struct['description']         = $cat->name;
  6264 				$struct['description']         = $cat->name;
  6198 	 *
  6283 	 *
  6199 	 * @since 1.5.0
  6284 	 * @since 1.5.0
  6200 	 *
  6285 	 *
  6201 	 * @global wpdb $wpdb WordPress database abstraction object.
  6286 	 * @global wpdb $wpdb WordPress database abstraction object.
  6202 	 *
  6287 	 *
  6203 	 * @param array  $args {
  6288 	 * @param array $args {
  6204 	 *     Method arguments. Note: arguments must be ordered as documented.
  6289 	 *     Method arguments. Note: arguments must be ordered as documented.
  6205 	 *
  6290 	 *
  6206 	 *     @type int    $blog_id (unused)
  6291 	 *     @type int    $blog_id (unused)
  6207 	 *     @type string $username
  6292 	 *     @type string $username
  6208 	 *     @type string $password
  6293 	 *     @type string $password
  6219 
  6304 
  6220 		$name = sanitize_file_name( $data['name'] );
  6305 		$name = sanitize_file_name( $data['name'] );
  6221 		$type = $data['type'];
  6306 		$type = $data['type'];
  6222 		$bits = $data['bits'];
  6307 		$bits = $data['bits'];
  6223 
  6308 
  6224 		if ( ! $user = $this->login( $username, $password ) ) {
  6309 		$user = $this->login( $username, $password );
       
  6310 		if ( ! $user ) {
  6225 			return $this->error;
  6311 			return $this->error;
  6226 		}
  6312 		}
  6227 
  6313 
  6228 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  6314 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  6229 		do_action( 'xmlrpc_call', 'metaWeblog.newMediaObject' );
  6315 		do_action( 'xmlrpc_call', 'metaWeblog.newMediaObject' );
  6235 
  6321 
  6236 		if ( is_multisite() && upload_is_user_over_quota( false ) ) {
  6322 		if ( is_multisite() && upload_is_user_over_quota( false ) ) {
  6237 			$this->error = new IXR_Error(
  6323 			$this->error = new IXR_Error(
  6238 				401,
  6324 				401,
  6239 				sprintf(
  6325 				sprintf(
  6240 					/* translators: %s: allowed space allocation */
  6326 					/* translators: %s: Allowed space allocation. */
  6241 					__( 'Sorry, you have used your space allocation of %s. Please delete some files to upload more files.' ),
  6327 					__( '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 )
  6328 					size_format( get_space_allowed() * MB_IN_BYTES )
  6243 				)
  6329 				)
  6244 			);
  6330 			);
  6245 			return $this->error;
  6331 			return $this->error;
  6253 		 *
  6339 		 *
  6254 		 * @since 2.1.0
  6340 		 * @since 2.1.0
  6255 		 *
  6341 		 *
  6256 		 * @param bool $error Whether to pre-empt the media upload. Default false.
  6342 		 * @param bool $error Whether to pre-empt the media upload. Default false.
  6257 		 */
  6343 		 */
  6258 		if ( $upload_err = apply_filters( 'pre_upload_error', false ) ) {
  6344 		$upload_err = apply_filters( 'pre_upload_error', false );
       
  6345 		if ( $upload_err ) {
  6259 			return new IXR_Error( 500, $upload_err );
  6346 			return new IXR_Error( 500, $upload_err );
  6260 		}
  6347 		}
  6261 
  6348 
  6262 		$upload = wp_upload_bits( $name, null, $bits );
  6349 		$upload = wp_upload_bits( $name, null, $bits );
  6263 		if ( ! empty( $upload['error'] ) ) {
  6350 		if ( ! empty( $upload['error'] ) ) {
  6264 			/* translators: 1: file name, 2: error message */
  6351 			/* translators: 1: File name, 2: Error message. */
  6265 			$errorString = sprintf( __( 'Could not write file %1$s (%2$s).' ), $name, $upload['error'] );
  6352 			$errorString = sprintf( __( 'Could not write file %1$s (%2$s).' ), $name, $upload['error'] );
  6266 			return new IXR_Error( 500, $errorString );
  6353 			return new IXR_Error( 500, $errorString );
  6267 		}
  6354 		}
  6268 		// Construct the attachment array
  6355 		// Construct the attachment array.
  6269 		$post_id = 0;
  6356 		$post_id = 0;
  6270 		if ( ! empty( $data['post_id'] ) ) {
  6357 		if ( ! empty( $data['post_id'] ) ) {
  6271 			$post_id = (int) $data['post_id'];
  6358 			$post_id = (int) $data['post_id'];
  6272 
  6359 
  6273 			if ( ! current_user_can( 'edit_post', $post_id ) ) {
  6360 			if ( ! current_user_can( 'edit_post', $post_id ) ) {
  6281 			'post_parent'    => $post_id,
  6368 			'post_parent'    => $post_id,
  6282 			'post_mime_type' => $type,
  6369 			'post_mime_type' => $type,
  6283 			'guid'           => $upload['url'],
  6370 			'guid'           => $upload['url'],
  6284 		);
  6371 		);
  6285 
  6372 
  6286 		// Save the data
  6373 		// Save the data.
  6287 		$id = wp_insert_attachment( $attachment, $upload['file'], $post_id );
  6374 		$id = wp_insert_attachment( $attachment, $upload['file'], $post_id );
  6288 		wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $upload['file'] ) );
  6375 		wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $upload['file'] ) );
  6289 
  6376 
  6290 		/**
  6377 		/**
  6291 		 * Fires after a new attachment has been added via the XML-RPC MovableType API.
  6378 		 * Fires after a new attachment has been added via the XML-RPC MovableType API.
  6293 		 * @since 3.4.0
  6380 		 * @since 3.4.0
  6294 		 *
  6381 		 *
  6295 		 * @param int   $id   ID of the new attachment.
  6382 		 * @param int   $id   ID of the new attachment.
  6296 		 * @param array $args An array of arguments to add the attachment.
  6383 		 * @param array $args An array of arguments to add the attachment.
  6297 		 */
  6384 		 */
  6298 		do_action( 'xmlrpc_call_success_mw_newMediaObject', $id, $args );
  6385 		do_action( 'xmlrpc_call_success_mw_newMediaObject', $id, $args ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.NotLowercase
  6299 
  6386 
  6300 		$struct = $this->_prepare_media_item( get_post( $id ) );
  6387 		$struct = $this->_prepare_media_item( get_post( $id ) );
  6301 
  6388 
  6302 		// Deprecated values
  6389 		// Deprecated values.
  6303 		$struct['id']   = $struct['attachment_id'];
  6390 		$struct['id']   = $struct['attachment_id'];
  6304 		$struct['file'] = $struct['title'];
  6391 		$struct['file'] = $struct['title'];
  6305 		$struct['url']  = $struct['link'];
  6392 		$struct['url']  = $struct['link'];
  6306 
  6393 
  6307 		return $struct;
  6394 		return $struct;
  6308 	}
  6395 	}
  6309 
  6396 
  6310 	/* MovableType API functions
  6397 	/*
  6311 	 * specs on http://www.movabletype.org/docs/mtmanual_programmatic.html
  6398 	 * MovableType API functions.
       
  6399 	 * Specs on http://www.movabletype.org/docs/mtmanual_programmatic.html
  6312 	 */
  6400 	 */
  6313 
  6401 
  6314 	/**
  6402 	/**
  6315 	 * Retrieve the post titles of recent posts.
  6403 	 * Retrieve the post titles of recent posts.
  6316 	 *
  6404 	 *
  6317 	 * @since 1.5.0
  6405 	 * @since 1.5.0
  6318 	 *
  6406 	 *
  6319 	 * @param array  $args {
  6407 	 * @param array $args {
  6320 	 *     Method arguments. Note: arguments must be ordered as documented.
  6408 	 *     Method arguments. Note: arguments must be ordered as documented.
  6321 	 *
  6409 	 *
  6322 	 *     @type int    $blog_id (unused)
  6410 	 *     @type int    $blog_id (unused)
  6323 	 *     @type string $username
  6411 	 *     @type string $username
  6324 	 *     @type string $password
  6412 	 *     @type string $password
  6335 			$query = array( 'numberposts' => absint( $args[3] ) );
  6423 			$query = array( 'numberposts' => absint( $args[3] ) );
  6336 		} else {
  6424 		} else {
  6337 			$query = array();
  6425 			$query = array();
  6338 		}
  6426 		}
  6339 
  6427 
  6340 		if ( ! $user = $this->login( $username, $password ) ) {
  6428 		$user = $this->login( $username, $password );
       
  6429 		if ( ! $user ) {
  6341 			return $this->error;
  6430 			return $this->error;
  6342 		}
  6431 		}
  6343 
  6432 
  6344 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  6433 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  6345 		do_action( 'xmlrpc_call', 'mt.getRecentPostTitles' );
  6434 		do_action( 'xmlrpc_call', 'mt.getRecentPostTitles' );
  6377 	/**
  6466 	/**
  6378 	 * Retrieve list of all categories on blog.
  6467 	 * Retrieve list of all categories on blog.
  6379 	 *
  6468 	 *
  6380 	 * @since 1.5.0
  6469 	 * @since 1.5.0
  6381 	 *
  6470 	 *
  6382 	 * @param array  $args {
  6471 	 * @param array $args {
  6383 	 *     Method arguments. Note: arguments must be ordered as documented.
  6472 	 *     Method arguments. Note: arguments must be ordered as documented.
  6384 	 *
  6473 	 *
  6385 	 *     @type int    $blog_id (unused)
  6474 	 *     @type int    $blog_id (unused)
  6386 	 *     @type string $username
  6475 	 *     @type string $username
  6387 	 *     @type string $password
  6476 	 *     @type string $password
  6392 		$this->escape( $args );
  6481 		$this->escape( $args );
  6393 
  6482 
  6394 		$username = $args[1];
  6483 		$username = $args[1];
  6395 		$password = $args[2];
  6484 		$password = $args[2];
  6396 
  6485 
  6397 		if ( ! $user = $this->login( $username, $password ) ) {
  6486 		$user = $this->login( $username, $password );
       
  6487 		if ( ! $user ) {
  6398 			return $this->error;
  6488 			return $this->error;
  6399 		}
  6489 		}
  6400 
  6490 
  6401 		if ( ! current_user_can( 'edit_posts' ) ) {
  6491 		if ( ! current_user_can( 'edit_posts' ) ) {
  6402 			return new IXR_Error( 401, __( 'Sorry, you must be able to edit posts on this site in order to view categories.' ) );
  6492 			return new IXR_Error( 401, __( 'Sorry, you must be able to edit posts on this site in order to view categories.' ) );
  6405 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  6495 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  6406 		do_action( 'xmlrpc_call', 'mt.getCategoryList' );
  6496 		do_action( 'xmlrpc_call', 'mt.getCategoryList' );
  6407 
  6497 
  6408 		$categories_struct = array();
  6498 		$categories_struct = array();
  6409 
  6499 
  6410 		if ( $cats = get_categories(
  6500 		$cats = get_categories(
  6411 			array(
  6501 			array(
  6412 				'hide_empty'   => 0,
  6502 				'hide_empty'   => 0,
  6413 				'hierarchical' => 0,
  6503 				'hierarchical' => 0,
  6414 			)
  6504 			)
  6415 		) ) {
  6505 		);
       
  6506 		if ( $cats ) {
  6416 			foreach ( $cats as $cat ) {
  6507 			foreach ( $cats as $cat ) {
  6417 				$struct                 = array();
  6508 				$struct                 = array();
  6418 				$struct['categoryId']   = $cat->term_id;
  6509 				$struct['categoryId']   = $cat->term_id;
  6419 				$struct['categoryName'] = $cat->name;
  6510 				$struct['categoryName'] = $cat->name;
  6420 
  6511 
  6428 	/**
  6519 	/**
  6429 	 * Retrieve post categories.
  6520 	 * Retrieve post categories.
  6430 	 *
  6521 	 *
  6431 	 * @since 1.5.0
  6522 	 * @since 1.5.0
  6432 	 *
  6523 	 *
  6433 	 * @param array  $args {
  6524 	 * @param array $args {
  6434 	 *     Method arguments. Note: arguments must be ordered as documented.
  6525 	 *     Method arguments. Note: arguments must be ordered as documented.
  6435 	 *
  6526 	 *
  6436 	 *     @type int    $post_ID
  6527 	 *     @type int    $post_ID
  6437 	 *     @type string $username
  6528 	 *     @type string $username
  6438 	 *     @type string $password
  6529 	 *     @type string $password
  6444 
  6535 
  6445 		$post_ID  = (int) $args[0];
  6536 		$post_ID  = (int) $args[0];
  6446 		$username = $args[1];
  6537 		$username = $args[1];
  6447 		$password = $args[2];
  6538 		$password = $args[2];
  6448 
  6539 
  6449 		if ( ! $user = $this->login( $username, $password ) ) {
  6540 		$user = $this->login( $username, $password );
       
  6541 		if ( ! $user ) {
  6450 			return $this->error;
  6542 			return $this->error;
  6451 		}
  6543 		}
  6452 
  6544 
  6453 		if ( ! get_post( $post_ID ) ) {
  6545 		if ( ! get_post( $post_ID ) ) {
  6454 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  6546 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
  6461 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  6553 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  6462 		do_action( 'xmlrpc_call', 'mt.getPostCategories' );
  6554 		do_action( 'xmlrpc_call', 'mt.getPostCategories' );
  6463 
  6555 
  6464 		$categories = array();
  6556 		$categories = array();
  6465 		$catids     = wp_get_post_categories( intval( $post_ID ) );
  6557 		$catids     = wp_get_post_categories( intval( $post_ID ) );
  6466 		// first listed category will be the primary category
  6558 		// First listed category will be the primary category.
  6467 		$isPrimary = true;
  6559 		$isPrimary = true;
  6468 		foreach ( $catids as $catid ) {
  6560 		foreach ( $catids as $catid ) {
  6469 			$categories[] = array(
  6561 			$categories[] = array(
  6470 				'categoryName' => get_cat_name( $catid ),
  6562 				'categoryName' => get_cat_name( $catid ),
  6471 				'categoryId'   => (string) $catid,
  6563 				'categoryId'   => (string) $catid,
  6480 	/**
  6572 	/**
  6481 	 * Sets categories for a post.
  6573 	 * Sets categories for a post.
  6482 	 *
  6574 	 *
  6483 	 * @since 1.5.0
  6575 	 * @since 1.5.0
  6484 	 *
  6576 	 *
  6485 	 * @param array  $args {
  6577 	 * @param array $args {
  6486 	 *     Method arguments. Note: arguments must be ordered as documented.
  6578 	 *     Method arguments. Note: arguments must be ordered as documented.
  6487 	 *
  6579 	 *
  6488 	 *     @type int    $post_ID
  6580 	 *     @type int    $post_ID
  6489 	 *     @type string $username
  6581 	 *     @type string $username
  6490 	 *     @type string $password
  6582 	 *     @type string $password
  6498 		$post_ID    = (int) $args[0];
  6590 		$post_ID    = (int) $args[0];
  6499 		$username   = $args[1];
  6591 		$username   = $args[1];
  6500 		$password   = $args[2];
  6592 		$password   = $args[2];
  6501 		$categories = $args[3];
  6593 		$categories = $args[3];
  6502 
  6594 
  6503 		if ( ! $user = $this->login( $username, $password ) ) {
  6595 		$user = $this->login( $username, $password );
       
  6596 		if ( ! $user ) {
  6504 			return $this->error;
  6597 			return $this->error;
  6505 		}
  6598 		}
  6506 
  6599 
  6507 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  6600 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  6508 		do_action( 'xmlrpc_call', 'mt.setPostCategories' );
  6601 		do_action( 'xmlrpc_call', 'mt.setPostCategories' );
  6586 			return array();
  6679 			return array();
  6587 		}
  6680 		}
  6588 
  6681 
  6589 		$trackback_pings = array();
  6682 		$trackback_pings = array();
  6590 		foreach ( $comments as $comment ) {
  6683 		foreach ( $comments as $comment ) {
  6591 			if ( 'trackback' == $comment->comment_type ) {
  6684 			if ( 'trackback' === $comment->comment_type ) {
  6592 				$content           = $comment->comment_content;
  6685 				$content           = $comment->comment_content;
  6593 				$title             = substr( $content, 8, ( strpos( $content, '</strong>' ) - 8 ) );
  6686 				$title             = substr( $content, 8, ( strpos( $content, '</strong>' ) - 8 ) );
  6594 				$trackback_pings[] = array(
  6687 				$trackback_pings[] = array(
  6595 					'pingTitle' => $title,
  6688 					'pingTitle' => $title,
  6596 					'pingURL'   => $comment->comment_author_url,
  6689 					'pingURL'   => $comment->comment_author_url,
  6605 	/**
  6698 	/**
  6606 	 * Sets a post's publish status to 'publish'.
  6699 	 * Sets a post's publish status to 'publish'.
  6607 	 *
  6700 	 *
  6608 	 * @since 1.5.0
  6701 	 * @since 1.5.0
  6609 	 *
  6702 	 *
  6610 	 * @param array  $args {
  6703 	 * @param array $args {
  6611 	 *     Method arguments. Note: arguments must be ordered as documented.
  6704 	 *     Method arguments. Note: arguments must be ordered as documented.
  6612 	 *
  6705 	 *
  6613 	 *     @type int    $post_ID
  6706 	 *     @type int    $post_ID
  6614 	 *     @type string $username
  6707 	 *     @type string $username
  6615 	 *     @type string $password
  6708 	 *     @type string $password
  6621 
  6714 
  6622 		$post_ID  = (int) $args[0];
  6715 		$post_ID  = (int) $args[0];
  6623 		$username = $args[1];
  6716 		$username = $args[1];
  6624 		$password = $args[2];
  6717 		$password = $args[2];
  6625 
  6718 
  6626 		if ( ! $user = $this->login( $username, $password ) ) {
  6719 		$user = $this->login( $username, $password );
       
  6720 		if ( ! $user ) {
  6627 			return $this->error;
  6721 			return $this->error;
  6628 		}
  6722 		}
  6629 
  6723 
  6630 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  6724 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  6631 		do_action( 'xmlrpc_call', 'mt.publishPost' );
  6725 		do_action( 'xmlrpc_call', 'mt.publishPost' );
  6639 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to publish this post.' ) );
  6733 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to publish this post.' ) );
  6640 		}
  6734 		}
  6641 
  6735 
  6642 		$postdata['post_status'] = 'publish';
  6736 		$postdata['post_status'] = 'publish';
  6643 
  6737 
  6644 		// retain old cats
  6738 		// Retain old categories.
  6645 		$cats                      = wp_get_post_categories( $post_ID );
  6739 		$postdata['post_category'] = wp_get_post_categories( $post_ID );
  6646 		$postdata['post_category'] = $cats;
       
  6647 		$this->escape( $postdata );
  6740 		$this->escape( $postdata );
  6648 
  6741 
  6649 		return wp_update_post( $postdata );
  6742 		return wp_update_post( $postdata );
  6650 	}
  6743 	}
  6651 
  6744 
  6652 	/* PingBack functions
  6745 	/*
  6653 	 * specs on www.hixie.ch/specs/pingback/pingback
  6746 	 * Pingback functions.
       
  6747 	 * Specs on www.hixie.ch/specs/pingback/pingback
  6654 	 */
  6748 	 */
  6655 
  6749 
  6656 	/**
  6750 	/**
  6657 	 * Retrieves a pingback and registers it.
  6751 	 * Retrieves a pingback and registers it.
  6658 	 *
  6752 	 *
  6659 	 * @since 1.5.0
  6753 	 * @since 1.5.0
  6660 	 *
  6754 	 *
  6661 	 * @param array  $args {
  6755 	 * @param array $args {
  6662 	 *     Method arguments. Note: arguments must be ordered as documented.
  6756 	 *     Method arguments. Note: arguments must be ordered as documented.
  6663 	 *
  6757 	 *
  6664 	 *     @type string $pagelinkedfrom
  6758 	 *     @type string $pagelinkedfrom
  6665 	 *     @type string $pagelinkedto
  6759 	 *     @type string $pagelinkedto
  6666 	 * }
  6760 	 * }
  6690 
  6784 
  6691 		if ( ! $pagelinkedfrom ) {
  6785 		if ( ! $pagelinkedfrom ) {
  6692 			return $this->pingback_error( 0, __( 'A valid URL was not provided.' ) );
  6786 			return $this->pingback_error( 0, __( 'A valid URL was not provided.' ) );
  6693 		}
  6787 		}
  6694 
  6788 
  6695 		// Check if the page linked to is in our site
  6789 		// Check if the page linked to is on our site.
  6696 		$pos1 = strpos( $pagelinkedto, str_replace( array( 'http://www.', 'http://', 'https://www.', 'https://' ), '', get_option( 'home' ) ) );
  6790 		$pos1 = strpos( $pagelinkedto, str_replace( array( 'http://www.', 'http://', 'https://www.', 'https://' ), '', get_option( 'home' ) ) );
  6697 		if ( ! $pos1 ) {
  6791 		if ( ! $pos1 ) {
  6698 			return $this->pingback_error( 0, __( 'Is there no link to us?' ) );
  6792 			return $this->pingback_error( 0, __( 'Is there no link to us?' ) );
  6699 		}
  6793 		}
  6700 
  6794 
  6701 		// let's find which post is linked to
  6795 		/*
  6702 		// FIXME: does url_to_postid() cover all these cases already?
  6796 		 * Let's find which post is linked to.
  6703 		//        if so, then let's use it and drop the old code.
  6797 		 * FIXME: Does url_to_postid() cover all these cases already?
       
  6798 		 * If so, then let's use it and drop the old code.
       
  6799 		 */
  6704 		$urltest = parse_url( $pagelinkedto );
  6800 		$urltest = parse_url( $pagelinkedto );
  6705 		if ( $post_ID = url_to_postid( $pagelinkedto ) ) {
  6801 		$post_ID = url_to_postid( $pagelinkedto );
       
  6802 		if ( $post_ID ) {
  6706 			// $way
  6803 			// $way
  6707 		} elseif ( isset( $urltest['path'] ) && preg_match( '#p/[0-9]{1,}#', $urltest['path'], $match ) ) {
  6804 		} elseif ( isset( $urltest['path'] ) && preg_match( '#p/[0-9]{1,}#', $urltest['path'], $match ) ) {
  6708 			// the path defines the post_ID (archives/p/XXXX)
  6805 			// The path defines the post_ID (archives/p/XXXX).
  6709 			$blah    = explode( '/', $match[0] );
  6806 			$blah    = explode( '/', $match[0] );
  6710 			$post_ID = (int) $blah[1];
  6807 			$post_ID = (int) $blah[1];
  6711 		} elseif ( isset( $urltest['query'] ) && preg_match( '#p=[0-9]{1,}#', $urltest['query'], $match ) ) {
  6808 		} elseif ( isset( $urltest['query'] ) && preg_match( '#p=[0-9]{1,}#', $urltest['query'], $match ) ) {
  6712 			// the querystring defines the post_ID (?p=XXXX)
  6809 			// The query string defines the post_ID (?p=XXXX).
  6713 			$blah    = explode( '=', $match[0] );
  6810 			$blah    = explode( '=', $match[0] );
  6714 			$post_ID = (int) $blah[1];
  6811 			$post_ID = (int) $blah[1];
  6715 		} elseif ( isset( $urltest['fragment'] ) ) {
  6812 		} elseif ( isset( $urltest['fragment'] ) ) {
  6716 			// an #anchor is there, it's either...
  6813 			// An #anchor is there, it's either...
  6717 			if ( intval( $urltest['fragment'] ) ) {
  6814 			if ( intval( $urltest['fragment'] ) ) {
  6718 				// ...an integer #XXXX (simplest case)
  6815 				// ...an integer #XXXX (simplest case),
  6719 				$post_ID = (int) $urltest['fragment'];
  6816 				$post_ID = (int) $urltest['fragment'];
  6720 			} elseif ( preg_match( '/post-[0-9]+/', $urltest['fragment'] ) ) {
  6817 			} elseif ( preg_match( '/post-[0-9]+/', $urltest['fragment'] ) ) {
  6721 				// ...a post id in the form 'post-###'
  6818 				// ...a post ID in the form 'post-###',
  6722 				$post_ID = preg_replace( '/[^0-9]+/', '', $urltest['fragment'] );
  6819 				$post_ID = preg_replace( '/[^0-9]+/', '', $urltest['fragment'] );
  6723 			} elseif ( is_string( $urltest['fragment'] ) ) {
  6820 			} elseif ( is_string( $urltest['fragment'] ) ) {
  6724 				// ...or a string #title, a little more complicated
  6821 				// ...or a string #title, a little more complicated.
  6725 				$title = preg_replace( '/[^a-z0-9]/i', '.', $urltest['fragment'] );
  6822 				$title   = preg_replace( '/[^a-z0-9]/i', '.', $urltest['fragment'] );
  6726 				$sql   = $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_title RLIKE %s", $title );
  6823 				$sql     = $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_title RLIKE %s", $title );
  6727 				if ( ! ( $post_ID = $wpdb->get_var( $sql ) ) ) {
  6824 				$post_ID = $wpdb->get_var( $sql );
  6728 					// returning unknown error '0' is better than die()ing
  6825 				if ( ! $post_ID ) {
       
  6826 					// Returning unknown error '0' is better than die()'ing.
  6729 					return $this->pingback_error( 0, '' );
  6827 					return $this->pingback_error( 0, '' );
  6730 				}
  6828 				}
  6731 			}
  6829 			}
  6732 		} else {
  6830 		} else {
  6733 			// TODO: Attempt to extract a post ID from the given URL
  6831 			// TODO: Attempt to extract a post ID from the given URL.
  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.' ) );
  6832 			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.' ) );
  6735 		}
  6833 		}
  6736 		$post_ID = (int) $post_ID;
  6834 		$post_ID = (int) $post_ID;
  6737 
  6835 
  6738 		$post = get_post( $post_ID );
  6836 		$post = get_post( $post_ID );
  6739 
  6837 
  6740 		if ( ! $post ) { // Post_ID not found
  6838 		if ( ! $post ) { // Post not found.
  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.' ) );
  6839 			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.' ) );
  6742 		}
  6840 		}
  6743 
  6841 
  6744 		if ( $post_ID == url_to_postid( $pagelinkedfrom ) ) {
  6842 		if ( url_to_postid( $pagelinkedfrom ) == $post_ID ) {
  6745 			return $this->pingback_error( 0, __( 'The source URL and the target URL cannot both point to the same resource.' ) );
  6843 			return $this->pingback_error( 0, __( 'The source URL and the target URL cannot both point to the same resource.' ) );
  6746 		}
  6844 		}
  6747 
  6845 
  6748 		// Check if pings are on
  6846 		// Check if pings are on.
  6749 		if ( ! pings_open( $post ) ) {
  6847 		if ( ! pings_open( $post ) ) {
  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.' ) );
  6848 			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 		}
  6849 		}
  6752 
  6850 
  6753 		// Let's check that the remote site didn't already pingback this entry
  6851 		// Let's check that the remote site didn't already pingback this entry.
  6754 		if ( $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_author_url = %s", $post_ID, $pagelinkedfrom ) ) ) {
  6852 		if ( $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_author_url = %s", $post_ID, $pagelinkedfrom ) ) ) {
  6755 			return $this->pingback_error( 48, __( 'The pingback has already been registered.' ) );
  6853 			return $this->pingback_error( 48, __( 'The pingback has already been registered.' ) );
  6756 		}
  6854 		}
  6757 
  6855 
  6758 		// very stupid, but gives time to the 'from' server to publish !
  6856 		// Very stupid, but gives time to the 'from' server to publish!
  6759 		sleep( 1 );
  6857 		sleep( 1 );
  6760 
  6858 
  6761 		$remote_ip = preg_replace( '/[^0-9a-fA-F:., ]/', '', $_SERVER['REMOTE_ADDR'] );
  6859 		$remote_ip = preg_replace( '/[^0-9a-fA-F:., ]/', '', $_SERVER['REMOTE_ADDR'] );
  6762 
  6860 
  6763 		/** This filter is documented in wp-includes/class-http.php */
  6861 		/** This filter is documented in wp-includes/class-http.php */
  6764 		$user_agent = apply_filters( 'http_headers_useragent', 'WordPress/' . get_bloginfo( 'version' ) . '; ' . get_bloginfo( 'url' ), $url );
  6862 		$user_agent = apply_filters( 'http_headers_useragent', 'WordPress/' . get_bloginfo( 'version' ) . '; ' . get_bloginfo( 'url' ), $pagelinkedfrom );
  6765 
  6863 
  6766 		// Let's check the remote site
  6864 		// Let's check the remote site.
  6767 		$http_api_args = array(
  6865 		$http_api_args = array(
  6768 			'timeout'             => 10,
  6866 			'timeout'             => 10,
  6769 			'redirection'         => 0,
  6867 			'redirection'         => 0,
  6770 			'limit_response_size' => 153600, // 150 KB
  6868 			'limit_response_size' => 153600, // 150 KB
  6771 			'user-agent'          => "$user_agent; verifying pingback from $remote_ip",
  6869 			'user-agent'          => "$user_agent; verifying pingback from $remote_ip",
  6772 			'headers'             => array(
  6870 			'headers'             => array(
  6773 				'X-Pingback-Forwarded-For' => $remote_ip,
  6871 				'X-Pingback-Forwarded-For' => $remote_ip,
  6774 			),
  6872 			),
  6775 		);
  6873 		);
  6776 
  6874 
  6777 		$request       = wp_safe_remote_get( $pagelinkedfrom, $http_api_args );
  6875 		$request                = wp_safe_remote_get( $pagelinkedfrom, $http_api_args );
  6778 		$remote_source = $remote_source_original = wp_remote_retrieve_body( $request );
  6876 		$remote_source          = wp_remote_retrieve_body( $request );
       
  6877 		$remote_source_original = $remote_source;
  6779 
  6878 
  6780 		if ( ! $remote_source ) {
  6879 		if ( ! $remote_source ) {
  6781 			return $this->pingback_error( 16, __( 'The source URL does not exist.' ) );
  6880 			return $this->pingback_error( 16, __( 'The source URL does not exist.' ) );
  6782 		}
  6881 		}
  6783 
  6882 
  6800 		$title = isset( $matchtitle[1] ) ? $matchtitle[1] : '';
  6899 		$title = isset( $matchtitle[1] ) ? $matchtitle[1] : '';
  6801 		if ( empty( $title ) ) {
  6900 		if ( empty( $title ) ) {
  6802 			return $this->pingback_error( 32, __( 'We cannot find a title on that page.' ) );
  6901 			return $this->pingback_error( 32, __( 'We cannot find a title on that page.' ) );
  6803 		}
  6902 		}
  6804 
  6903 
  6805 		$remote_source = strip_tags( $remote_source, '<a>' ); // just keep the tag we need
  6904 		// Remove all script and style tags including their content.
       
  6905 		$remote_source = preg_replace( '@<(script|style)[^>]*?>.*?</\\1>@si', '', $remote_source );
       
  6906 		// Just keep the tag we need.
       
  6907 		$remote_source = strip_tags( $remote_source, '<a>' );
  6806 
  6908 
  6807 		$p = explode( "\n\n", $remote_source );
  6909 		$p = explode( "\n\n", $remote_source );
  6808 
  6910 
  6809 		$preg_target = preg_quote( $pagelinkedto, '|' );
  6911 		$preg_target = preg_quote( $pagelinkedto, '|' );
  6810 
  6912 
  6811 		foreach ( $p as $para ) {
  6913 		foreach ( $p as $para ) {
  6812 			if ( strpos( $para, $pagelinkedto ) !== false ) { // it exists, but is it a link?
  6914 			if ( strpos( $para, $pagelinkedto ) !== false ) { // It exists, but is it a link?
  6813 				preg_match( '|<a[^>]+?' . $preg_target . '[^>]*>([^>]+?)</a>|', $para, $context );
  6915 				preg_match( '|<a[^>]+?' . $preg_target . '[^>]*>([^>]+?)</a>|', $para, $context );
  6814 
  6916 
  6815 				// If the URL isn't in a link context, keep looking
  6917 				// If the URL isn't in a link context, keep looking.
  6816 				if ( empty( $context ) ) {
  6918 				if ( empty( $context ) ) {
  6817 					continue;
  6919 					continue;
  6818 				}
  6920 				}
  6819 
  6921 
  6820 				// We're going to use this fake tag to mark the context in a bit
  6922 				// We're going to use this fake tag to mark the context in a bit.
  6821 				// the marker is needed in case the link text appears more than once in the paragraph
  6923 				// The marker is needed in case the link text appears more than once in the paragraph.
  6822 				$excerpt = preg_replace( '|\</?wpcontext\>|', '', $para );
  6924 				$excerpt = preg_replace( '|\</?wpcontext\>|', '', $para );
  6823 
  6925 
  6824 				// prevent really long link text
  6926 				// prevent really long link text
  6825 				if ( strlen( $context[1] ) > 100 ) {
  6927 				if ( strlen( $context[1] ) > 100 ) {
  6826 					$context[1] = substr( $context[1], 0, 100 ) . '&#8230;';
  6928 					$context[1] = substr( $context[1], 0, 100 ) . '&#8230;';
  6827 				}
  6929 				}
  6828 
  6930 
  6829 				$marker      = '<wpcontext>' . $context[1] . '</wpcontext>';    // set up our marker
  6931 				$marker      = '<wpcontext>' . $context[1] . '</wpcontext>';  // Set up our marker.
  6830 				$excerpt     = str_replace( $context[0], $marker, $excerpt ); // swap out the link for our marker
  6932 				$excerpt     = str_replace( $context[0], $marker, $excerpt ); // Swap out the link for our marker.
  6831 				$excerpt     = strip_tags( $excerpt, '<wpcontext>' );        // strip all tags but our context marker
  6933 				$excerpt     = strip_tags( $excerpt, '<wpcontext>' );         // Strip all tags but our context marker.
  6832 				$excerpt     = trim( $excerpt );
  6934 				$excerpt     = trim( $excerpt );
  6833 				$preg_marker = preg_quote( $marker, '|' );
  6935 				$preg_marker = preg_quote( $marker, '|' );
  6834 				$excerpt     = preg_replace( "|.*?\s(.{0,100}$preg_marker.{0,100})\s.*|s", '$1', $excerpt );
  6936 				$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
  6937 				$excerpt     = strip_tags( $excerpt ); // YES, again, to remove the marker wrapper.
  6836 				break;
  6938 				break;
  6837 			}
  6939 			}
  6838 		}
  6940 		}
  6839 
  6941 
  6840 		if ( empty( $context ) ) { // Link to target not found
  6942 		if ( empty( $context ) ) { // Link to target not found.
  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.' ) );
  6943 			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.' ) );
  6842 		}
  6944 		}
  6843 
  6945 
  6844 		$pagelinkedfrom = str_replace( '&', '&amp;', $pagelinkedfrom );
  6946 		$pagelinkedfrom = str_replace( '&', '&amp;', $pagelinkedfrom );
  6845 
  6947 
  6879 		 *
  6981 		 *
  6880 		 * @param int $comment_ID Comment ID.
  6982 		 * @param int $comment_ID Comment ID.
  6881 		 */
  6983 		 */
  6882 		do_action( 'pingback_post', $comment_ID );
  6984 		do_action( 'pingback_post', $comment_ID );
  6883 
  6985 
  6884 		/* translators: 1: URL of the page linked from, 2: URL of the page linked to */
  6986 		/* translators: 1: URL of the page linked from, 2: URL of the page linked to. */
  6885 		return sprintf( __( 'Pingback from %1$s to %2$s registered. Keep the web talking! :-)' ), $pagelinkedfrom, $pagelinkedto );
  6987 		return sprintf( __( 'Pingback from %1$s to %2$s registered. Keep the web talking! :-)' ), $pagelinkedfrom, $pagelinkedto );
  6886 	}
  6988 	}
  6887 
  6989 
  6888 	/**
  6990 	/**
  6889 	 * Retrieve array of URLs that pingbacked the given URL.
  6991 	 * Retrieve array of URLs that pingbacked the given URL.
  6905 
  7007 
  6906 		$url = $this->escape( $url );
  7008 		$url = $this->escape( $url );
  6907 
  7009 
  6908 		$post_ID = url_to_postid( $url );
  7010 		$post_ID = url_to_postid( $url );
  6909 		if ( ! $post_ID ) {
  7011 		if ( ! $post_ID ) {
  6910 			// We aren't sure that the resource is available and/or pingback enabled
  7012 			// We aren't sure that the resource is available and/or pingback enabled.
  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.' ) );
  7013 			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.' ) );
  6912 		}
  7014 		}
  6913 
  7015 
  6914 		$actual_post = get_post( $post_ID, ARRAY_A );
  7016 		$actual_post = get_post( $post_ID, ARRAY_A );
  6915 
  7017 
  6916 		if ( ! $actual_post ) {
  7018 		if ( ! $actual_post ) {
  6917 			// No such post = resource not found
  7019 			// No such post = resource not found.
  6918 			return $this->pingback_error( 32, __( 'The specified target URL does not exist.' ) );
  7020 			return $this->pingback_error( 32, __( 'The specified target URL does not exist.' ) );
  6919 		}
  7021 		}
  6920 
  7022 
  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 ) );
  7023 		$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 ) );
  6922 
  7024 
  6924 			return array();
  7026 			return array();
  6925 		}
  7027 		}
  6926 
  7028 
  6927 		$pingbacks = array();
  7029 		$pingbacks = array();
  6928 		foreach ( $comments as $comment ) {
  7030 		foreach ( $comments as $comment ) {
  6929 			if ( 'pingback' == $comment->comment_type ) {
  7031 			if ( 'pingback' === $comment->comment_type ) {
  6930 				$pingbacks[] = $comment->comment_author_url;
  7032 				$pingbacks[] = $comment->comment_author_url;
  6931 			}
  7033 			}
  6932 		}
  7034 		}
  6933 
  7035 
  6934 		return $pingbacks;
  7036 		return $pingbacks;