Index: wp-includes/class-wp-xmlrpc-server.php
===================================================================
--- wp-includes/class-wp-xmlrpc-server.php	(revision 20030)
+++ wp-includes/class-wp-xmlrpc-server.php	(working copy)
@@ -467,6 +467,36 @@
 	}
 
 	/**
+	 * Convert a WordPress date string to an IXR_Date object.
+	 *
+	 * @access protected
+	 *
+	 * @param $date
+	 * @return IXR_Date
+	 */
+	protected function _convert_date( $date, $format = 'Ymd\TH:i:s' ) {
+		if ( $date === '0000-00-00 00:00:00' ) {
+			return new IXR_Date( '00000000T00:00:00Z' );
+		}
+		return new IXR_Date( mysql2date( $format, $date, false ) );
+	}
+
+	/**
+	 * Convert a WordPress date string to an IXR_Date object.
+	 *
+	 * @access protected
+	 *
+	 * @param $date
+	 * @return IXR_Date
+	 */
+	protected function _convert_date_gmt( $date, $format = 'Ymd\TH:i:s' ) {
+		if ( $date === '0000-00-00 00:00:00' ) {
+			return new IXR_Date( '00000000T00:00:00Z' );
+		}
+		return new IXR_Date( get_gmt_from_date( mysql2date( $format, $date, false ) ) );
+	}
+
+	/**
 	 * Prepares post data for return in an XML-RPC object.
 	 *
 	 * @access private
@@ -477,15 +507,15 @@
 	 */
 	function _prepare_post( $post, $fields ) {
 		// holds the data for this post. built up based on $fields
-		$_post = array( 'post_id' => $post['ID'] );
+		$_post = array( 'post_id' => strval( $post['ID'] ) );
 
 		// prepare common post fields
 		$post_fields = array(
 			'post_title'        => $post['post_title'],
-			'post_date'         => new IXR_Date( mysql2date( 'Ymd\TH:i:s', $post['post_date'], false ) ),
-			'post_date_gmt'     => new IXR_Date( mysql2date( 'Ymd\TH:i:s', $post['post_date_gmt'], false ) ),
-			'post_modified'     => new IXR_Date( mysql2date( 'Ymd\TH:i:s', $post['post_modified'], false ) ),
-			'post_modified_gmt' => new IXR_Date( mysql2date( 'Ymd\TH:i:s', $post['post_modified_gmt'], false ) ),
+			'post_date'         => $this->_convert_date( $post['post_date'] ),
+			'post_date_gmt'     => $this->_convert_date( $post['post_date_gmt'] ),
+			'post_modified'     => $this->_convert_date( $post['post_modified'] ),
+			'post_modified_gmt' => $this->_convert_date( $post['post_modified_gmt'] ),
 			'post_status'       => $post['post_status'],
 			'post_type'         => $post['post_type'],
 			'post_name'         => $post['post_name'],
@@ -499,6 +529,10 @@
 			'sticky'            => ( $post['post_type'] === 'post' && is_sticky( $post['ID'] ) ),
 		);
 
+		if( current_theme_supports( 'post-thumbnails' ) ) {
+			$post_fields['featured_image'] = get_post_thumbnail_id( $post['ID'] );
+		}
+
 		// Consider future posts as published
 		if ( $post_fields['post_status'] === 'future' )
 			$post_fields['post_status'] = 'publish';
@@ -591,6 +625,7 @@
 	 *      - comment_status - can be 'open' | 'closed'
 	 *      - ping_status - can be 'open' | 'closed'
 	 *      - sticky
+	 *      - featured_image - ID of a media item to use as the featured image
 	 *      - custom_fields - array, with each element containing 'key' and 'value'
 	 *      - terms - array, with taxonomy names as keys and arrays of term IDs as values
 	 *      - terms_names - array, with taxonomy names as keys and arrays of term names as values
@@ -724,6 +759,23 @@
 			stick_post( $post_ID );
 		}
 
+		if ( isset ( $post_data['featured_image'] ) ) {
+			if( current_theme_supports( 'post-thumbnails' ) ) {
+				// empty value deletes, non-empty value adds/updates
+				if ( empty( $post_data['featured_image'] ) ) {
+					delete_post_thumbnail( $post_ID );
+				}
+				else {
+					if ( set_post_thumbnail( $post_ID, $post_data['featured_image'] ) === false )
+						return new IXR_Error( 404, __( 'Invalid attachment ID.' ) );
+				}
+				unset( $content_struct['featured_image'] );
+			}
+			else {
+				return new IXR_Error( 401, __( 'Sorry, you are not able to set a post thumbnail.' ) );
+			}
+		}
+
 		if ( isset ( $post_data['custom_fields'] ) && post_type_supports( $post_data['post_type'], 'custom-fields' ) ) {
 			$this->set_custom_fields( $post_ID, $post_data['custom_fields'] );
 		}
