wp/wp-includes/class-wp-xmlrpc-server.php
changeset 22 8c2e4d02f4ef
parent 21 48c4eec2b7e6
equal deleted inserted replaced
21:48c4eec2b7e6 22:8c2e4d02f4ef
   283 	 *
   283 	 *
   284 	 * @param string $username User's username.
   284 	 * @param string $username User's username.
   285 	 * @param string $password User's password.
   285 	 * @param string $password User's password.
   286 	 * @return WP_User|false WP_User object if authentication passed, false otherwise.
   286 	 * @return WP_User|false WP_User object if authentication passed, false otherwise.
   287 	 */
   287 	 */
   288 	public function login( $username, $password ) {
   288 	public function login(
       
   289 		$username,
       
   290 		#[\SensitiveParameter]
       
   291 		$password
       
   292 	) {
   289 		if ( ! $this->is_enabled ) {
   293 		if ( ! $this->is_enabled ) {
   290 			$this->error = new IXR_Error( 405, sprintf( __( 'XML-RPC services are disabled on this site.' ) ) );
   294 			$this->error = new IXR_Error( 405, sprintf( __( 'XML-RPC services are disabled on this site.' ) ) );
   291 			return false;
   295 			return false;
   292 		}
   296 		}
   293 
   297 
   328 	 *
   332 	 *
   329 	 * @param string $username User's username.
   333 	 * @param string $username User's username.
   330 	 * @param string $password User's password.
   334 	 * @param string $password User's password.
   331 	 * @return bool Whether authentication passed.
   335 	 * @return bool Whether authentication passed.
   332 	 */
   336 	 */
   333 	public function login_pass_ok( $username, $password ) {
   337 	public function login_pass_ok(
       
   338 		$username,
       
   339 		#[\SensitiveParameter]
       
   340 		$password
       
   341 	) {
   334 		return (bool) $this->login( $username, $password );
   342 		return (bool) $this->login( $username, $password );
   335 	}
   343 	}
   336 
   344 
   337 	/**
   345 	/**
   338 	 * Escapes string or array of strings for database.
   346 	 * Escapes string or array of strings for database.
   424 		foreach ( (array) $fields as $meta ) {
   432 		foreach ( (array) $fields as $meta ) {
   425 			if ( isset( $meta['id'] ) ) {
   433 			if ( isset( $meta['id'] ) ) {
   426 				$meta['id'] = (int) $meta['id'];
   434 				$meta['id'] = (int) $meta['id'];
   427 				$pmeta      = get_metadata_by_mid( 'post', $meta['id'] );
   435 				$pmeta      = get_metadata_by_mid( 'post', $meta['id'] );
   428 
   436 
   429 				if ( ! $pmeta || $pmeta->post_id != $post_id ) {
   437 				if ( ! $pmeta || (int) $pmeta->post_id !== $post_id ) {
   430 					continue;
   438 					continue;
   431 				}
   439 				}
   432 
   440 
   433 				if ( isset( $meta['key'] ) ) {
   441 				if ( isset( $meta['key'] ) ) {
   434 					$meta['key'] = wp_unslash( $meta['key'] );
   442 					$meta['key'] = wp_unslash( $meta['key'] );
   733 		 * @param array|string     $args   The escaped arguments passed to the method.
   741 		 * @param array|string     $args   The escaped arguments passed to the method.
   734 		 * @param wp_xmlrpc_server $server The XML-RPC server instance.
   742 		 * @param wp_xmlrpc_server $server The XML-RPC server instance.
   735 		 */
   743 		 */
   736 		do_action( 'xmlrpc_call', 'wp.getUsersBlogs', $args, $this );
   744 		do_action( 'xmlrpc_call', 'wp.getUsersBlogs', $args, $this );
   737 
   745 
   738 		$blogs           = (array) get_blogs_of_user( $user->ID );
   746 		$blogs  = (array) get_blogs_of_user( $user->ID );
   739 		$struct          = array();
   747 		$struct = array();
       
   748 
   740 		$primary_blog_id = 0;
   749 		$primary_blog_id = 0;
   741 		$active_blog     = get_active_blog_for_user( $user->ID );
   750 		$active_blog     = get_active_blog_for_user( $user->ID );
   742 		if ( $active_blog ) {
   751 		if ( $active_blog ) {
   743 			$primary_blog_id = (int) $active_blog->blog_id;
   752 			$primary_blog_id = (int) $active_blog->blog_id;
   744 		}
   753 		}
   745 
   754 
       
   755 		$current_network_id = get_current_network_id();
       
   756 
   746 		foreach ( $blogs as $blog ) {
   757 		foreach ( $blogs as $blog ) {
   747 			// Don't include blogs that aren't hosted at this site.
   758 			// Don't include blogs that aren't hosted at this site.
   748 			if ( get_current_network_id() != $blog->site_id ) {
   759 			if ( $blog->site_id !== $current_network_id ) {
   749 				continue;
   760 				continue;
   750 			}
   761 			}
   751 
   762 
   752 			$blog_id = $blog->userblog_id;
   763 			$blog_id = $blog->userblog_id;
   753 
   764 
  1177 	 */
  1188 	 */
  1178 	protected function _prepare_comment( $comment ) {
  1189 	protected function _prepare_comment( $comment ) {
  1179 		// Format page date.
  1190 		// Format page date.
  1180 		$comment_date_gmt = $this->_convert_date_gmt( $comment->comment_date_gmt, $comment->comment_date );
  1191 		$comment_date_gmt = $this->_convert_date_gmt( $comment->comment_date_gmt, $comment->comment_date );
  1181 
  1192 
  1182 		if ( '0' == $comment->comment_approved ) {
  1193 		if ( '0' === $comment->comment_approved ) {
  1183 			$comment_status = 'hold';
  1194 			$comment_status = 'hold';
  1184 		} elseif ( 'spam' === $comment->comment_approved ) {
  1195 		} elseif ( 'spam' === $comment->comment_approved ) {
  1185 			$comment_status = 'spam';
  1196 			$comment_status = 'spam';
  1186 		} elseif ( '1' == $comment->comment_approved ) {
  1197 		} elseif ( '1' === $comment->comment_approved ) {
  1187 			$comment_status = 'approve';
  1198 			$comment_status = 'approve';
  1188 		} else {
  1199 		} else {
  1189 			$comment_status = $comment->comment_approved;
  1200 			$comment_status = $comment->comment_approved;
  1190 		}
  1201 		}
  1191 		$_comment = array(
  1202 		$_comment = array(
  1486 		if ( ! empty( $post_data['post_password'] ) && ! current_user_can( $post_type->cap->publish_posts ) ) {
  1497 		if ( ! empty( $post_data['post_password'] ) && ! current_user_can( $post_type->cap->publish_posts ) ) {
  1487 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to create password protected posts in this post type.' ) );
  1498 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to create password protected posts in this post type.' ) );
  1488 		}
  1499 		}
  1489 
  1500 
  1490 		$post_data['post_author'] = absint( $post_data['post_author'] );
  1501 		$post_data['post_author'] = absint( $post_data['post_author'] );
  1491 		if ( ! empty( $post_data['post_author'] ) && $post_data['post_author'] != $user->ID ) {
  1502 		if ( ! empty( $post_data['post_author'] ) && $post_data['post_author'] !== $user->ID ) {
  1492 			if ( ! current_user_can( $post_type->cap->edit_others_posts ) ) {
  1503 			if ( ! current_user_can( $post_type->cap->edit_others_posts ) ) {
  1493 				return new IXR_Error( 401, __( 'Sorry, you are not allowed to create posts as this user.' ) );
  1504 				return new IXR_Error( 401, __( 'Sorry, you are not allowed to create posts as this user.' ) );
  1494 			}
  1505 			}
  1495 
  1506 
  1496 			$author = get_userdata( $post_data['post_author'] );
  1507 			$author = get_userdata( $post_data['post_author'] );
  1511 		}
  1522 		}
  1512 
  1523 
  1513 		// Do some timestamp voodoo.
  1524 		// Do some timestamp voodoo.
  1514 		if ( ! empty( $post_data['post_date_gmt'] ) ) {
  1525 		if ( ! empty( $post_data['post_date_gmt'] ) ) {
  1515 			// We know this is supposed to be GMT, so we're going to slap that Z on there by force.
  1526 			// We know this is supposed to be GMT, so we're going to slap that Z on there by force.
  1516 			$dateCreated = rtrim( $post_data['post_date_gmt']->getIso(), 'Z' ) . 'Z';
  1527 			$date_created = rtrim( $post_data['post_date_gmt']->getIso(), 'Z' ) . 'Z';
  1517 		} elseif ( ! empty( $post_data['post_date'] ) ) {
  1528 		} elseif ( ! empty( $post_data['post_date'] ) ) {
  1518 			$dateCreated = $post_data['post_date']->getIso();
  1529 			$date_created = $post_data['post_date']->getIso();
  1519 		}
  1530 		}
  1520 
  1531 
  1521 		// Default to not flagging the post date to be edited unless it's intentional.
  1532 		// Default to not flagging the post date to be edited unless it's intentional.
  1522 		$post_data['edit_date'] = false;
  1533 		$post_data['edit_date'] = false;
  1523 
  1534 
  1524 		if ( ! empty( $dateCreated ) ) {
  1535 		if ( ! empty( $date_created ) ) {
  1525 			$post_data['post_date']     = iso8601_to_datetime( $dateCreated );
  1536 			$post_data['post_date']     = iso8601_to_datetime( $date_created );
  1526 			$post_data['post_date_gmt'] = iso8601_to_datetime( $dateCreated, 'gmt' );
  1537 			$post_data['post_date_gmt'] = iso8601_to_datetime( $date_created, 'gmt' );
  1527 
  1538 
  1528 			// Flag the post date to be edited.
  1539 			// Flag the post date to be edited.
  1529 			$post_data['edit_date'] = true;
  1540 			$post_data['edit_date'] = true;
  1530 		}
  1541 		}
  1531 
  1542 
  3502 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to delete this category.' ) );
  3513 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to delete this category.' ) );
  3503 		}
  3514 		}
  3504 
  3515 
  3505 		$status = wp_delete_term( $category_id, 'category' );
  3516 		$status = wp_delete_term( $category_id, 'category' );
  3506 
  3517 
  3507 		if ( true == $status ) {
  3518 		if ( true === $status ) {
  3508 			/**
  3519 			/**
  3509 			 * Fires after a category has been successfully deleted via XML-RPC.
  3520 			 * Fires after a category has been successfully deleted via XML-RPC.
  3510 			 *
  3521 			 *
  3511 			 * @since 3.4.0
  3522 			 * @since 3.4.0
  3512 			 *
  3523 			 *
  3752 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3763 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  3753 		do_action( 'xmlrpc_call', 'wp.deleteComment', $args, $this );
  3764 		do_action( 'xmlrpc_call', 'wp.deleteComment', $args, $this );
  3754 
  3765 
  3755 		$status = wp_delete_comment( $comment_id );
  3766 		$status = wp_delete_comment( $comment_id );
  3756 
  3767 
  3757 		if ( $status ) {
  3768 		if ( true === $status ) {
  3758 			/**
  3769 			/**
  3759 			 * Fires after a comment has been successfully deleted via XML-RPC.
  3770 			 * Fires after a comment has been successfully deleted via XML-RPC.
  3760 			 *
  3771 			 *
  3761 			 * @since 3.4.0
  3772 			 * @since 3.4.0
  3762 			 *
  3773 			 *
  3835 		}
  3846 		}
  3836 
  3847 
  3837 		// Do some timestamp voodoo.
  3848 		// Do some timestamp voodoo.
  3838 		if ( ! empty( $content_struct['date_created_gmt'] ) ) {
  3849 		if ( ! empty( $content_struct['date_created_gmt'] ) ) {
  3839 			// We know this is supposed to be GMT, so we're going to slap that Z on there by force.
  3850 			// We know this is supposed to be GMT, so we're going to slap that Z on there by force.
  3840 			$dateCreated                 = rtrim( $content_struct['date_created_gmt']->getIso(), 'Z' ) . 'Z';
  3851 			$date_created = rtrim( $content_struct['date_created_gmt']->getIso(), 'Z' ) . 'Z';
  3841 			$comment['comment_date']     = get_date_from_gmt( $dateCreated );
  3852 
  3842 			$comment['comment_date_gmt'] = iso8601_to_datetime( $dateCreated, 'gmt' );
  3853 			$comment['comment_date']     = get_date_from_gmt( $date_created );
       
  3854 			$comment['comment_date_gmt'] = iso8601_to_datetime( $date_created, 'gmt' );
  3843 		}
  3855 		}
  3844 
  3856 
  3845 		if ( isset( $content_struct['content'] ) ) {
  3857 		if ( isset( $content_struct['content'] ) ) {
  3846 			$comment['comment_content'] = $content_struct['content'];
  3858 			$comment['comment_content'] = $content_struct['content'];
  3847 		}
  3859 		}
  4017 		if ( is_wp_error( $comment_id ) ) {
  4029 		if ( is_wp_error( $comment_id ) ) {
  4018 			return new IXR_Error( 403, $comment_id->get_error_message() );
  4030 			return new IXR_Error( 403, $comment_id->get_error_message() );
  4019 		}
  4031 		}
  4020 
  4032 
  4021 		if ( ! $comment_id ) {
  4033 		if ( ! $comment_id ) {
  4022 			return new IXR_Error( 403, __( 'Something went wrong.' ) );
  4034 			return new IXR_Error( 403, __( 'An error occurred while processing your comment. Please ensure all fields are filled correctly and try again.' ) );
  4023 		}
  4035 		}
  4024 
  4036 
  4025 		/**
  4037 		/**
  4026 		 * Fires after a new comment has been successfully created via XML-RPC.
  4038 		 * Fires after a new comment has been successfully created via XML-RPC.
  4027 		 *
  4039 		 *
  4324 			$option_names[] = $o_name;
  4336 			$option_names[] = $o_name;
  4325 			if ( ! array_key_exists( $o_name, $this->blog_options ) ) {
  4337 			if ( ! array_key_exists( $o_name, $this->blog_options ) ) {
  4326 				continue;
  4338 				continue;
  4327 			}
  4339 			}
  4328 
  4340 
  4329 			if ( true == $this->blog_options[ $o_name ]['readonly'] ) {
  4341 			if ( $this->blog_options[ $o_name ]['readonly'] ) {
  4330 				continue;
  4342 				continue;
  4331 			}
  4343 			}
  4332 
  4344 
  4333 			update_option( $this->blog_options[ $o_name ]['option'], wp_unslash( $o_value ) );
  4345 			update_option( $this->blog_options[ $o_name ]['option'], wp_unslash( $o_value ) );
  4334 		}
  4346 		}
  4881 		$blogs = $this->wp_getUsersBlogs( $args );
  4893 		$blogs = $this->wp_getUsersBlogs( $args );
  4882 		if ( $blogs instanceof IXR_Error ) {
  4894 		if ( $blogs instanceof IXR_Error ) {
  4883 			return $blogs;
  4895 			return $blogs;
  4884 		}
  4896 		}
  4885 
  4897 
  4886 		if ( $_SERVER['HTTP_HOST'] == $domain && $_SERVER['REQUEST_URI'] == $path ) {
  4898 		if ( $_SERVER['HTTP_HOST'] === $domain && $_SERVER['REQUEST_URI'] === $path ) {
  4887 			return $blogs;
  4899 			return $blogs;
  4888 		} else {
  4900 		} else {
  4889 			foreach ( (array) $blogs as $blog ) {
  4901 			foreach ( (array) $blogs as $blog ) {
  4890 				if ( str_contains( $blog['url'], $_SERVER['HTTP_HOST'] ) ) {
  4902 				if ( str_contains( $blog['url'], $_SERVER['HTTP_HOST'] ) ) {
  4891 					return array( $blog );
  4903 					return array( $blog );
  5037 		do_action( 'xmlrpc_call', 'blogger.getRecentPosts', $args, $this );
  5049 		do_action( 'xmlrpc_call', 'blogger.getRecentPosts', $args, $this );
  5038 
  5050 
  5039 		$posts_list = wp_get_recent_posts( $query );
  5051 		$posts_list = wp_get_recent_posts( $query );
  5040 
  5052 
  5041 		if ( ! $posts_list ) {
  5053 		if ( ! $posts_list ) {
  5042 			$this->error = new IXR_Error( 500, __( 'Either there are no posts, or something went wrong.' ) );
  5054 			$this->error = new IXR_Error( 500, __( 'No posts found or an error occurred while retrieving posts.' ) );
  5043 			return $this->error;
  5055 			return $this->error;
  5044 		}
  5056 		}
  5045 
  5057 
  5046 		$recent_posts = array();
  5058 		$recent_posts = array();
  5047 		foreach ( $posts_list as $entry ) {
  5059 		foreach ( $posts_list as $entry ) {
  5140 		$post_content  = xmlrpc_removepostdata( $content );
  5152 		$post_content  = xmlrpc_removepostdata( $content );
  5141 
  5153 
  5142 		$post_date     = current_time( 'mysql' );
  5154 		$post_date     = current_time( 'mysql' );
  5143 		$post_date_gmt = current_time( 'mysql', 1 );
  5155 		$post_date_gmt = current_time( 'mysql', 1 );
  5144 
  5156 
  5145 		$post_data = compact( 'post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_title', 'post_category', 'post_status' );
  5157 		$post_data = compact(
       
  5158 			'post_author',
       
  5159 			'post_date',
       
  5160 			'post_date_gmt',
       
  5161 			'post_content',
       
  5162 			'post_title',
       
  5163 			'post_category',
       
  5164 			'post_status'
       
  5165 		);
  5146 
  5166 
  5147 		$post_id = wp_insert_post( $post_data );
  5167 		$post_id = wp_insert_post( $post_data );
  5148 		if ( is_wp_error( $post_id ) ) {
  5168 		if ( is_wp_error( $post_id ) ) {
  5149 			return new IXR_Error( 500, $post_id->get_error_message() );
  5169 			return new IXR_Error( 500, $post_id->get_error_message() );
  5150 		}
  5170 		}
  5446 			$menu_order = $content_struct['wp_page_order'];
  5466 			$menu_order = $content_struct['wp_page_order'];
  5447 		}
  5467 		}
  5448 
  5468 
  5449 		$post_author = $user->ID;
  5469 		$post_author = $user->ID;
  5450 
  5470 
  5451 		// If an author id was provided then use it instead.
  5471 		// If an author ID was provided then use it instead.
  5452 		if ( isset( $content_struct['wp_author_id'] ) && ( $user->ID != $content_struct['wp_author_id'] ) ) {
  5472 		if ( isset( $content_struct['wp_author_id'] ) && ( $user->ID !== (int) $content_struct['wp_author_id'] ) ) {
  5453 			switch ( $post_type ) {
  5473 			switch ( $post_type ) {
  5454 				case 'post':
  5474 				case 'post':
  5455 					if ( ! current_user_can( 'edit_others_posts' ) ) {
  5475 					if ( ! current_user_can( 'edit_others_posts' ) ) {
  5456 						return new IXR_Error( 401, __( 'Sorry, you are not allowed to create posts as this user.' ) );
  5476 						return new IXR_Error( 401, __( 'Sorry, you are not allowed to create posts as this user.' ) );
  5457 					}
  5477 					}
  5569 		}
  5589 		}
  5570 
  5590 
  5571 		// Do some timestamp voodoo.
  5591 		// Do some timestamp voodoo.
  5572 		if ( ! empty( $content_struct['date_created_gmt'] ) ) {
  5592 		if ( ! empty( $content_struct['date_created_gmt'] ) ) {
  5573 			// We know this is supposed to be GMT, so we're going to slap that Z on there by force.
  5593 			// We know this is supposed to be GMT, so we're going to slap that Z on there by force.
  5574 			$dateCreated = rtrim( $content_struct['date_created_gmt']->getIso(), 'Z' ) . 'Z';
  5594 			$date_created = rtrim( $content_struct['date_created_gmt']->getIso(), 'Z' ) . 'Z';
  5575 		} elseif ( ! empty( $content_struct['dateCreated'] ) ) {
  5595 		} elseif ( ! empty( $content_struct['dateCreated'] ) ) {
  5576 			$dateCreated = $content_struct['dateCreated']->getIso();
  5596 			$date_created = $content_struct['dateCreated']->getIso();
  5577 		}
  5597 		}
  5578 
  5598 
  5579 		$post_date     = '';
  5599 		$post_date     = '';
  5580 		$post_date_gmt = '';
  5600 		$post_date_gmt = '';
  5581 		if ( ! empty( $dateCreated ) ) {
  5601 		if ( ! empty( $date_created ) ) {
  5582 			$post_date     = iso8601_to_datetime( $dateCreated );
  5602 			$post_date     = iso8601_to_datetime( $date_created );
  5583 			$post_date_gmt = iso8601_to_datetime( $dateCreated, 'gmt' );
  5603 			$post_date_gmt = iso8601_to_datetime( $date_created, 'gmt' );
  5584 		}
  5604 		}
  5585 
  5605 
  5586 		$post_category = array();
  5606 		$post_category = array();
  5587 		if ( isset( $content_struct['categories'] ) ) {
  5607 		if ( isset( $content_struct['categories'] ) ) {
  5588 			$catnames = $content_struct['categories'];
  5608 			$catnames = $content_struct['categories'];
  5592 					$post_category[] = get_cat_ID( $cat );
  5612 					$post_category[] = get_cat_ID( $cat );
  5593 				}
  5613 				}
  5594 			}
  5614 			}
  5595 		}
  5615 		}
  5596 
  5616 
  5597 		$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' );
  5617 		$postdata = compact(
       
  5618 			'post_author',
       
  5619 			'post_date',
       
  5620 			'post_date_gmt',
       
  5621 			'post_content',
       
  5622 			'post_title',
       
  5623 			'post_category',
       
  5624 			'post_status',
       
  5625 			'post_excerpt',
       
  5626 			'comment_status',
       
  5627 			'ping_status',
       
  5628 			'to_ping',
       
  5629 			'post_type',
       
  5630 			'post_name',
       
  5631 			'post_password',
       
  5632 			'post_parent',
       
  5633 			'menu_order',
       
  5634 			'tags_input',
       
  5635 			'page_template'
       
  5636 		);
  5598 
  5637 
  5599 		$post_id        = get_default_post_to_edit( $post_type, true )->ID;
  5638 		$post_id        = get_default_post_to_edit( $post_type, true )->ID;
  5600 		$postdata['ID'] = $post_id;
  5639 		$postdata['ID'] = $post_id;
  5601 
  5640 
  5602 		// Only posts can be sticky.
  5641 		// Only posts can be sticky.
  5620 
  5659 
  5621 			unset( $content_struct['wp_post_thumbnail'] );
  5660 			unset( $content_struct['wp_post_thumbnail'] );
  5622 		}
  5661 		}
  5623 
  5662 
  5624 		// Handle enclosures.
  5663 		// Handle enclosures.
  5625 		$thisEnclosure = isset( $content_struct['enclosure'] ) ? $content_struct['enclosure'] : null;
  5664 		$enclosure = isset( $content_struct['enclosure'] ) ? $content_struct['enclosure'] : null;
  5626 		$this->add_enclosure_if_new( $post_id, $thisEnclosure );
  5665 		$this->add_enclosure_if_new( $post_id, $enclosure );
  5627 
  5666 
  5628 		$this->attach_uploads( $post_id, $post_content );
  5667 		$this->attach_uploads( $post_id, $post_content );
  5629 
  5668 
  5630 		/*
  5669 		/*
  5631 		 * Handle post formats if assigned, value is validated earlier
  5670 		 * Handle post formats if assigned, value is validated earlier
  5760 		if ( ! in_array( $postdata['post_type'], array( 'post', 'page' ), true ) ) {
  5799 		if ( ! in_array( $postdata['post_type'], array( 'post', 'page' ), true ) ) {
  5761 			return new IXR_Error( 401, __( 'Invalid post type.' ) );
  5800 			return new IXR_Error( 401, __( 'Invalid post type.' ) );
  5762 		}
  5801 		}
  5763 
  5802 
  5764 		// Thwart attempt to change the post type.
  5803 		// Thwart attempt to change the post type.
  5765 		if ( ! empty( $content_struct['post_type'] ) && ( $content_struct['post_type'] != $postdata['post_type'] ) ) {
  5804 		if ( ! empty( $content_struct['post_type'] ) && ( $content_struct['post_type'] !== $postdata['post_type'] ) ) {
  5766 			return new IXR_Error( 401, __( 'The post type may not be changed.' ) );
  5805 			return new IXR_Error( 401, __( 'The post type may not be changed.' ) );
  5767 		}
  5806 		}
  5768 
  5807 
  5769 		// Check for a valid post format if one was given.
  5808 		// Check for a valid post format if one was given.
  5770 		if ( isset( $content_struct['wp_post_format'] ) ) {
  5809 		if ( isset( $content_struct['wp_post_format'] ) ) {
  5774 			}
  5813 			}
  5775 		}
  5814 		}
  5776 
  5815 
  5777 		$this->escape( $postdata );
  5816 		$this->escape( $postdata );
  5778 
  5817 
  5779 		$ID             = $postdata['ID'];
  5818 		$post_id        = $postdata['ID'];
  5780 		$post_content   = $postdata['post_content'];
  5819 		$post_content   = $postdata['post_content'];
  5781 		$post_title     = $postdata['post_title'];
  5820 		$post_title     = $postdata['post_title'];
  5782 		$post_excerpt   = $postdata['post_excerpt'];
  5821 		$post_excerpt   = $postdata['post_excerpt'];
  5783 		$post_password  = $postdata['post_password'];
  5822 		$post_password  = $postdata['post_password'];
  5784 		$post_parent    = $postdata['post_parent'];
  5823 		$post_parent    = $postdata['post_parent'];
  5813 			$page_template = $content_struct['wp_page_template'];
  5852 			$page_template = $content_struct['wp_page_template'];
  5814 		}
  5853 		}
  5815 
  5854 
  5816 		$post_author = $postdata['post_author'];
  5855 		$post_author = $postdata['post_author'];
  5817 
  5856 
  5818 		// If an author id was provided then use it instead.
  5857 		// If an author ID was provided then use it instead.
  5819 		if ( isset( $content_struct['wp_author_id'] ) ) {
  5858 		if ( isset( $content_struct['wp_author_id'] ) ) {
  5820 			// Check permissions if attempting to switch author to or from another user.
  5859 			// Check permissions if attempting to switch author to or from another user.
  5821 			if ( $user->ID != $content_struct['wp_author_id'] || $user->ID != $post_author ) {
  5860 			if ( $user->ID !== (int) $content_struct['wp_author_id'] || $user->ID !== (int) $post_author ) {
  5822 				switch ( $post_type ) {
  5861 				switch ( $post_type ) {
  5823 					case 'post':
  5862 					case 'post':
  5824 						if ( ! current_user_can( 'edit_others_posts' ) ) {
  5863 						if ( ! current_user_can( 'edit_others_posts' ) ) {
  5825 							return new IXR_Error( 401, __( 'Sorry, you are not allowed to change the post author as this user.' ) );
  5864 							return new IXR_Error( 401, __( 'Sorry, you are not allowed to change the post author as this user.' ) );
  5826 						}
  5865 						}
  5956 		}
  5995 		}
  5957 
  5996 
  5958 		// Do some timestamp voodoo.
  5997 		// Do some timestamp voodoo.
  5959 		if ( ! empty( $content_struct['date_created_gmt'] ) ) {
  5998 		if ( ! empty( $content_struct['date_created_gmt'] ) ) {
  5960 			// We know this is supposed to be GMT, so we're going to slap that Z on there by force.
  5999 			// We know this is supposed to be GMT, so we're going to slap that Z on there by force.
  5961 			$dateCreated = rtrim( $content_struct['date_created_gmt']->getIso(), 'Z' ) . 'Z';
  6000 			$date_created = rtrim( $content_struct['date_created_gmt']->getIso(), 'Z' ) . 'Z';
  5962 		} elseif ( ! empty( $content_struct['dateCreated'] ) ) {
  6001 		} elseif ( ! empty( $content_struct['dateCreated'] ) ) {
  5963 			$dateCreated = $content_struct['dateCreated']->getIso();
  6002 			$date_created = $content_struct['dateCreated']->getIso();
  5964 		}
  6003 		}
  5965 
  6004 
  5966 		// Default to not flagging the post date to be edited unless it's intentional.
  6005 		// Default to not flagging the post date to be edited unless it's intentional.
  5967 		$edit_date = false;
  6006 		$edit_date = false;
  5968 
  6007 
  5969 		if ( ! empty( $dateCreated ) ) {
  6008 		if ( ! empty( $date_created ) ) {
  5970 			$post_date     = iso8601_to_datetime( $dateCreated );
  6009 			$post_date     = iso8601_to_datetime( $date_created );
  5971 			$post_date_gmt = iso8601_to_datetime( $dateCreated, 'gmt' );
  6010 			$post_date_gmt = iso8601_to_datetime( $date_created, 'gmt' );
  5972 
  6011 
  5973 			// Flag the post date to be edited.
  6012 			// Flag the post date to be edited.
  5974 			$edit_date = true;
  6013 			$edit_date = true;
  5975 		} else {
  6014 		} else {
  5976 			$post_date     = $postdata['post_date'];
  6015 			$post_date     = $postdata['post_date'];
  5977 			$post_date_gmt = $postdata['post_date_gmt'];
  6016 			$post_date_gmt = $postdata['post_date_gmt'];
  5978 		}
  6017 		}
  5979 
  6018 
       
  6019 		$newpost = array(
       
  6020 			'ID' => $post_id,
       
  6021 		);
       
  6022 
       
  6023 		$newpost += compact(
       
  6024 			'post_content',
       
  6025 			'post_title',
       
  6026 			'post_category',
       
  6027 			'post_status',
       
  6028 			'post_excerpt',
       
  6029 			'comment_status',
       
  6030 			'ping_status',
       
  6031 			'edit_date',
       
  6032 			'post_date',
       
  6033 			'post_date_gmt',
       
  6034 			'to_ping',
       
  6035 			'post_name',
       
  6036 			'post_password',
       
  6037 			'post_parent',
       
  6038 			'menu_order',
       
  6039 			'post_author',
       
  6040 			'tags_input',
       
  6041 			'page_template'
       
  6042 		);
       
  6043 
  5980 		// We've got all the data -- post it.
  6044 		// We've got all the data -- post it.
  5981 		$newpost = compact( 'ID', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt', 'comment_status', 'ping_status', 'edit_date', 'post_date', 'post_date_gmt', 'to_ping', 'post_name', 'post_password', 'post_parent', 'menu_order', 'post_author', 'tags_input', 'page_template' );
       
  5982 
       
  5983 		$result = wp_update_post( $newpost, true );
  6045 		$result = wp_update_post( $newpost, true );
  5984 		if ( is_wp_error( $result ) ) {
  6046 		if ( is_wp_error( $result ) ) {
  5985 			return new IXR_Error( 500, $result->get_error_message() );
  6047 			return new IXR_Error( 500, $result->get_error_message() );
  5986 		}
  6048 		}
  5987 
  6049 
  6016 			}
  6078 			}
  6017 			unset( $content_struct['wp_post_thumbnail'] );
  6079 			unset( $content_struct['wp_post_thumbnail'] );
  6018 		}
  6080 		}
  6019 
  6081 
  6020 		// Handle enclosures.
  6082 		// Handle enclosures.
  6021 		$thisEnclosure = isset( $content_struct['enclosure'] ) ? $content_struct['enclosure'] : null;
  6083 		$enclosure = isset( $content_struct['enclosure'] ) ? $content_struct['enclosure'] : null;
  6022 		$this->add_enclosure_if_new( $post_id, $thisEnclosure );
  6084 		$this->add_enclosure_if_new( $post_id, $enclosure );
  6023 
  6085 
  6024 		$this->attach_uploads( $ID, $post_content );
  6086 		$this->attach_uploads( $post_id, $post_content );
  6025 
  6087 
  6026 		// Handle post formats if assigned, validation is handled earlier in this function.
  6088 		// Handle post formats if assigned, validation is handled earlier in this function.
  6027 		if ( isset( $content_struct['wp_post_format'] ) ) {
  6089 		if ( isset( $content_struct['wp_post_format'] ) ) {
  6028 			set_post_format( $post_id, $content_struct['wp_post_format'] );
  6090 			set_post_format( $post_id, $content_struct['wp_post_format'] );
  6029 		}
  6091 		}
  6084 			$post_date_gmt     = $this->_convert_date_gmt( $postdata['post_date_gmt'], $postdata['post_date'] );
  6146 			$post_date_gmt     = $this->_convert_date_gmt( $postdata['post_date_gmt'], $postdata['post_date'] );
  6085 			$post_modified     = $this->_convert_date( $postdata['post_modified'] );
  6147 			$post_modified     = $this->_convert_date( $postdata['post_modified'] );
  6086 			$post_modified_gmt = $this->_convert_date_gmt( $postdata['post_modified_gmt'], $postdata['post_modified'] );
  6148 			$post_modified_gmt = $this->_convert_date_gmt( $postdata['post_modified_gmt'], $postdata['post_modified'] );
  6087 
  6149 
  6088 			$categories = array();
  6150 			$categories = array();
  6089 			$catids     = wp_get_post_categories( $post_id );
  6151 			$cat_ids    = wp_get_post_categories( $post_id );
  6090 			foreach ( $catids as $catid ) {
  6152 			foreach ( $cat_ids as $cat_id ) {
  6091 				$categories[] = get_cat_name( $catid );
  6153 				$categories[] = get_cat_name( $cat_id );
  6092 			}
  6154 			}
  6093 
  6155 
  6094 			$tagnames = array();
  6156 			$tagnames = array();
  6095 			$tags     = wp_get_post_tags( $post_id );
  6157 			$tags     = wp_get_post_tags( $post_id );
  6096 			if ( ! empty( $tags ) ) {
  6158 			if ( ! empty( $tags ) ) {
  6236 			$post_date_gmt     = $this->_convert_date_gmt( $entry['post_date_gmt'], $entry['post_date'] );
  6298 			$post_date_gmt     = $this->_convert_date_gmt( $entry['post_date_gmt'], $entry['post_date'] );
  6237 			$post_modified     = $this->_convert_date( $entry['post_modified'] );
  6299 			$post_modified     = $this->_convert_date( $entry['post_modified'] );
  6238 			$post_modified_gmt = $this->_convert_date_gmt( $entry['post_modified_gmt'], $entry['post_modified'] );
  6300 			$post_modified_gmt = $this->_convert_date_gmt( $entry['post_modified_gmt'], $entry['post_modified'] );
  6239 
  6301 
  6240 			$categories = array();
  6302 			$categories = array();
  6241 			$catids     = wp_get_post_categories( $entry['ID'] );
  6303 			$cat_ids    = wp_get_post_categories( $entry['ID'] );
  6242 			foreach ( $catids as $catid ) {
  6304 			foreach ( $cat_ids as $cat_id ) {
  6243 				$categories[] = get_cat_name( $catid );
  6305 				$categories[] = get_cat_name( $cat_id );
  6244 			}
  6306 			}
  6245 
  6307 
  6246 			$tagnames = array();
  6308 			$tagnames = array();
  6247 			$tags     = wp_get_post_tags( $entry['ID'] );
  6309 			$tags     = wp_get_post_tags( $entry['ID'] );
  6248 			if ( ! empty( $tags ) ) {
  6310 			if ( ! empty( $tags ) ) {
  6431 		}
  6493 		}
  6432 
  6494 
  6433 		$upload = wp_upload_bits( $name, null, $bits );
  6495 		$upload = wp_upload_bits( $name, null, $bits );
  6434 		if ( ! empty( $upload['error'] ) ) {
  6496 		if ( ! empty( $upload['error'] ) ) {
  6435 			/* translators: 1: File name, 2: Error message. */
  6497 			/* translators: 1: File name, 2: Error message. */
  6436 			$errorString = sprintf( __( 'Could not write file %1$s (%2$s).' ), $name, $upload['error'] );
  6498 			$error_string = sprintf( __( 'Could not write file %1$s (%2$s).' ), $name, $upload['error'] );
  6437 			return new IXR_Error( 500, $errorString );
  6499 			return new IXR_Error( 500, $error_string );
  6438 		}
  6500 		}
       
  6501 
  6439 		// Construct the attachment array.
  6502 		// Construct the attachment array.
  6440 		$post_id = 0;
  6503 		$post_id = 0;
  6441 		if ( ! empty( $data['post_id'] ) ) {
  6504 		if ( ! empty( $data['post_id'] ) ) {
  6442 			$post_id = (int) $data['post_id'];
  6505 			$post_id = (int) $data['post_id'];
  6443 
  6506 
  6444 			if ( ! current_user_can( 'edit_post', $post_id ) ) {
  6507 			if ( ! current_user_can( 'edit_post', $post_id ) ) {
  6445 				return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit this post.' ) );
  6508 				return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit this post.' ) );
  6446 			}
  6509 			}
  6447 		}
  6510 		}
       
  6511 
  6448 		$attachment = array(
  6512 		$attachment = array(
  6449 			'post_title'     => $name,
  6513 			'post_title'     => $name,
  6450 			'post_content'   => '',
  6514 			'post_content'   => '',
  6451 			'post_type'      => 'attachment',
  6515 			'post_type'      => 'attachment',
  6452 			'post_parent'    => $post_id,
  6516 			'post_parent'    => $post_id,
  6453 			'post_mime_type' => $type,
  6517 			'post_mime_type' => $type,
  6454 			'guid'           => $upload['url'],
  6518 			'guid'           => $upload['url'],
  6455 		);
  6519 		);
  6456 
  6520 
  6457 		// Save the data.
  6521 		// Save the data.
  6458 		$id = wp_insert_attachment( $attachment, $upload['file'], $post_id );
  6522 		$attachment_id = wp_insert_attachment( $attachment, $upload['file'], $post_id );
  6459 		wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $upload['file'] ) );
  6523 		wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $upload['file'] ) );
  6460 
  6524 
  6461 		/**
  6525 		/**
  6462 		 * Fires after a new attachment has been added via the XML-RPC MovableType API.
  6526 		 * Fires after a new attachment has been added via the XML-RPC MovableType API.
  6463 		 *
  6527 		 *
  6464 		 * @since 3.4.0
  6528 		 * @since 3.4.0
  6465 		 *
  6529 		 *
  6466 		 * @param int   $id   ID of the new attachment.
  6530 		 * @param int   $attachment_id ID of the new attachment.
  6467 		 * @param array $args An array of arguments to add the attachment.
  6531 		 * @param array $args          An array of arguments to add the attachment.
  6468 		 */
  6532 		 */
  6469 		do_action( 'xmlrpc_call_success_mw_newMediaObject', $id, $args ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.NotLowercase
  6533 		do_action( 'xmlrpc_call_success_mw_newMediaObject', $attachment_id, $args ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.NotLowercase
  6470 
  6534 
  6471 		$struct = $this->_prepare_media_item( get_post( $id ) );
  6535 		$struct = $this->_prepare_media_item( get_post( $attachment_id ) );
  6472 
  6536 
  6473 		// Deprecated values.
  6537 		// Deprecated values.
  6474 		$struct['id']   = $struct['attachment_id'];
  6538 		$struct['id']   = $struct['attachment_id'];
  6475 		$struct['file'] = $struct['title'];
  6539 		$struct['file'] = $struct['title'];
  6476 		$struct['url']  = $struct['link'];
  6540 		$struct['url']  = $struct['link'];
  6518 		do_action( 'xmlrpc_call', 'mt.getRecentPostTitles', $args, $this );
  6582 		do_action( 'xmlrpc_call', 'mt.getRecentPostTitles', $args, $this );
  6519 
  6583 
  6520 		$posts_list = wp_get_recent_posts( $query );
  6584 		$posts_list = wp_get_recent_posts( $query );
  6521 
  6585 
  6522 		if ( ! $posts_list ) {
  6586 		if ( ! $posts_list ) {
  6523 			$this->error = new IXR_Error( 500, __( 'Either there are no posts, or something went wrong.' ) );
  6587 			$this->error = new IXR_Error( 500, __( 'No posts found or an error occurred while retrieving posts.' ) );
  6524 			return $this->error;
  6588 			return $this->error;
  6525 		}
  6589 		}
  6526 
  6590 
  6527 		$recent_posts = array();
  6591 		$recent_posts = array();
  6528 
  6592 
  6636 
  6700 
  6637 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  6701 		/** This action is documented in wp-includes/class-wp-xmlrpc-server.php */
  6638 		do_action( 'xmlrpc_call', 'mt.getPostCategories', $args, $this );
  6702 		do_action( 'xmlrpc_call', 'mt.getPostCategories', $args, $this );
  6639 
  6703 
  6640 		$categories = array();
  6704 		$categories = array();
  6641 		$catids     = wp_get_post_categories( (int) $post_id );
  6705 		$cat_ids    = wp_get_post_categories( (int) $post_id );
  6642 		// First listed category will be the primary category.
  6706 		// First listed category will be the primary category.
  6643 		$isPrimary = true;
  6707 		$is_primary = true;
  6644 		foreach ( $catids as $catid ) {
  6708 		foreach ( $cat_ids as $cat_id ) {
  6645 			$categories[] = array(
  6709 			$categories[] = array(
  6646 				'categoryName' => get_cat_name( $catid ),
  6710 				'categoryName' => get_cat_name( $cat_id ),
  6647 				'categoryId'   => (string) $catid,
  6711 				'categoryId'   => (string) $cat_id,
  6648 				'isPrimary'    => $isPrimary,
  6712 				'isPrimary'    => $is_primary,
  6649 			);
  6713 			);
  6650 			$isPrimary    = false;
  6714 			$is_primary   = false;
  6651 		}
  6715 		}
  6652 
  6716 
  6653 		return $categories;
  6717 		return $categories;
  6654 	}
  6718 	}
  6655 
  6719 
  6690 
  6754 
  6691 		if ( ! current_user_can( 'edit_post', $post_id ) ) {
  6755 		if ( ! current_user_can( 'edit_post', $post_id ) ) {
  6692 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit this post.' ) );
  6756 			return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit this post.' ) );
  6693 		}
  6757 		}
  6694 
  6758 
  6695 		$catids = array();
  6759 		$cat_ids = array();
  6696 		foreach ( $categories as $cat ) {
  6760 		foreach ( $categories as $cat ) {
  6697 			$catids[] = $cat['categoryId'];
  6761 			$cat_ids[] = $cat['categoryId'];
  6698 		}
  6762 		}
  6699 
  6763 
  6700 		wp_set_post_categories( $post_id, $catids );
  6764 		wp_set_post_categories( $post_id, $cat_ids );
  6701 
  6765 
  6702 		return true;
  6766 		return true;
  6703 	}
  6767 	}
  6704 
  6768 
  6705 	/**
  6769 	/**
  6883 		 * FIXME: Does url_to_postid() cover all these cases already?
  6947 		 * FIXME: Does url_to_postid() cover all these cases already?
  6884 		 * If so, then let's use it and drop the old code.
  6948 		 * If so, then let's use it and drop the old code.
  6885 		 */
  6949 		 */
  6886 		$urltest = parse_url( $pagelinkedto );
  6950 		$urltest = parse_url( $pagelinkedto );
  6887 		$post_id = url_to_postid( $pagelinkedto );
  6951 		$post_id = url_to_postid( $pagelinkedto );
       
  6952 
  6888 		if ( $post_id ) {
  6953 		if ( $post_id ) {
  6889 			// $way
  6954 			// $way
  6890 		} elseif ( isset( $urltest['path'] ) && preg_match( '#p/[0-9]{1,}#', $urltest['path'], $match ) ) {
  6955 		} elseif ( isset( $urltest['path'] ) && preg_match( '#p/[0-9]{1,}#', $urltest['path'], $match ) ) {
  6891 			// The path defines the post_ID (archives/p/XXXX).
  6956 			// The path defines the post_ID (archives/p/XXXX).
  6892 			$blah    = explode( '/', $match[0] );
  6957 			$blah    = explode( '/', $match[0] );
  6915 			}
  6980 			}
  6916 		} else {
  6981 		} else {
  6917 			// TODO: Attempt to extract a post ID from the given URL.
  6982 			// TODO: Attempt to extract a post ID from the given URL.
  6918 			return $this->pingback_error( 33, __( 'The specified target URL cannot be used as a target. It either does not exist, or it is not a pingback-enabled resource.' ) );
  6983 			return $this->pingback_error( 33, __( 'The specified target URL cannot be used as a target. It either does not exist, or it is not a pingback-enabled resource.' ) );
  6919 		}
  6984 		}
       
  6985 
  6920 		$post_id = (int) $post_id;
  6986 		$post_id = (int) $post_id;
  6921 
  6987 		$post    = get_post( $post_id );
  6922 		$post = get_post( $post_id );
       
  6923 
  6988 
  6924 		if ( ! $post ) { // Post not found.
  6989 		if ( ! $post ) { // Post not found.
  6925 			return $this->pingback_error( 33, __( 'The specified target URL cannot be used as a target. It either does not exist, or it is not a pingback-enabled resource.' ) );
  6990 			return $this->pingback_error( 33, __( 'The specified target URL cannot be used as a target. It either does not exist, or it is not a pingback-enabled resource.' ) );
  6926 		}
  6991 		}
  6927 
  6992 
  6928 		if ( url_to_postid( $pagelinkedfrom ) == $post_id ) {
  6993 		if ( url_to_postid( $pagelinkedfrom ) === $post_id ) {
  6929 			return $this->pingback_error( 0, __( 'The source URL and the target URL cannot both point to the same resource.' ) );
  6994 			return $this->pingback_error( 0, __( 'The source URL and the target URL cannot both point to the same resource.' ) );
  6930 		}
  6995 		}
  6931 
  6996 
  6932 		// Check if pings are on.
  6997 		// Check if pings are on.
  6933 		if ( ! pings_open( $post ) ) {
  6998 		if ( ! pings_open( $post ) ) {