Index: wp-admin/includes/user.php
===================================================================
--- wp-admin/includes/user.php	(revision 42839)
+++ wp-admin/includes/user.php	(working copy)
@@ -626,10 +626,12 @@
 	}
 
 	update_post_meta( $request_id, '_wp_user_request_confirmed_timestamp', time() );
+
 	$request = wp_update_post( array(
-		'ID'          => $request_data['request_id'],
+		'ID'          => $request_id,
 		'post_status' => 'request-confirmed',
 	) );
+
 	return $request;
 }
 
@@ -772,6 +774,38 @@
 }
 
 /**
+ * Cleans up failed and expired requests before displaying the list table.
+ *
+ * @since 4.9.6
+ * @access private
+ */
+function _wp_personal_data_cleanup_requests() {
+	$expires        = (int) apply_filters( 'user_request_key_expiration', DAY_IN_SECONDS );
+	$requests_query = new WP_Query( array(
+		'post_type'      => 'user_request',
+		'posts_per_page' => -1,
+		'post_status'    => 'request-pending',
+		'fields'         => 'ids',
+		'date_query' => array(
+			array(
+				'column' => 'post_modified_gmt',
+				'before' => $expires . ' seconds ago',
+			),
+		),
+	) );
+
+	$request_ids = $requests_query->posts;
+
+	foreach ( $request_ids as $request_id ) {
+		wp_update_post( array(
+			'ID'            => $request_id,
+			'post_status'   => 'request-failed',
+			'post_password' => '',
+		) );
+	}
+}
+
+/**
  * Personal data export.
  *
  * @since 4.9.6
@@ -783,6 +817,7 @@
 	}
 
 	_wp_personal_data_handle_actions();
+	_wp_personal_data_cleanup_requests();
 
 	$requests_table = new WP_Privacy_Data_Export_Requests_Table( array(
 		'plural'   => 'privacy_requests',
@@ -844,6 +879,7 @@
 	}
 
 	_wp_personal_data_handle_actions();
+	_wp_personal_data_cleanup_requests();
 
 	// "Borrow" xfn.js for now so we don't have to create new files.
 	wp_enqueue_script( 'xfn' );
@@ -882,7 +918,7 @@
 
 		<form class="search-form wp-clearfix">
 			<?php $requests_table->search_box( __( 'Search Requests' ), 'requests' ); ?>
-			<input type="hidden" name="page" value="export_personal_data" />
+			<input type="hidden" name="page" value="remove_personal_data" />
 			<input type="hidden" name="filter-status" value="<?php echo isset( $_REQUEST['filter-status'] ) ? esc_attr( sanitize_text_field( $_REQUEST['filter-status'] ) ) : ''; ?>" />
 			<input type="hidden" name="orderby" value="<?php echo isset( $_REQUEST['orderby'] ) ? esc_attr( sanitize_text_field( $_REQUEST['orderby'] ) ) : ''; ?>" />
 			<input type="hidden" name="order" value="<?php echo isset( $_REQUEST['order'] ) ? esc_attr( sanitize_text_field( $_REQUEST['order'] ) ) : ''; ?>" />
@@ -948,11 +984,11 @@
 	 */
 	public function get_columns() {
 		$columns = array(
-			'cb'                  => '<input type="checkbox" />',
-			'email'               => __( 'Requester' ),
-			'status'              => __( 'Status' ),
-			'requested_timestamp' => __( 'Requested' ),
-			'next_steps'          => __( 'Next Steps' ),
+			'cb'                => '<input type="checkbox" />',
+			'email'             => __( 'Requester' ),
+			'status'            => __( 'Status' ),
+			'created_timestamp' => __( 'Requested' ),
+			'next_steps'        => __( 'Next Steps' ),
 		);
 		return $columns;
 	}
@@ -1000,7 +1036,7 @@
 			SELECT post_status, COUNT( * ) AS num_posts 
 			FROM {$wpdb->posts} 
 			WHERE post_type = %s