@@ -880,14 +932,14 @@
 			return new IXR_Error( 404, __( 'Invalid post ID.' ) );
 
 		// convert the date field back to IXR form
-		$post['post_date'] = new IXR_Date( mysql2date( 'Ymd\TH:i:s', $post['post_date'], false ) );
+		$post['post_date'] = $this->_convert_date( $post['post_date'] );
 
 		// ignore the existing GMT date if it is empty or a non-GMT date was supplied in $content_struct,
 		// since _insert_post will ignore the non-GMT date if the GMT date is set
 		if ( $post['post_date_gmt'] == '0000-00-00 00:00:00' || isset( $content_struct['post_date'] ) )
 			unset( $post['post_date_gmt'] );
 		else
-			$post['post_date_gmt'] = new IXR_Date( mysql2date( 'Ymd\TH:i:s', $post['post_date_gmt'], false ) );
+			$post['post_date_gmt'] = $this->_convert_date( $post['post_date_gmt'] );
 
 		$this->escape( $post );
 		$merged_content_struct = array_merge( $post, $content_struct );
@@ -1080,8 +1132,6 @@
 				$query['order'] = $filter['order'];
 		}
 
-		do_action( 'xmlrpc_call', 'wp.getPosts' );
-
 		$posts_list = wp_get_recent_posts( $query );
 
 		if ( ! $posts_list )
@@ -1151,12 +1201,12 @@
 			$allow_pings = pings_open($page->ID) ? 1 : 0;
 
 			// Format page date.
-			$page_date = mysql2date('Ymd\TH:i:s', $page->post_date, false);
-			$page_date_gmt = mysql2date('Ymd\TH:i:s', $page->post_date_gmt, false);
+			$page_date = $this->_convert_date( $page->post_date );
+			$page_date_gmt = $this->_convert_date( $page->post_date_gmt );
 
 			// For drafts use the GMT version of the date
-			if ( $page->post_status == 'draft' )
-				$page_date_gmt = get_gmt_from_date( mysql2date( 'Y-m-d H:i:s', $page->post_date ), 'Ymd\TH:i:s' );
+			if ( in_array( $page->post_status, array( 'draft', 'pending', 'auto-draft' ) ) )
+				$page_date_gmt = $this->_convert_date_gmt( $page->post_date );
 
 			// Pull the categories info together.
 			$categories = array();
@@ -1172,7 +1222,7 @@
 				$page_template = 'default';
 
 			$page_struct = array(
-				'dateCreated'			=> new IXR_Date($page_date),
+				'dateCreated'			=> $page_date,
 				'userid'				=> $page->post_author,
 				'page_id'				=> $page->ID,
 				'page_status'			=> $page->post_status,
@@ -1193,7 +1243,7 @@
 				'wp_page_order'			=> $page->menu_order,
 				'wp_author_id'			=> (string) $author->ID,
 				'wp_author_display_name'	=> $author->display_name,
-				'date_created_gmt'		=> new IXR_Date($page_date_gmt),
+				'date_created_gmt'		=> $page_date_gmt,
 				'custom_fields'			=> $this->get_custom_fields($page_id),
 				'wp_page_template'		=> $page_template
 			);
@@ -1410,16 +1460,12 @@
 		// The date needs to be formatted properly.
 		$num_pages = count($page_list);
 		for ( $i = 0; $i < $num_pages; $i++ ) {
-			$post_date = mysql2date('Ymd\TH:i:s', $page_list[$i]->post_date, false);
-			$post_date_gmt = mysql2date('Ymd\TH:i:s', $page_list[$i]->post_date_gmt, false);
+			$page_list[$i]->dateCreated = $this->_convert_date(  $page_list[$i]->post_date );
+			$page_list[$i]->date_created_gmt = $this->_convert_date( $page_list[$i]->post_date_gmt );
 
-			$page_list[$i]->dateCreated = new IXR_Date($post_date);
-			$page_list[$i]->date_created_gmt = new IXR_Date($post_date_gmt);
-
 			// For drafts use the GMT version of the date
-			if ( $page_list[$i]->post_status == 'draft' ) {
-				$page_list[$i]->date_created_gmt = get_gmt_from_date( mysql2date( 'Y-m-d H:i:s', $page_list[$i]->post_date ), 'Ymd\TH:i:s' );
-				$page_list[$i]->date_created_gmt = new IXR_Date( $page_list[$i]->date_created_gmt );
+			if ( in_array( $page_list[$i]->post_status, array( 'draft', 'pending', 'auto-draft' ) ) ) {
+				$page_list[$i]->date_created_gmt = $this->_convert_date_gmt( $page_list[$i]->post_date );
 			}
 
 			unset($page_list[$i]->post_date_gmt);
@@ -1658,8 +1704,8 @@
 			return new IXR_Error( 404, __( 'Invalid comment ID.' ) );
 
 		// Format page date.
-		$comment_date = mysql2date('Ymd\TH:i:s', $comment->comment_date, false);
-		$comment_date_gmt = mysql2date('Ymd\TH:i:s', $comment->comment_date_gmt, false);
+		$comment_date = $this->_convert_date( $comment->comment_date );
+		$comment_date_gmt = $this->_convert_date( $comment->comment_date_gmt );
 
 		if ( '0' == $comment->comment_approved )
 			$comment_status = 'hold';
@@ -1673,7 +1719,7 @@
 		$link = get_comment_link($comment);
 
 		$comment_struct = array(
-			'date_created_gmt'		=> new IXR_Date($comment_date_gmt),
+			'date_created_gmt'		=> $comment_date_gmt,
 			'user_id'				=> $comment->user_id,
 			'comment_id'			=> $comment->comment_ID,
 			'parent'				=> $comment->comment_parent,
@@ -2241,14 +2287,14 @@
 			return new IXR_Error( 404, __( 'Invalid attachment ID.' ) );
 
 		// Format page date.
-		$attachment_date = mysql2date('Ymd\TH:i:s', $attachment->post_date, false);
-		$attachment_date_gmt = mysql2date('Ymd\TH:i:s', $attachment->post_date_gmt, false);
+		$attachment_date = $this->_convert_date( $attachment->post_date );
+		$attachment_date_gmt = $this->_convert_date( $attachment->post_date_gmt );
 
 		$link = wp_get_attachment_url($attachment->ID);
 		$thumbnail_link = wp_get_attachment_thumb_url($attachment->ID);
 
 		$attachment_struct = array(
-			'date_created_gmt'		=> new IXR_Date($attachment_date_gmt),
+			'date_created_gmt'		=> $attachment_date_gmt,
 			'parent'				=> $attachment->post_parent,
 			'link'					=> $link,
 			'thumbnail'				=> $thumbnail_link,
@@ -2503,7 +2549,7 @@
 
 		$struct = array(
 			'userid'    => $post_data['post_author'],
-			'dateCreated' => new IXR_Date(mysql2date('Ymd\TH:i:s', $post_data['post_date'], false)),
+			'dateCreated' => $this->_convert_date( $post_data['post_date'] ),
 			'content'     => $content,
 			'postid'  => (string) $post_data['ID']
 		);
@@ -2548,7 +2594,7 @@
 			if ( !current_user_can( 'edit_post', $entry['ID'] ) )
 				continue;
 
-			$post_date = mysql2date('Ymd\TH:i:s', $entry['post_date'], false);
+			$post_date  = $this->_convert_date( $entry['post_date'] );
 			$categories = implode(',', wp_get_post_categories($entry['ID']));
 
 			$content  = '<title>'.stripslashes($entry['post_title']).'</title>';
@@ -2557,7 +2603,7 @@
 
 			$struct[] = array(
 				'userid' => $entry['post_author'],
-				'dateCreated' => new IXR_Date($post_date),
+				'dateCreated' => $post_date,
 				'content' => $content,
 				'postid' => (string) $entry['ID'],
 			);
@@ -2816,6 +2862,7 @@
 	 *  - wp_page_parent_id
 	 *  - wp_page_order
 	 *  - wp_author_id
+	 *  - wp_featured_image
 	 *  - post_status | page_status - can be 'draft', 'private', 'publish', or 'pending'
 	 *  - mt_allow_comments - can be 'open' or 'closed'
 	 *  - mt_allow_pings - can be 'open' or 'closed'
@@ -3067,6 +3114,18 @@
 		if ( isset($content_struct['custom_fields']) )
 			$this->set_custom_fields($post_ID, $content_struct['custom_fields']);
 
+		if ( isset ( $post_data['wp_featured_image'] ) ) {
+			if( current_theme_supports( 'post-thumbnails' ) && ! empty( $post_data['wp_featured_image'] ) ) {
+				if ( set_post_thumbnail( $post_ID, $post_data['wp_featured_image'] ) === false )
+					return new IXR_Error( 404, __( 'Invalid attachment ID.' ) );
+
+				unset( $content_struct['wp_featured_image'] );
+			}
+			else {
+				return new IXR_Error( 401, __( 'Sorry, you are not able to set a post thumbnail.' ) );
+			}
+		}
+
 		// Handle enclosures
 		$thisEnclosure = isset($content_struct['enclosure']) ? $content_struct['enclosure'] : null;
 		$this->add_enclosure_if_new($post_ID, $thisEnclosure);
@@ -3365,6 +3424,23 @@
 		if ( isset($content_struct['custom_fields']) )
 			$this->set_custom_fields($post_ID, $content_struct['custom_fields']);
 
+		if ( isset ( $post_data['wp_featured_image'] ) ) {
+			if( current_theme_supports( 'post-thumbnails' ) ) {
+				// empty value deletes, non-empty value adds/updates
+				if ( empty( $post_data['wp_featured_image'] ) ) {
+					delete_post_thumbnail( $post_ID );
+				}
+				else {
+					if ( set_post_thumbnail( $post_ID, $post_data['wp_featured_image'] ) === false )
+						return new IXR_Error( 404, __( 'Invalid attachment ID.' ) );
+				}
+				unset( $content_struct['wp_featured_image'] );
+			}
+			else {
+				return new IXR_Error( 401, __( 'Sorry, you are not able to set a post thumbnail.' ) );
+			}
+		}
+
 		// Handle enclosures
 		$thisEnclosure = isset($content_struct['enclosure']) ? $content_struct['enclosure'] : null;
 		$this->add_enclosure_if_new($post_ID, $thisEnclosure);
@@ -3406,15 +3482,15 @@
 		$postdata = wp_get_single_post($post_ID, ARRAY_A);
 
 		if ($postdata['post_date'] != '') {
-			$post_date = mysql2date('Ymd\TH:i:s', $postdata['post_date'], false);
-			$post_date_gmt = mysql2date('Ymd\TH:i:s', $postdata['post_date_gmt'], false);
-			$post_modified = mysql2date('Ymd\TH:i:s', $postdata['post_modified'], false);
-			$post_modified_gmt = mysql2date('Ymd\TH:i:s', $postdata['post_modified_gmt'], false);
+			$post_date = $this->_convert_date( $postdata['post_date'] );
+			$post_date_gmt = $this->_convert_date( $postdata['post_date_gmt'] );
+			$post_modified = $this->_convert_date( $postdata['post_modified'] );
+			$post_modified_gmt = $this->_convert_date( $postdata['post_modified_gmt'] );
 
 			// For drafts use the GMT version of the post date
 			if ( $postdata['post_status'] == 'draft' ) {
-				$post_date_gmt = get_gmt_from_date( mysql2date( 'Y-m-d H:i:s', $postdata['post_date'] ), 'Ymd\TH:i:s' );
-				$post_modified_gmt = get_gmt_from_date( mysql2date( 'Y-m-d H:i:s', $postdata['post_modified'] ), 'Ymd\TH:i:s' );
+				$post_date_gmt = $this->_convert_date_gmt( $postdata['post_date'] );
+				$post_modified_gmt = $this->_convert_date_gmt( $postdata['post_modified'] );
 			}
 
 			$categories = array();
@@ -3468,7 +3544,7 @@
 			}
 
 			$resp = array(
-				'dateCreated' => new IXR_Date($post_date),
+				'dateCreated' => $post_date,
 				'userid' => $postdata['post_author'],
 				'postid' => $postdata['ID'],
 				'description' => $post['main'],
@@ -3486,18 +3562,22 @@
 				'wp_slug' => $postdata['post_name'],
 				'wp_password' => $postdata['post_password'],
 				'wp_author_id' => (string) $author->ID,
-				'wp_author_display_name'	=> $author->display_name,
-				'date_created_gmt' => new IXR_Date($post_date_gmt),
+				'wp_author_display_name' => $author->display_name,
+				'date_created_gmt' => $post_date_gmt,
 				'post_status' => $postdata['post_status'],
 				'custom_fields' => $this->get_custom_fields($post_ID),
 				'wp_post_format' => $post_format,
 				'sticky' => $sticky,
-				'date_modified' => new IXR_Date( $post_modified ),
-				'date_modified_gmt' => new IXR_Date( $post_modified_gmt )
+				'date_modified' => $post_modified,
+				'date_modified_gmt' => $post_modified_gmt
 			);
 
 			if ( !empty($enclosure) ) $resp['enclosure'] = $enclosure;
 
+			if( current_theme_supports( 'post-thumbnails' ) ) {
+				$resp['wp_featured_image'] = get_post_thumbnail_id( $postdata['ID'] );
+			}
+
 			return $resp;
 		} else {
 			return new IXR_Error(404, __('Sorry, no such post.'));
@@ -3538,15 +3618,15 @@
 			if ( !current_user_can( 'edit_post', $entry['ID'] ) )
 				continue;
 
-			$post_date = mysql2date('Ymd\TH:i:s', $entry['post_date'], false);
-			$post_date_gmt = mysql2date('Ymd\TH:i:s', $entry['post_date_gmt'], false);
-			$post_modified = mysql2date('Ymd\TH:i:s', $entry['post_modified'], false);
-			$post_modified_gmt = mysql2date('Ymd\TH:i:s', $entry['post_modified_gmt'], false);
+			$post_date = $this->_convert_date( $entry['post_date'] );
+			$post_date_gmt = $this->_convert_date( $entry['post_date_gmt'] );
+			$post_modified = $this->_convert_date( $entry['post_modified'] );
+			$post_modified_gmt = $this->_convert_date( $entry['post_modified_gmt'] );
 
 			// For drafts use the GMT version of the date
 			if ( $entry['post_status'] == 'draft' ) {
-				$post_date_gmt = get_gmt_from_date( mysql2date( 'Y-m-d H:i:s', $entry['post_date'] ), 'Ymd\TH:i:s' );
-				$post_modified_gmt = get_gmt_from_date( mysql2date( 'Y-m-d H:i:s', $entry['post_modified'] ), 'Ymd\TH:i:s' );
+				$post_date_gmt = $this->_convert_date_gmt( $entry['post_date'] );
+				$post_modified_gmt = $this->_convert_date_gmt( $entry['post_modified'] );
 			}
 
 			$categories = array();
@@ -3584,7 +3664,7 @@
 				$post_format = 'standard';
 
 			$struct[] = array(
-				'dateCreated' => new IXR_Date($post_date),
+				'dateCreated' => $post_date,
 				'userid' => $entry['post_author'],
 				'postid' => (string) $entry['ID'],
 				'description' => $post['main'],
@@ -3603,14 +3683,18 @@
 				'wp_password' => $entry['post_password'],
 				'wp_author_id' => (string) $author->ID,
 				'wp_author_display_name' => $author->display_name,
-				'date_created_gmt' => new IXR_Date($post_date_gmt),
+				'date_created_gmt' => $post_date_gmt,
 				'post_status' => $entry['post_status'],
 				'custom_fields' => $this->get_custom_fields($entry['ID']),
 				'wp_post_format' => $post_format,
-				'date_modified' => new IXR_Date( $post_modified ),
-				'date_modified_gmt' => new IXR_Date( $post_modified_gmt )
+				'date_modified' => $post_modified,
+				'date_modified_gmt' => $post_modified_gmt
 			);
 
+			$entry_index = count( $struct ) - 1;
+			if( current_theme_supports( 'post-thumbnails' ) ) {
+				$struct[ $entry_index ][ 'wp_featured_image' ] = get_post_thumbnail_id( $entry['ID'] );
+			}
 		}
 
 		$recent_posts = array();
@@ -3783,20 +3867,20 @@
 			if ( !current_user_can( 'edit_post', $entry['ID'] ) )
 				continue;
 
-			$post_date = mysql2date('Ymd\TH:i:s', $entry['post_date'], false);
-			$post_date_gmt = mysql2date('Ymd\TH:i:s', $entry['post_date_gmt'], false);
+			$post_date = $this->_convert_date( $entry['post_date'] );
+			$post_date_gmt = $this->_convert_date( $entry['post_date_gmt'] );
 
 			// For drafts use the GMT version of the date
-			if ( $entry['post_status'] == 'draft' )
-				$post_date_gmt = get_gmt_from_date( mysql2date( 'Y-m-d H:i:s', $entry['post_date'] ), 'Ymd\TH:i:s' );
+			if ( in_array( $entry['post_status'], array( 'draft', 'pending', 'auto-draft' ) ) )
+				$post_date_gmt = $this->_convert_date_gmt( $entry['post_date'] );
 
 			$struct[] = array(
-				'dateCreated' => new IXR_Date($post_date),
+				'dateCreated' => $post_date,
 				'userid' => $entry['post_author'],
 				'postid' => (string) $entry['ID'],
 				'title' => $entry['post_title'],
 				'post_status' => $entry['post_status'],
-				'date_created_gmt' => new IXR_Date($post_date_gmt)
+				'date_created_gmt' => $post_date_gmt
 			);
 
 		}