-			AND post_title = %s
+			AND post_name = %s
 			GROUP BY post_status";
 
 		$results = (array) $wpdb->get_results( $wpdb->prepare( $query, $this->post_type, $this->request_type ), ARRAY_A );
@@ -1088,7 +1124,7 @@
 			case 'resend':
 				foreach ( $request_ids as $request_id ) {
 					$resend = _wp_privacy_resend_request( $request_id );
-					
+
 					if ( $resend && ! is_wp_error( $resend ) ) {
 						$count++;
 					}
@@ -1124,10 +1160,11 @@
 		$posts_per_page = 20;
 		$args           = array(
 			'post_type'      => $this->post_type,
-			'title'          => $this->request_type,
+			'post_name__in'  => array( $this->request_type ),
 			'posts_per_page' => $posts_per_page,
 			'offset'         => isset( $_REQUEST['paged'] ) ? max( 0, absint( $_REQUEST['paged'] ) - 1 ) * $posts_per_page: 0,
 			'post_status'    => 'any',
+			's'              => isset( $_REQUEST['s'] ) ? sanitize_text_field( $_REQUEST['s'] ) : '',
 		);
 
 		if ( ! empty( $_REQUEST['filter-status'] ) ) {
@@ -1135,18 +1172,6 @@
 			$args['post_status'] = $filter_status;
 		}
 
-		if ( ! empty( $_REQUEST['s'] ) ) {
-			$args['meta_query'] = array(
-				$name_query,
-				'relation'  => 'AND',
-				array(
-					'key'     => '_wp_user_request_user_email',
-					'value'   => isset( $_REQUEST['s'] ) ? sanitize_text_field( $_REQUEST['s'] ): '',
-					'compare' => 'LIKE',
-				),
-			);
-		}
-
 		$requests_query = new WP_Query( $args );
 		$requests       = $requests_query->posts;
 
@@ -1154,6 +1179,8 @@
 			$this->items[] = wp_get_user_request_data( $request->ID );
 		}
 
+		$this->items = array_filter( $this->items );
+
 		$this->set_pagination_args(
 			array(
 				'total_items' => $requests_query->found_posts,
@@ -1167,11 +1194,11 @@
 	 *
 	 * @since 4.9.6
 	 *
-	 * @param array $item Item being shown.
+	 * @param WP_User_Request $item Item being shown.
 	 * @return string
 	 */
 	public function column_cb( $item ) {
-		return sprintf( '<input type="checkbox" name="request_id[]" value="%1$s" /><span class="spinner"></span>', esc_attr( $item['request_id'] ) );
+		return sprintf( '<input type="checkbox" name="request_id[]" value="%1$s" /><span class="spinner"></span>', esc_attr( $item->ID ) );
 	}
 
 	/**
@@ -1179,11 +1206,11 @@
 	 *
 	 * @since 4.9.6
 	 *
-	 * @param array $item Item being shown.
+	 * @param WP_User_Request $item Item being shown.
 	 * @return string
 	 */
 	public function column_status( $item ) {
-		$status        = get_post_status( $item['request_id'] );
+		$status        = get_post_status( $item->ID );
 		$status_object = get_post_status_object( $status );
 
 		if ( ! $status_object || empty( $status_object->label ) ) {
@@ -1194,10 +1221,10 @@
 
 		switch ( $status ) {
 			case 'request-confirmed':
-				$timestamp = $item['confirmed_timestamp'];
+				$timestamp = $item->confirmed_timestamp;
 				break;
 			case 'request-completed':
-				$timestamp = $item['completed_timestamp'];
+				$timestamp = $item->completed_timestamp;
 				break;
 		}
 
@@ -1238,14 +1265,14 @@
 	 *
 	 * @since 4.9.6
 	 *
-	 * @param array $item         Item being shown.
-	 * @param string $column_name Name of column being shown.
+	 * @param WP_User_Request $item         Item being shown.
+	 * @param string          $column_name Name of column being shown.
 	 * @return string
 	 */
 	public function column_default( $item, $column_name ) {
-		$cell_value = $item[ $column_name ];
+		$cell_value = $item->$column_name;
 
-		if ( in_array( $column_name, array( 'requested_timestamp' ), true ) ) {
+		if ( in_array( $column_name, array( 'created_timestamp' ), true ) ) {
 			return $this->get_timestamp_as_date( $cell_value );
 		}
 
@@ -1257,11 +1284,11 @@
 	 *
 	 * @since 4.9.6
 	 *
-	 * @param array $item Item being shown.
+	 * @param WP_User_Request $item Item being shown.
 	 * @return string
 	 */
 	public function column_email( $item ) {
-		return sprintf( '%1$s %2$s', $item['email'], $this->row_actions( array() ) );
+		return sprintf( '%1$s %2$s', $item->email, $this->row_actions( array() ) );
 	}
 
 	/**
@@ -1269,7 +1296,7 @@
 	 *
 	 * @since 4.9.6
 	 *
-	 * @param array $item Item being shown.
+	 * @param WP_User_Request $item Item being shown.
 	 */
 	public function column_next_steps( $item ) {}
 
@@ -1278,10 +1305,10 @@
 	 *
 	 * @since 4.9.6
 	 *
-	 * @param object $item The current item
+	 * @param WP_User_Request $item The current item
 	 */
 	public function single_row( $item ) {
-		$status = get_post_status( $item['request_id'] );
+		$status = $item->status;
 
 		echo '<tr class="status-' . esc_attr( $status ) . '">';
 		$this->single_row_columns( $item );
@@ -1325,13 +1352,13 @@
 	 *
 	 * @since 4.9.6
 	 *
-	 * @param array $item Item being shown.
+	 * @param WP_User_Request $item Item being shown.
 	 * @return string
 	 */
 	public function column_email( $item ) {
 		$exporters       = apply_filters( 'wp_privacy_personal_data_exporters', array() );
 		$exporters_count = count( $exporters );
-		$request_id      = $item['request_id'];
+		$request_id      = $item->ID;
 		$nonce           = wp_create_nonce( 'wp-privacy-export-personal-data-' . $request_id );
 
 		$download_data_markup = '<div class="download_personal_data" ' .
@@ -1348,7 +1375,7 @@
 			'download_data' => $download_data_markup,
 		);
 
-		return sprintf( '%1$s %2$s', $item['email'], $this->row_actions( $row_actions ) );
+		return sprintf( '%1$s %2$s', $item->email, $this->row_actions( $row_actions ) );
 	}
 
 	/**
@@ -1356,10 +1383,10 @@
 	 *
 	 * @since 4.9.6
 	 *
-	 * @param array $item Item being shown.
+	 * @param WP_User_Request $item Item being shown.
 	 */
 	public function column_next_steps( $item ) {
-		$status = get_post_status( $item['request_id'] );
+		$status = $item->status;
 
 		switch ( $status ) {
 			case 'request-pending':
@@ -1369,12 +1396,12 @@
 				// TODO Complete in follow on patch.
 				break;
 			case 'request-failed':
-				submit_button( __( 'Retry' ), 'secondary', 'privacy_action_email_retry[' . $item['request_id'] . ']', false );
+				submit_button( __( 'Retry' ), 'secondary', 'privacy_action_email_retry[' . $item->ID . ']', false );
 				break;
 			case 'request-completed':
 				echo '<a href="' . esc_url( wp_nonce_url( add_query_arg( array(
 					'action' => 'delete',
-					'request_id' => array( $item['request_id'] )
+					'request_id' => array( $item->ID )
 				), admin_url( 'tools.php?page=export_personal_data' ) ), 'bulk-privacy_requests' ) ) . '">' . esc_html__( 'Remove request' ) . '</a>';
 				break;
 		}
@@ -1410,18 +1437,18 @@
 	 *
 	 * @since 4.9.6
 	 *
-	 * @param array $item Item being shown.
+	 * @param WP_User_Request $item Item being shown.
 	 * @return string
 	 */
 	public function column_email( $item ) {
 		$row_actions = array();
 
-		// Allow the administrator to "force remove" the personal data even if confirmation has not yet been received
-		$status = get_post_status( $item['request_id'] );
+		// Allow the administrator to "force remove" the personal data even if confirmation has not yet been received.
+		$status = $item->status;
 		if ( 'request-confirmed' !== $status ) {
 			$erasers       = apply_filters( 'wp_privacy_personal_data_erasers', array() );
 			$erasers_count = count( $erasers );
-			$request_id    = $item['request_id'];
+			$request_id    = $item->ID;
 			$nonce         = wp_create_nonce( 'wp-privacy-erase-personal-data-' . $request_id );
 
 			$remove_data_markup = '<div class="remove_personal_data force_remove_personal_data" ' .
@@ -1439,7 +1466,7 @@
 			);
 		}
 
-		return sprintf( '%1$s %2$s', $item['email'], $this->row_actions( $row_actions ) );
+		return sprintf( '%1$s %2$s', $item->email, $this->row_actions( $row_actions ) );
 	}
 
 	/**
@@ -1447,10 +1474,10 @@
 	 *
 	 * @since 4.9.6
 	 *
-	 * @param array $item Item being shown.
+	 * @param WP_User_Request $item Item being shown.
 	 */
 	public function column_next_steps( $item ) {
-		$status = get_post_status( $item['request_id'] );
+		$status = $item->status;
 
 		switch ( $status ) {
 			case 'request-pending':
@@ -1459,7 +1486,7 @@
 			case 'request-confirmed':
 				$erasers       = apply_filters( 'wp_privacy_personal_data_erasers', array() );
 				$erasers_count = count( $erasers );
-				$request_id    = $item['request_id'];
+				$request_id    = $item->ID;
 				$nonce         = wp_create_nonce( 'wp-privacy-erase-personal-data-' . $request_id );
 
 				echo '<div class="remove_personal_data" ' .
@@ -1477,12 +1504,12 @@
 
 				break;
 			case 'request-failed':
-				submit_button( __( 'Retry' ), 'secondary', 'privacy_action_email_retry[' . $item['request_id'] . ']', false );
+				submit_button( __( 'Retry' ), 'secondary', 'privacy_action_email_retry[' . $item->ID . ']', false );
 				break;
 			case 'request-completed':
 				echo '<a href="' . esc_url( wp_nonce_url( add_query_arg( array(
 					'action' => 'delete',
-					'request_id' => array( $item['request_id'] ),
+					'request_id' => array( $item->ID ),
 				), admin_url( 'tools.php?page=remove_personal_data' ) ), 'bulk-privacy_requests' ) ) . '">' . esc_html__( 'Remove request' ) . '</a>';
 				break;
 		}
Index: wp-content/plugins
===================================================================
--- wp-content/plugins	(revision 42839)
+++ wp-content/plugins	(working copy)

Property changes on: wp-content/plugins
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,6 ##
+order-simulator-woocommerce-master
+query-monitor
+woocommerce
+wp-cron-control
+woocommerce-product-type-column
+wp-mail-smtp
Index: wp-content
===================================================================
--- wp-content	(revision 42839)
+++ wp-content	(working copy)

Property changes on: wp-content
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,4 ##
+uploads
+upgrade
+debug.log
+db.php
Index: wp-includes/post.php
===================================================================
--- wp-includes/post.php	(revision 42839)
+++ wp-includes/post.php	(working copy)
@@ -3980,7 +3980,7 @@
  * @return string Unique slug for the post, based on $post_name (with a -1, -2, etc. suffix)
  */
 function wp_unique_post_slug( $slug, $post_ID, $post_status, $post_type, $post_parent ) {
-	if ( in_array( $post_status, array( 'draft', 'pending', 'auto-draft' ) ) || ( 'inherit' == $post_status && 'revision' == $post_type ) ) {
+	if ( in_array( $post_status, array( 'draft', 'pending', 'auto-draft' ) ) || ( 'inherit' == $post_status && 'revision' == $post_type ) || 'user_request' === $post_type ) {
 		return $slug;
 	}
 
Index: wp-includes/user.php
===================================================================
--- wp-includes/user.php	(revision 42839)
+++ wp-includes/user.php	(working copy)
@@ -2840,13 +2840,13 @@
 		return;
 	}
 
-	if ( ! in_array( $request_data['status'], array( 'request-pending', 'request-failed' ), true ) ) {
+	if ( ! in_array( $request_data->status, array( 'request-pending', 'request-failed' ), true ) ) {
 		return;
 	}
 
 	update_post_meta( $request_id, '_wp_user_request_confirmed_timestamp', time() );
 	wp_update_post( array(
-		'ID'          => $request_data['request_id'],
+		'ID'          => $request_id,
 		'post_status' => 'request-confirmed',
 	) );
 }
@@ -2862,7 +2862,7 @@
 function _wp_privacy_account_request_confirmed_message( $message, $request_id ) {
 	$request = wp_get_user_request_data( $request_id );
 
-	if ( $request && in_array( $request['action'], _wp_privacy_action_request_types(), true ) ) {
+	if ( $request && in_array( $request->action_name, _wp_privacy_action_request_types(), true ) ) {
 		$message = '<p class="message">' . __( 'Action has been confirmed.' ) . '</p>';
 		$message .= __( 'The site administrator has been notified and will fulfill your request as soon as possible.' );
 	}
@@ -2900,16 +2900,11 @@
 
 	// Check for duplicates.
 	$requests_query = new WP_Query( array(
-		'post_type'   => 'user_request',
-		'title'       => $action_name,
-		'post_status' => 'any',
-		'fields'      => 'ids',
-		'meta_query'  => array(
-			array(
-				'key'     => '_wp_user_request_user_email',
-				'value'   => $email_address,
-			),
-		),
+		'post_type'     => 'user_request',
+		'post_name__in' => array( $action_name ),  // Action name stored in post_name column.
+		'title'         => $email_address, // Email address stored in post_title column.
+		'post_status'   => 'any',
+		'fields'        => 'ids',
 	) );
 
 	if ( $requests_query->found_posts ) {
@@ -2918,7 +2913,8 @@
 
 	$request_id = wp_insert_post( array(
 		'post_author'   => $user_id,
-		'post_title'    => $action_name,
+		'post_name'     => $action_name,
+		'post_title'    => $email_address,
 		'post_content'  => wp_json_encode( $request_data ),
 		'post_status'   => 'request-pending',
 		'post_type'     => 'user_request',
@@ -2926,13 +2922,6 @@
 		'post_date_gmt' => current_time( 'mysql', true ),
 	), true );
 
-	if ( is_wp_error( $request_id ) ) {
-		return $request_id;
-	}
-
-	update_post_meta( $request_id, '_wp_user_request_user_email', $email_address );
-	update_post_meta( $request_id, '_wp_user_request_confirmed_timestamp', false );
-
 	return $request_id;
 }
 
@@ -2963,7 +2952,7 @@
 	 *
 	 * @param string $description The default description.
 	 * @param string $action_name The name of the request.
-	 */	 	 	 	
+	 */
 	return apply_filters( 'user_request_action_description', $description, $action_name );
 }
 
@@ -2979,25 +2968,15 @@
  */
 function wp_send_user_request( $request_id ) {
 	$request_id = absint( $request_id );
-	$request    = get_post( $request_id );
+	$request    = wp_get_user_request_data( $request_id );
 
-	if ( ! $request || 'user_request' !== $request->post_type ) {
+	if ( ! $request ) {
 		return new WP_Error( 'user_request_error', __( 'Invalid request.' ) );
 	}
 
-	if ( 'request-pending' !== $request->post_status ) {
-		wp_update_post( array(
-			'ID'            => $request_id,
-			'post_status'   => 'request-pending',
-			'post_date'     => current_time( 'mysql', false ),
-			'post_date_gmt' => current_time( 'mysql', true ),
-		) );
-	}
-
 	$email_data = array(
-		'action_name' => $request->post_title,
-		'email'       => get_post_meta( $request->ID, '_wp_user_request_user_email', true ),
-		'description' => wp_user_request_action_description( $request->post_title ),
+		'email'       => $request->email,
+		'description' => wp_user_request_action_description( $request->action_name ),
 		'confirm_url' => add_query_arg( array(
 			'action'      => 'confirmaction',
 			'request_id'  => $request_id,
@@ -3045,12 +3024,12 @@
 	 * @param array  $email_data {
 	 *     Data relating to the account action email.
 	 *
-	 *     @type string $action_name Name of the action being performed.
-	 *     @type string $email       The email address this is being sent to.
-	 *     @type string $description Description of the action being performed so the user knows what the email is for.
-	 *     @type string $confirm_url The link to click on to confirm the account action.
-	 *     @type string $sitename    The site name sending the mail.
-	 *     @type string $siteurl     The site URL sending the mail.
+	 *     @type WP_User_Request $request User request object.
+	 *     @type string          $email       The email address this is being sent to.
+	 *     @type string          $description Description of the action being performed so the user knows what the email is for.
+	 *     @type string          $confirm_url The link to click on to confirm the account action.
+	 *     @type string          $sitename    The site name sending the mail.
+	 *     @type string          $siteurl     The site URL sending the mail.
 	 * }
 	 */
 	$content = apply_filters( 'user_request_action_email_content', $email_text, $email_data );
@@ -3066,7 +3045,7 @@
 }
 
 /**
- * Returns a confirmation key for a user action and stores the hashed version.
+ * Returns a confirmation key for a user action and stores the hashed version for future comparison.
  *
  * @since 4.9.6
  *
@@ -3085,8 +3064,13 @@
 		$wp_hasher = new PasswordHash( 8, true );
 	}
 
-	update_post_meta( $request_id, '_wp_user_request_confirm_key', $wp_hasher->HashPassword( $key ) );
-	update_post_meta( $request_id, '_wp_user_request_confirm_key_timestamp', time() );
+	wp_update_post( array(
+		'ID'                => $request_id,
+		'post_status'       => 'request-pending',
+		'post_password'     => $wp_hasher->HashPassword( $key ),
+		'post_modified'     => current_time( 'mysql', false ),
+		'post_modified_gmt' => current_time( 'mysql', true ),
+	) );
 
 	return $key;
 }
@@ -3110,7 +3094,7 @@
 		return new WP_Error( 'user_request_error', __( 'Invalid request.' ) );
 	}
 
-	if ( ! in_array( $request['status'], array( 'request-pending', 'request-failed' ), true ) ) {
+	if ( ! in_array( $request->status, array( 'request-pending', 'request-failed' ), true ) ) {
 		return __( 'This link has expired.' );
 	}
 
@@ -3123,8 +3107,8 @@
 		$wp_hasher = new PasswordHash( 8, true );
 	}
 
-	$key_request_time = $request['confirm_key_timestamp'];
-	$saved_key        = $request['confirm_key'];
+	$key_request_time = $request->modified_timestamp;
+	$saved_key        = $request->confirm_key;
 
 	if ( ! $saved_key ) {
 		return new WP_Error( 'invalid_key', __( 'Invalid key' ) );
@@ -3165,23 +3149,119 @@
  */
 function wp_get_user_request_data( $request_id ) {
 	$request_id = absint( $request_id );
-	$request    = get_post( $request_id );
+	$post       = get_post( $request_id );
 
-	if ( ! $request || 'user_request' !== $request->post_type ) {
+	if ( ! $post || 'user_request' !== $post->post_type ) {
 		return false;
 	}
 
-	return array(
-		'request_id'            => $request->ID,
-		'user_id'               => $request->post_author,
-		'email'                 => get_post_meta( $request->ID, '_wp_user_request_user_email', true ),
-		'action'                => $request->post_title,
-		'requested_timestamp'   => strtotime( $request->post_date_gmt ),
-		'confirmed_timestamp'   => get_post_meta( $request->ID, '_wp_user_request_confirmed_timestamp', true ),
-		'completed_timestamp'   => get_post_meta( $request->ID, '_wp_user_request_completed_timestamp', true ),
-		'request_data'          => json_decode( $request->post_content, true ),
-		'status'                => $request->post_status,
-		'confirm_key'           => get_post_meta( $request_id, '_wp_user_request_confirm_key', true ),
-		'confirm_key_timestamp' => get_post_meta( $request_id, '_wp_user_request_confirm_key_timestamp', true ),
-	);
+	return new WP_User_Request( $post );
 }
+
+/**
+ * WP_User_Request class.
+ *
+ * Represents user request data loaded from a WP_Post object.
+ *
+ * @since 4.9.6
+ */
+class WP_User_Request {
+	/**
+	 * Request ID.
+	 *
+	 * @var int
+	 */
+	public $ID = 0;
+
+	/**
+	 * User ID.
+	 *
+	 * @var int
+	 */
+
+	public $user_id = 0;
+
+	/**
+	 * User email.
+	 *
+	 * @var int
+	 */
+	public $email = '';
+
+	/**
+	 * Action name.
+	 *
+	 * @var string
+	 */
+	public $action_name = '';
+
+	/**
+	 * Current status.
+	 *
+	 * @var string
+	 */
+	public $status = '';
+
+	/**
+	 * Timestamp this request was created.
+	 *
+	 * @var int|null
+	 */
+	public $created_timestamp = null;
+
+	/**
+	 * Timestamp this request was last modified.
+	 *
+	 * @var int|null
+	 */
+	public $modified_timestamp = null;
+
+	/**
+	 * Timestamp this request was confirmed.
+	 *
+	 * @var int
+	 */
+	public $confirmed_timestamp = null;
+
+	/**
+	 * Timestamp this request was completed.
+	 *
+	 * @var int
+	 */
+	public $completed_timestamp = null;
+
+	/**
+	 * Misc data assigned to this request.
+	 *
+	 * @var array
+	 */
+	public $request_data = array();
+
+	/**
+	 * Key used to confirm this request.
+	 *
+	 * @var string
+	 */
+	public $confirm_key = '';
+
+	/**
+	 * Constructor.
+	 *
+	 * @since 3.5.0
+	 *
+	 * @param WP_Post|object $post Post object.
+	 */
+	public function __construct( $post ) {
+		$this->ID                  = $post->ID;
+		$this->user_id             = $post->post_author;
+		$this->email               = $post->post_title;
+		$this->action_name         = $post->post_name;
+		$this->status              = $post->post_status;
+		$this->created_timestamp   = strtotime( $post->post_date_gmt );
+		$this->modified_timestamp  = strtotime( $post->post_modified_gmt );
+		$this->confirmed_timestamp = (int) get_post_meta( $post->ID, '_wp_user_request_confirmed_timestamp', true );
+		$this->completed_timestamp = (int) get_post_meta( $post->ID, '_wp_user_request_completed_timestamp', true );
+		$this->request_data        = json_decode( $post->post_content, true );
+		$this->confirm_key         = $post->post_password;
+	}
+}
\ No newline at end of file
Index: .
===================================================================
--- .	(revision 42839)
+++ .	(working copy)

Property changes on: .
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,2 ##
+.htaccess
+wp-config.php
