wp/wp-admin/includes/post.php
changeset 9 177826044cd9
parent 7 cf61fcea0001
child 16 a86126ab1dd4
equal deleted inserted replaced
8:c7c34916027a 9:177826044cd9
    17  * @param array $post_data Array of post data. Defaults to the contents of $_POST.
    17  * @param array $post_data Array of post data. Defaults to the contents of $_POST.
    18  * @return object|bool WP_Error on failure, true on success.
    18  * @return object|bool WP_Error on failure, true on success.
    19  */
    19  */
    20 function _wp_translate_postdata( $update = false, $post_data = null ) {
    20 function _wp_translate_postdata( $update = false, $post_data = null ) {
    21 
    21 
    22 	if ( empty($post_data) )
    22 	if ( empty( $post_data ) ) {
    23 		$post_data = &$_POST;
    23 		$post_data = &$_POST;
    24 
    24 	}
    25 	if ( $update )
    25 
       
    26 	if ( $update ) {
    26 		$post_data['ID'] = (int) $post_data['post_ID'];
    27 		$post_data['ID'] = (int) $post_data['post_ID'];
       
    28 	}
    27 
    29 
    28 	$ptype = get_post_type_object( $post_data['post_type'] );
    30 	$ptype = get_post_type_object( $post_data['post_type'] );
    29 
    31 
    30 	if ( $update && ! current_user_can( 'edit_post', $post_data['ID'] ) ) {
    32 	if ( $update && ! current_user_can( 'edit_post', $post_data['ID'] ) ) {
    31 		if ( 'page' == $post_data['post_type'] )
    33 		if ( 'page' == $post_data['post_type'] ) {
    32 			return new WP_Error( 'edit_others_pages', __( 'Sorry, you are not allowed to edit pages as this user.' ) );
    34 			return new WP_Error( 'edit_others_pages', __( 'Sorry, you are not allowed to edit pages as this user.' ) );
    33 		else
    35 		} else {
    34 			return new WP_Error( 'edit_others_posts', __( 'Sorry, you are not allowed to edit posts as this user.' ) );
    36 			return new WP_Error( 'edit_others_posts', __( 'Sorry, you are not allowed to edit posts as this user.' ) );
       
    37 		}
    35 	} elseif ( ! $update && ! current_user_can( $ptype->cap->create_posts ) ) {
    38 	} elseif ( ! $update && ! current_user_can( $ptype->cap->create_posts ) ) {
    36 		if ( 'page' == $post_data['post_type'] )
    39 		if ( 'page' == $post_data['post_type'] ) {
    37 			return new WP_Error( 'edit_others_pages', __( 'Sorry, you are not allowed to create pages as this user.' ) );
    40 			return new WP_Error( 'edit_others_pages', __( 'Sorry, you are not allowed to create pages as this user.' ) );
    38 		else
    41 		} else {
    39 			return new WP_Error( 'edit_others_posts', __( 'Sorry, you are not allowed to create posts as this user.' ) );
    42 			return new WP_Error( 'edit_others_posts', __( 'Sorry, you are not allowed to create posts as this user.' ) );
    40 	}
    43 		}
    41 
    44 	}
    42 	if ( isset( $post_data['content'] ) )
    45 
       
    46 	if ( isset( $post_data['content'] ) ) {
    43 		$post_data['post_content'] = $post_data['content'];
    47 		$post_data['post_content'] = $post_data['content'];
    44 
    48 	}
    45 	if ( isset( $post_data['excerpt'] ) )
    49 
       
    50 	if ( isset( $post_data['excerpt'] ) ) {
    46 		$post_data['post_excerpt'] = $post_data['excerpt'];
    51 		$post_data['post_excerpt'] = $post_data['excerpt'];
    47 
    52 	}
    48 	if ( isset( $post_data['parent_id'] ) )
    53 
       
    54 	if ( isset( $post_data['parent_id'] ) ) {
    49 		$post_data['post_parent'] = (int) $post_data['parent_id'];
    55 		$post_data['post_parent'] = (int) $post_data['parent_id'];
    50 
    56 	}
    51 	if ( isset($post_data['trackback_url']) )
    57 
       
    58 	if ( isset( $post_data['trackback_url'] ) ) {
    52 		$post_data['to_ping'] = $post_data['trackback_url'];
    59 		$post_data['to_ping'] = $post_data['trackback_url'];
       
    60 	}
    53 
    61 
    54 	$post_data['user_ID'] = get_current_user_id();
    62 	$post_data['user_ID'] = get_current_user_id();
    55 
    63 
    56 	if (!empty ( $post_data['post_author_override'] ) ) {
    64 	if ( ! empty( $post_data['post_author_override'] ) ) {
    57 		$post_data['post_author'] = (int) $post_data['post_author_override'];
    65 		$post_data['post_author'] = (int) $post_data['post_author_override'];
    58 	} else {
    66 	} else {
    59 		if (!empty ( $post_data['post_author'] ) ) {
    67 		if ( ! empty( $post_data['post_author'] ) ) {
    60 			$post_data['post_author'] = (int) $post_data['post_author'];
    68 			$post_data['post_author'] = (int) $post_data['post_author'];
    61 		} else {
    69 		} else {
    62 			$post_data['post_author'] = (int) $post_data['user_ID'];
    70 			$post_data['post_author'] = (int) $post_data['user_ID'];
    63 		}
    71 		}
    64 	}
    72 	}
    65 
    73 
    66 	if ( isset( $post_data['user_ID'] ) && ( $post_data['post_author'] != $post_data['user_ID'] )
    74 	if ( isset( $post_data['user_ID'] ) && ( $post_data['post_author'] != $post_data['user_ID'] )
    67 		 && ! current_user_can( $ptype->cap->edit_others_posts ) ) {
    75 		&& ! current_user_can( $ptype->cap->edit_others_posts ) ) {
       
    76 
    68 		if ( $update ) {
    77 		if ( $update ) {
    69 			if ( 'page' == $post_data['post_type'] )
    78 			if ( 'page' == $post_data['post_type'] ) {
    70 				return new WP_Error( 'edit_others_pages', __( 'Sorry, you are not allowed to edit pages as this user.' ) );
    79 				return new WP_Error( 'edit_others_pages', __( 'Sorry, you are not allowed to edit pages as this user.' ) );
    71 			else
    80 			} else {
    72 				return new WP_Error( 'edit_others_posts', __( 'Sorry, you are not allowed to edit posts as this user.' ) );
    81 				return new WP_Error( 'edit_others_posts', __( 'Sorry, you are not allowed to edit posts as this user.' ) );
       
    82 			}
    73 		} else {
    83 		} else {
    74 			if ( 'page' == $post_data['post_type'] )
    84 			if ( 'page' == $post_data['post_type'] ) {
    75 				return new WP_Error( 'edit_others_pages', __( 'Sorry, you are not allowed to create pages as this user.' ) );
    85 				return new WP_Error( 'edit_others_pages', __( 'Sorry, you are not allowed to create pages as this user.' ) );
    76 			else
    86 			} else {
    77 				return new WP_Error( 'edit_others_posts', __( 'Sorry, you are not allowed to create posts as this user.' ) );
    87 				return new WP_Error( 'edit_others_posts', __( 'Sorry, you are not allowed to create posts as this user.' ) );
       
    88 			}
    78 		}
    89 		}
    79 	}
    90 	}
    80 
    91 
    81 	if ( ! empty( $post_data['post_status'] ) ) {
    92 	if ( ! empty( $post_data['post_status'] ) ) {
    82 		$post_data['post_status'] = sanitize_key( $post_data['post_status'] );
    93 		$post_data['post_status'] = sanitize_key( $post_data['post_status'] );
    90 			unset( $post_data['post_status'] );
   101 			unset( $post_data['post_status'] );
    91 		}
   102 		}
    92 	}
   103 	}
    93 
   104 
    94 	// What to do based on which button they pressed
   105 	// What to do based on which button they pressed
    95 	if ( isset($post_data['saveasdraft']) && '' != $post_data['saveasdraft'] )
   106 	if ( isset( $post_data['saveasdraft'] ) && '' != $post_data['saveasdraft'] ) {
    96 		$post_data['post_status'] = 'draft';
   107 		$post_data['post_status'] = 'draft';
    97 	if ( isset($post_data['saveasprivate']) && '' != $post_data['saveasprivate'] )
   108 	}
       
   109 	if ( isset( $post_data['saveasprivate'] ) && '' != $post_data['saveasprivate'] ) {
    98 		$post_data['post_status'] = 'private';
   110 		$post_data['post_status'] = 'private';
    99 	if ( isset($post_data['publish']) && ( '' != $post_data['publish'] ) && ( !isset($post_data['post_status']) || $post_data['post_status'] != 'private' ) )
   111 	}
       
   112 	if ( isset( $post_data['publish'] ) && ( '' != $post_data['publish'] ) && ( ! isset( $post_data['post_status'] ) || $post_data['post_status'] != 'private' ) ) {
   100 		$post_data['post_status'] = 'publish';
   113 		$post_data['post_status'] = 'publish';
   101 	if ( isset($post_data['advanced']) && '' != $post_data['advanced'] )
   114 	}
       
   115 	if ( isset( $post_data['advanced'] ) && '' != $post_data['advanced'] ) {
   102 		$post_data['post_status'] = 'draft';
   116 		$post_data['post_status'] = 'draft';
   103 	if ( isset($post_data['pending']) && '' != $post_data['pending'] )
   117 	}
       
   118 	if ( isset( $post_data['pending'] ) && '' != $post_data['pending'] ) {
   104 		$post_data['post_status'] = 'pending';
   119 		$post_data['post_status'] = 'pending';
   105 
   120 	}
   106 	if ( isset( $post_data['ID'] ) )
   121 
       
   122 	if ( isset( $post_data['ID'] ) ) {
   107 		$post_id = $post_data['ID'];
   123 		$post_id = $post_data['ID'];
   108 	else
   124 	} else {
   109 		$post_id = false;
   125 		$post_id = false;
       
   126 	}
   110 	$previous_status = $post_id ? get_post_field( 'post_status', $post_id ) : false;
   127 	$previous_status = $post_id ? get_post_field( 'post_status', $post_id ) : false;
   111 
   128 
   112 	if ( isset( $post_data['post_status'] ) && 'private' == $post_data['post_status'] && ! current_user_can( $ptype->cap->publish_posts ) ) {
   129 	if ( isset( $post_data['post_status'] ) && 'private' == $post_data['post_status'] && ! current_user_can( $ptype->cap->publish_posts ) ) {
   113 		$post_data['post_status'] = $previous_status ? $previous_status : 'pending';
   130 		$post_data['post_status'] = $previous_status ? $previous_status : 'pending';
   114 	}
   131 	}
   115 
   132 
   116 	$published_statuses = array( 'publish', 'future' );
   133 	$published_statuses = array( 'publish', 'future' );
   117 
   134 
   118 	// Posts 'submitted for approval' present are submitted to $_POST the same as if they were being published.
   135 	// Posts 'submitted for approval' present are submitted to $_POST the same as if they were being published.
   119 	// Change status from 'publish' to 'pending' if user lacks permissions to publish or to resave published posts.
   136 	// Change status from 'publish' to 'pending' if user lacks permissions to publish or to resave published posts.
   120 	if ( isset($post_data['post_status']) && (in_array( $post_data['post_status'], $published_statuses ) && !current_user_can( $ptype->cap->publish_posts )) )
   137 	if ( isset( $post_data['post_status'] ) && ( in_array( $post_data['post_status'], $published_statuses ) && ! current_user_can( $ptype->cap->publish_posts ) ) ) {
   121 		if ( ! in_array( $previous_status, $published_statuses ) || !current_user_can( 'edit_post', $post_id ) )
   138 		if ( ! in_array( $previous_status, $published_statuses ) || ! current_user_can( 'edit_post', $post_id ) ) {
   122 			$post_data['post_status'] = 'pending';
   139 			$post_data['post_status'] = 'pending';
       
   140 		}
       
   141 	}
   123 
   142 
   124 	if ( ! isset( $post_data['post_status'] ) ) {
   143 	if ( ! isset( $post_data['post_status'] ) ) {
   125 		$post_data['post_status'] = 'auto-draft' === $previous_status ? 'draft' : $previous_status;
   144 		$post_data['post_status'] = 'auto-draft' === $previous_status ? 'draft' : $previous_status;
   126 	}
   145 	}
   127 
   146 
   128 	if ( isset( $post_data['post_password'] ) && ! current_user_can( $ptype->cap->publish_posts ) ) {
   147 	if ( isset( $post_data['post_password'] ) && ! current_user_can( $ptype->cap->publish_posts ) ) {
   129 		unset( $post_data['post_password'] );
   148 		unset( $post_data['post_password'] );
   130 	}
   149 	}
   131 
   150 
   132 	if (!isset( $post_data['comment_status'] ))
   151 	if ( ! isset( $post_data['comment_status'] ) ) {
   133 		$post_data['comment_status'] = 'closed';
   152 		$post_data['comment_status'] = 'closed';
   134 
   153 	}
   135 	if (!isset( $post_data['ping_status'] ))
   154 
       
   155 	if ( ! isset( $post_data['ping_status'] ) ) {
   136 		$post_data['ping_status'] = 'closed';
   156 		$post_data['ping_status'] = 'closed';
   137 
   157 	}
   138 	foreach ( array('aa', 'mm', 'jj', 'hh', 'mn') as $timeunit ) {
   158 
   139 		if ( !empty( $post_data['hidden_' . $timeunit] ) && $post_data['hidden_' . $timeunit] != $post_data[$timeunit] ) {
   159 	foreach ( array( 'aa', 'mm', 'jj', 'hh', 'mn' ) as $timeunit ) {
       
   160 		if ( ! empty( $post_data[ 'hidden_' . $timeunit ] ) && $post_data[ 'hidden_' . $timeunit ] != $post_data[ $timeunit ] ) {
   140 			$post_data['edit_date'] = '1';
   161 			$post_data['edit_date'] = '1';
   141 			break;
   162 			break;
   142 		}
   163 		}
   143 	}
   164 	}
   144 
   165 
   145 	if ( !empty( $post_data['edit_date'] ) ) {
   166 	if ( ! empty( $post_data['edit_date'] ) ) {
   146 		$aa = $post_data['aa'];
   167 		$aa                     = $post_data['aa'];
   147 		$mm = $post_data['mm'];
   168 		$mm                     = $post_data['mm'];
   148 		$jj = $post_data['jj'];
   169 		$jj                     = $post_data['jj'];
   149 		$hh = $post_data['hh'];
   170 		$hh                     = $post_data['hh'];
   150 		$mn = $post_data['mn'];
   171 		$mn                     = $post_data['mn'];
   151 		$ss = $post_data['ss'];
   172 		$ss                     = $post_data['ss'];
   152 		$aa = ($aa <= 0 ) ? date('Y') : $aa;
   173 		$aa                     = ( $aa <= 0 ) ? date( 'Y' ) : $aa;
   153 		$mm = ($mm <= 0 ) ? date('n') : $mm;
   174 		$mm                     = ( $mm <= 0 ) ? date( 'n' ) : $mm;
   154 		$jj = ($jj > 31 ) ? 31 : $jj;
   175 		$jj                     = ( $jj > 31 ) ? 31 : $jj;
   155 		$jj = ($jj <= 0 ) ? date('j') : $jj;
   176 		$jj                     = ( $jj <= 0 ) ? date( 'j' ) : $jj;
   156 		$hh = ($hh > 23 ) ? $hh -24 : $hh;
   177 		$hh                     = ( $hh > 23 ) ? $hh - 24 : $hh;
   157 		$mn = ($mn > 59 ) ? $mn -60 : $mn;
   178 		$mn                     = ( $mn > 59 ) ? $mn - 60 : $mn;
   158 		$ss = ($ss > 59 ) ? $ss -60 : $ss;
   179 		$ss                     = ( $ss > 59 ) ? $ss - 60 : $ss;
   159 		$post_data['post_date'] = sprintf( "%04d-%02d-%02d %02d:%02d:%02d", $aa, $mm, $jj, $hh, $mn, $ss );
   180 		$post_data['post_date'] = sprintf( '%04d-%02d-%02d %02d:%02d:%02d', $aa, $mm, $jj, $hh, $mn, $ss );
   160 		$valid_date = wp_checkdate( $mm, $jj, $aa, $post_data['post_date'] );
   181 		$valid_date             = wp_checkdate( $mm, $jj, $aa, $post_data['post_date'] );
   161 		if ( !$valid_date ) {
   182 		if ( ! $valid_date ) {
   162 			return new WP_Error( 'invalid_date', __( 'Invalid date.' ) );
   183 			return new WP_Error( 'invalid_date', __( 'Invalid date.' ) );
   163 		}
   184 		}
   164 		$post_data['post_date_gmt'] = get_gmt_from_date( $post_data['post_date'] );
   185 		$post_data['post_date_gmt'] = get_gmt_from_date( $post_data['post_date'] );
   165 	}
   186 	}
   166 
   187 
   173 
   194 
   174 	return $post_data;
   195 	return $post_data;
   175 }
   196 }
   176 
   197 
   177 /**
   198 /**
       
   199  * Returns only allowed post data fields
       
   200  *
       
   201  * @since 5.0.1
       
   202  *
       
   203  * @param array $post_data Array of post data. Defaults to the contents of $_POST.
       
   204  * @return object|bool WP_Error on failure, true on success.
       
   205  */
       
   206 function _wp_get_allowed_postdata( $post_data = null ) {
       
   207 	if ( empty( $post_data ) ) {
       
   208 		$post_data = $_POST;
       
   209 	}
       
   210 
       
   211 	// Pass through errors
       
   212 	if ( is_wp_error( $post_data ) ) {
       
   213 		return $post_data;
       
   214 	}
       
   215 
       
   216 	return array_diff_key( $post_data, array_flip( array( 'meta_input', 'file', 'guid' ) ) );
       
   217 }
       
   218 
       
   219 /**
   178  * Update an existing post with values provided in $_POST.
   220  * Update an existing post with values provided in $_POST.
   179  *
   221  *
   180  * @since 1.5.0
   222  * @since 1.5.0
   181  *
   223  *
   182  * @global wpdb $wpdb WordPress database abstraction object.
   224  * @global wpdb $wpdb WordPress database abstraction object.
   185  * @return int Post ID.
   227  * @return int Post ID.
   186  */
   228  */
   187 function edit_post( $post_data = null ) {
   229 function edit_post( $post_data = null ) {
   188 	global $wpdb;
   230 	global $wpdb;
   189 
   231 
   190 	if ( empty($post_data) )
   232 	if ( empty( $post_data ) ) {
   191 		$post_data = &$_POST;
   233 		$post_data = &$_POST;
       
   234 	}
   192 
   235 
   193 	// Clear out any data in internal vars.
   236 	// Clear out any data in internal vars.
   194 	unset( $post_data['filter'] );
   237 	unset( $post_data['filter'] );
   195 
   238 
   196 	$post_ID = (int) $post_data['post_ID'];
   239 	$post_ID                     = (int) $post_data['post_ID'];
   197 	$post = get_post( $post_ID );
   240 	$post                        = get_post( $post_ID );
   198 	$post_data['post_type'] = $post->post_type;
   241 	$post_data['post_type']      = $post->post_type;
   199 	$post_data['post_mime_type'] = $post->post_mime_type;
   242 	$post_data['post_mime_type'] = $post->post_mime_type;
   200 
   243 
   201 	if ( ! empty( $post_data['post_status'] ) ) {
   244 	if ( ! empty( $post_data['post_status'] ) ) {
   202 		$post_data['post_status'] = sanitize_key( $post_data['post_status'] );
   245 		$post_data['post_status'] = sanitize_key( $post_data['post_status'] );
   203 
   246 
   204 		if ( 'inherit' == $post_data['post_status'] ) {
   247 		if ( 'inherit' == $post_data['post_status'] ) {
   205 			unset( $post_data['post_status'] );
   248 			unset( $post_data['post_status'] );
   206 		}
   249 		}
   207 	}
   250 	}
   208 
   251 
   209 	$ptype = get_post_type_object($post_data['post_type']);
   252 	$ptype = get_post_type_object( $post_data['post_type'] );
   210 	if ( !current_user_can( 'edit_post', $post_ID ) ) {
   253 	if ( ! current_user_can( 'edit_post', $post_ID ) ) {
   211 		if ( 'page' == $post_data['post_type'] )
   254 		if ( 'page' == $post_data['post_type'] ) {
   212 			wp_die( __('Sorry, you are not allowed to edit this page.' ));
   255 			wp_die( __( 'Sorry, you are not allowed to edit this page.' ) );
   213 		else
   256 		} else {
   214 			wp_die( __('Sorry, you are not allowed to edit this post.' ));
   257 			wp_die( __( 'Sorry, you are not allowed to edit this post.' ) );
       
   258 		}
   215 	}
   259 	}
   216 
   260 
   217 	if ( post_type_supports( $ptype->name, 'revisions' ) ) {
   261 	if ( post_type_supports( $ptype->name, 'revisions' ) ) {
   218 		$revisions = wp_get_post_revisions( $post_ID, array( 'order' => 'ASC', 'posts_per_page' => 1 ) );
   262 		$revisions = wp_get_post_revisions(
   219 		$revision = current( $revisions );
   263 			$post_ID,
       
   264 			array(
       
   265 				'order'          => 'ASC',
       
   266 				'posts_per_page' => 1,
       
   267 			)
       
   268 		);
       
   269 		$revision  = current( $revisions );
   220 
   270 
   221 		// Check if the revisions have been upgraded
   271 		// Check if the revisions have been upgraded
   222 		if ( $revisions && _wp_get_post_revision_version( $revision ) < 1 )
   272 		if ( $revisions && _wp_get_post_revision_version( $revision ) < 1 ) {
   223 			_wp_upgrade_revisions_of_post( $post, wp_get_post_revisions( $post_ID ) );
   273 			_wp_upgrade_revisions_of_post( $post, wp_get_post_revisions( $post_ID ) );
   224 	}
   274 		}
   225 
   275 	}
   226 	if ( isset($post_data['visibility']) ) {
   276 
       
   277 	if ( isset( $post_data['visibility'] ) ) {
   227 		switch ( $post_data['visibility'] ) {
   278 		switch ( $post_data['visibility'] ) {
   228 			case 'public' :
   279 			case 'public':
   229 				$post_data['post_password'] = '';
   280 				$post_data['post_password'] = '';
   230 				break;
   281 				break;
   231 			case 'password' :
   282 			case 'password':
   232 				unset( $post_data['sticky'] );
   283 				unset( $post_data['sticky'] );
   233 				break;
   284 				break;
   234 			case 'private' :
   285 			case 'private':
   235 				$post_data['post_status'] = 'private';
   286 				$post_data['post_status']   = 'private';
   236 				$post_data['post_password'] = '';
   287 				$post_data['post_password'] = '';
   237 				unset( $post_data['sticky'] );
   288 				unset( $post_data['sticky'] );
   238 				break;
   289 				break;
   239 		}
   290 		}
   240 	}
   291 	}
   241 
   292 
   242 	$post_data = _wp_translate_postdata( true, $post_data );
   293 	$post_data = _wp_translate_postdata( true, $post_data );
   243 	if ( is_wp_error($post_data) )
   294 	if ( is_wp_error( $post_data ) ) {
   244 		wp_die( $post_data->get_error_message() );
   295 		wp_die( $post_data->get_error_message() );
       
   296 	}
       
   297 	$translated = _wp_get_allowed_postdata( $post_data );
   245 
   298 
   246 	// Post Formats
   299 	// Post Formats
   247 	if ( isset( $post_data['post_format'] ) )
   300 	if ( isset( $post_data['post_format'] ) ) {
   248 		set_post_format( $post_ID, $post_data['post_format'] );
   301 		set_post_format( $post_ID, $post_data['post_format'] );
       
   302 	}
   249 
   303 
   250 	$format_meta_urls = array( 'url', 'link_url', 'quote_source_url' );
   304 	$format_meta_urls = array( 'url', 'link_url', 'quote_source_url' );
   251 	foreach ( $format_meta_urls as $format_meta_url ) {
   305 	foreach ( $format_meta_urls as $format_meta_url ) {
   252 		$keyed = '_format_' . $format_meta_url;
   306 		$keyed = '_format_' . $format_meta_url;
   253 		if ( isset( $post_data[ $keyed ] ) )
   307 		if ( isset( $post_data[ $keyed ] ) ) {
   254 			update_post_meta( $post_ID, $keyed, wp_slash( esc_url_raw( wp_unslash( $post_data[ $keyed ] ) ) ) );
   308 			update_post_meta( $post_ID, $keyed, wp_slash( esc_url_raw( wp_unslash( $post_data[ $keyed ] ) ) ) );
       
   309 		}
   255 	}
   310 	}
   256 
   311 
   257 	$format_keys = array( 'quote', 'quote_source_name', 'image', 'gallery', 'audio_embed', 'video_embed' );
   312 	$format_keys = array( 'quote', 'quote_source_name', 'image', 'gallery', 'audio_embed', 'video_embed' );
   258 
   313 
   259 	foreach ( $format_keys as $key ) {
   314 	foreach ( $format_keys as $key ) {
   260 		$keyed = '_format_' . $key;
   315 		$keyed = '_format_' . $key;
   261 		if ( isset( $post_data[ $keyed ] ) ) {
   316 		if ( isset( $post_data[ $keyed ] ) ) {
   262 			if ( current_user_can( 'unfiltered_html' ) )
   317 			if ( current_user_can( 'unfiltered_html' ) ) {
   263 				update_post_meta( $post_ID, $keyed, $post_data[ $keyed ] );
   318 				update_post_meta( $post_ID, $keyed, $post_data[ $keyed ] );
   264 			else
   319 			} else {
   265 				update_post_meta( $post_ID, $keyed, wp_filter_post_kses( $post_data[ $keyed ] ) );
   320 				update_post_meta( $post_ID, $keyed, wp_filter_post_kses( $post_data[ $keyed ] ) );
       
   321 			}
   266 		}
   322 		}
   267 	}
   323 	}
   268 
   324 
   269 	if ( 'attachment' === $post_data['post_type'] && preg_match( '#^(audio|video)/#', $post_data['post_mime_type'] ) ) {
   325 	if ( 'attachment' === $post_data['post_type'] && preg_match( '#^(audio|video)/#', $post_data['post_mime_type'] ) ) {
   270 		$id3data = wp_get_attachment_metadata( $post_ID );
   326 		$id3data = wp_get_attachment_metadata( $post_ID );
   279 		}
   335 		}
   280 		wp_update_attachment_metadata( $post_ID, $id3data );
   336 		wp_update_attachment_metadata( $post_ID, $id3data );
   281 	}
   337 	}
   282 
   338 
   283 	// Meta Stuff
   339 	// Meta Stuff
   284 	if ( isset($post_data['meta']) && $post_data['meta'] ) {
   340 	if ( isset( $post_data['meta'] ) && $post_data['meta'] ) {
   285 		foreach ( $post_data['meta'] as $key => $value ) {
   341 		foreach ( $post_data['meta'] as $key => $value ) {
   286 			if ( !$meta = get_post_meta_by_id( $key ) )
   342 			if ( ! $meta = get_post_meta_by_id( $key ) ) {
   287 				continue;
   343 				continue;
   288 			if ( $meta->post_id != $post_ID )
   344 			}
       
   345 			if ( $meta->post_id != $post_ID ) {
   289 				continue;
   346 				continue;
   290 			if ( is_protected_meta( $meta->meta_key, 'post' ) || ! current_user_can( 'edit_post_meta', $post_ID, $meta->meta_key ) )
   347 			}
       
   348 			if ( is_protected_meta( $meta->meta_key, 'post' ) || ! current_user_can( 'edit_post_meta', $post_ID, $meta->meta_key ) ) {
   291 				continue;
   349 				continue;
   292 			if ( is_protected_meta( $value['key'], 'post' ) || ! current_user_can( 'edit_post_meta', $post_ID, $value['key'] ) )
   350 			}
       
   351 			if ( is_protected_meta( $value['key'], 'post' ) || ! current_user_can( 'edit_post_meta', $post_ID, $value['key'] ) ) {
   293 				continue;
   352 				continue;
       
   353 			}
   294 			update_meta( $key, $value['key'], $value['value'] );
   354 			update_meta( $key, $value['key'], $value['value'] );
   295 		}
   355 		}
   296 	}
   356 	}
   297 
   357 
   298 	if ( isset($post_data['deletemeta']) && $post_data['deletemeta'] ) {
   358 	if ( isset( $post_data['deletemeta'] ) && $post_data['deletemeta'] ) {
   299 		foreach ( $post_data['deletemeta'] as $key => $value ) {
   359 		foreach ( $post_data['deletemeta'] as $key => $value ) {
   300 			if ( !$meta = get_post_meta_by_id( $key ) )
   360 			if ( ! $meta = get_post_meta_by_id( $key ) ) {
   301 				continue;
   361 				continue;
   302 			if ( $meta->post_id != $post_ID )
   362 			}
       
   363 			if ( $meta->post_id != $post_ID ) {
   303 				continue;
   364 				continue;
   304 			if ( is_protected_meta( $meta->meta_key, 'post' ) || ! current_user_can( 'delete_post_meta', $post_ID, $meta->meta_key ) )
   365 			}
       
   366 			if ( is_protected_meta( $meta->meta_key, 'post' ) || ! current_user_can( 'delete_post_meta', $post_ID, $meta->meta_key ) ) {
   305 				continue;
   367 				continue;
       
   368 			}
   306 			delete_meta( $key );
   369 			delete_meta( $key );
   307 		}
   370 		}
   308 	}
   371 	}
   309 
   372 
   310 	// Attachment stuff
   373 	// Attachment stuff
   311 	if ( 'attachment' == $post_data['post_type'] ) {
   374 	if ( 'attachment' == $post_data['post_type'] ) {
   312 		if ( isset( $post_data[ '_wp_attachment_image_alt' ] ) ) {
   375 		if ( isset( $post_data['_wp_attachment_image_alt'] ) ) {
   313 			$image_alt = wp_unslash( $post_data['_wp_attachment_image_alt'] );
   376 			$image_alt = wp_unslash( $post_data['_wp_attachment_image_alt'] );
   314 			if ( $image_alt != get_post_meta( $post_ID, '_wp_attachment_image_alt', true ) ) {
   377 			if ( $image_alt != get_post_meta( $post_ID, '_wp_attachment_image_alt', true ) ) {
   315 				$image_alt = wp_strip_all_tags( $image_alt, true );
   378 				$image_alt = wp_strip_all_tags( $image_alt, true );
   316 				// update_meta expects slashed.
   379 				// update_meta expects slashed.
   317 				update_post_meta( $post_ID, '_wp_attachment_image_alt', wp_slash( $image_alt ) );
   380 				update_post_meta( $post_ID, '_wp_attachment_image_alt', wp_slash( $image_alt ) );
   319 		}
   382 		}
   320 
   383 
   321 		$attachment_data = isset( $post_data['attachments'][ $post_ID ] ) ? $post_data['attachments'][ $post_ID ] : array();
   384 		$attachment_data = isset( $post_data['attachments'][ $post_ID ] ) ? $post_data['attachments'][ $post_ID ] : array();
   322 
   385 
   323 		/** This filter is documented in wp-admin/includes/media.php */
   386 		/** This filter is documented in wp-admin/includes/media.php */
   324 		$post_data = apply_filters( 'attachment_fields_to_save', $post_data, $attachment_data );
   387 		$translated = apply_filters( 'attachment_fields_to_save', $translated, $attachment_data );
   325 	}
   388 	}
   326 
   389 
   327 	// Convert taxonomy input to term IDs, to avoid ambiguity.
   390 	// Convert taxonomy input to term IDs, to avoid ambiguity.
   328 	if ( isset( $post_data['tax_input'] ) ) {
   391 	if ( isset( $post_data['tax_input'] ) ) {
   329 		foreach ( (array) $post_data['tax_input'] as $taxonomy => $terms ) {
   392 		foreach ( (array) $post_data['tax_input'] as $taxonomy => $terms ) {
   330 			// Hierarchical taxonomy data is already sent as term IDs, so no conversion is necessary.
   393 			$tax_object = get_taxonomy( $taxonomy );
   331 			if ( is_taxonomy_hierarchical( $taxonomy ) ) {
   394 
       
   395 			if ( $tax_object && isset( $tax_object->meta_box_sanitize_cb ) ) {
       
   396 				$translated['tax_input'][ $taxonomy ] = call_user_func_array( $tax_object->meta_box_sanitize_cb, array( $taxonomy, $terms ) );
       
   397 			}
       
   398 		}
       
   399 	}
       
   400 
       
   401 	add_meta( $post_ID );
       
   402 
       
   403 	update_post_meta( $post_ID, '_edit_last', get_current_user_id() );
       
   404 
       
   405 	$success = wp_update_post( $translated );
       
   406 	// If the save failed, see if we can sanity check the main fields and try again
       
   407 	if ( ! $success && is_callable( array( $wpdb, 'strip_invalid_text_for_column' ) ) ) {
       
   408 		$fields = array( 'post_title', 'post_content', 'post_excerpt' );
       
   409 
       
   410 		foreach ( $fields as $field ) {
       
   411 			if ( isset( $translated[ $field ] ) ) {
       
   412 				$translated[ $field ] = $wpdb->strip_invalid_text_for_column( $wpdb->posts, $field, $translated[ $field ] );
       
   413 			}
       
   414 		}
       
   415 
       
   416 		wp_update_post( $translated );
       
   417 	}
       
   418 
       
   419 	// Now that we have an ID we can fix any attachment anchor hrefs
       
   420 	_fix_attachment_links( $post_ID );
       
   421 
       
   422 	wp_set_post_lock( $post_ID );
       
   423 
       
   424 	if ( current_user_can( $ptype->cap->edit_others_posts ) && current_user_can( $ptype->cap->publish_posts ) ) {
       
   425 		if ( ! empty( $post_data['sticky'] ) ) {
       
   426 			stick_post( $post_ID );
       
   427 		} else {
       
   428 			unstick_post( $post_ID );
       
   429 		}
       
   430 	}
       
   431 
       
   432 	return $post_ID;
       
   433 }
       
   434 
       
   435 /**
       
   436  * Process the post data for the bulk editing of posts.
       
   437  *
       
   438  * Updates all bulk edited posts/pages, adding (but not removing) tags and
       
   439  * categories. Skips pages when they would be their own parent or child.
       
   440  *
       
   441  * @since 2.7.0
       
   442  *
       
   443  * @global wpdb $wpdb WordPress database abstraction object.
       
   444  *
       
   445  * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
       
   446  * @return array
       
   447  */
       
   448 function bulk_edit_posts( $post_data = null ) {
       
   449 	global $wpdb;
       
   450 
       
   451 	if ( empty( $post_data ) ) {
       
   452 		$post_data = &$_POST;
       
   453 	}
       
   454 
       
   455 	if ( isset( $post_data['post_type'] ) ) {
       
   456 		$ptype = get_post_type_object( $post_data['post_type'] );
       
   457 	} else {
       
   458 		$ptype = get_post_type_object( 'post' );
       
   459 	}
       
   460 
       
   461 	if ( ! current_user_can( $ptype->cap->edit_posts ) ) {
       
   462 		if ( 'page' == $ptype->name ) {
       
   463 			wp_die( __( 'Sorry, you are not allowed to edit pages.' ) );
       
   464 		} else {
       
   465 			wp_die( __( 'Sorry, you are not allowed to edit posts.' ) );
       
   466 		}
       
   467 	}
       
   468 
       
   469 	if ( -1 == $post_data['_status'] ) {
       
   470 		$post_data['post_status'] = null;
       
   471 		unset( $post_data['post_status'] );
       
   472 	} else {
       
   473 		$post_data['post_status'] = $post_data['_status'];
       
   474 	}
       
   475 	unset( $post_data['_status'] );
       
   476 
       
   477 	if ( ! empty( $post_data['post_status'] ) ) {
       
   478 		$post_data['post_status'] = sanitize_key( $post_data['post_status'] );
       
   479 
       
   480 		if ( 'inherit' == $post_data['post_status'] ) {
       
   481 			unset( $post_data['post_status'] );
       
   482 		}
       
   483 	}
       
   484 
       
   485 	$post_IDs = array_map( 'intval', (array) $post_data['post'] );
       
   486 
       
   487 	$reset = array(
       
   488 		'post_author',
       
   489 		'post_status',
       
   490 		'post_password',
       
   491 		'post_parent',
       
   492 		'page_template',
       
   493 		'comment_status',
       
   494 		'ping_status',
       
   495 		'keep_private',
       
   496 		'tax_input',
       
   497 		'post_category',
       
   498 		'sticky',
       
   499 		'post_format',
       
   500 	);
       
   501 
       
   502 	foreach ( $reset as $field ) {
       
   503 		if ( isset( $post_data[ $field ] ) && ( '' == $post_data[ $field ] || -1 == $post_data[ $field ] ) ) {
       
   504 			unset( $post_data[ $field ] );
       
   505 		}
       
   506 	}
       
   507 
       
   508 	if ( isset( $post_data['post_category'] ) ) {
       
   509 		if ( is_array( $post_data['post_category'] ) && ! empty( $post_data['post_category'] ) ) {
       
   510 			$new_cats = array_map( 'absint', $post_data['post_category'] );
       
   511 		} else {
       
   512 			unset( $post_data['post_category'] );
       
   513 		}
       
   514 	}
       
   515 
       
   516 	$tax_input = array();
       
   517 	if ( isset( $post_data['tax_input'] ) ) {
       
   518 		foreach ( $post_data['tax_input'] as $tax_name => $terms ) {
       
   519 			if ( empty( $terms ) ) {
   332 				continue;
   520 				continue;
   333 			}
   521 			}
   334 
   522 			if ( is_taxonomy_hierarchical( $tax_name ) ) {
   335 			/*
   523 				$tax_input[ $tax_name ] = array_map( 'absint', $terms );
   336 			 * Assume that a 'tax_input' string is a comma-separated list of term names.
   524 			} else {
   337 			 * Some languages may use a character other than a comma as a delimiter, so we standardize on
       
   338 			 * commas before parsing the list.
       
   339 			 */
       
   340 			if ( ! is_array( $terms ) ) {
       
   341 				$comma = _x( ',', 'tag delimiter' );
   525 				$comma = _x( ',', 'tag delimiter' );
   342 				if ( ',' !== $comma ) {
   526 				if ( ',' !== $comma ) {
   343 					$terms = str_replace( $comma, ',', $terms );
   527 					$terms = str_replace( $comma, ',', $terms );
   344 				}
   528 				}
   345 				$terms = explode( ',', trim( $terms, " \n\t\r\0\x0B," ) );
       
   346 			}
       
   347 
       
   348 			$clean_terms = array();
       
   349 			foreach ( $terms as $term ) {
       
   350 				// Empty terms are invalid input.
       
   351 				if ( empty( $term ) ) {
       
   352 					continue;
       
   353 				}
       
   354 
       
   355 				$_term = get_terms( $taxonomy, array(
       
   356 					'name' => $term,
       
   357 					'fields' => 'ids',
       
   358 					'hide_empty' => false,
       
   359 				) );
       
   360 
       
   361 				if ( ! empty( $_term ) ) {
       
   362 					$clean_terms[] = intval( $_term[0] );
       
   363 				} else {
       
   364 					// No existing term was found, so pass the string. A new term will be created.
       
   365 					$clean_terms[] = $term;
       
   366 				}
       
   367 			}
       
   368 
       
   369 			$post_data['tax_input'][ $taxonomy ] = $clean_terms;
       
   370 		}
       
   371 	}
       
   372 
       
   373 	add_meta( $post_ID );
       
   374 
       
   375 	update_post_meta( $post_ID, '_edit_last', get_current_user_id() );
       
   376 
       
   377 	$success = wp_update_post( $post_data );
       
   378 	// If the save failed, see if we can sanity check the main fields and try again
       
   379 	if ( ! $success && is_callable( array( $wpdb, 'strip_invalid_text_for_column' ) ) ) {
       
   380 		$fields = array( 'post_title', 'post_content', 'post_excerpt' );
       
   381 
       
   382 		foreach ( $fields as $field ) {
       
   383 			if ( isset( $post_data[ $field ] ) ) {
       
   384 				$post_data[ $field ] = $wpdb->strip_invalid_text_for_column( $wpdb->posts, $field, $post_data[ $field ] );
       
   385 			}
       
   386 		}
       
   387 
       
   388 		wp_update_post( $post_data );
       
   389 	}
       
   390 
       
   391 	// Now that we have an ID we can fix any attachment anchor hrefs
       
   392 	_fix_attachment_links( $post_ID );
       
   393 
       
   394 	wp_set_post_lock( $post_ID );
       
   395 
       
   396 	if ( current_user_can( $ptype->cap->edit_others_posts ) && current_user_can( $ptype->cap->publish_posts ) ) {
       
   397 		if ( ! empty( $post_data['sticky'] ) )
       
   398 			stick_post( $post_ID );
       
   399 		else
       
   400 			unstick_post( $post_ID );
       
   401 	}
       
   402 
       
   403 	return $post_ID;
       
   404 }
       
   405 
       
   406 /**
       
   407  * Process the post data for the bulk editing of posts.
       
   408  *
       
   409  * Updates all bulk edited posts/pages, adding (but not removing) tags and
       
   410  * categories. Skips pages when they would be their own parent or child.
       
   411  *
       
   412  * @since 2.7.0
       
   413  *
       
   414  * @global wpdb $wpdb WordPress database abstraction object.
       
   415  *
       
   416  * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
       
   417  * @return array
       
   418  */
       
   419 function bulk_edit_posts( $post_data = null ) {
       
   420 	global $wpdb;
       
   421 
       
   422 	if ( empty($post_data) )
       
   423 		$post_data = &$_POST;
       
   424 
       
   425 	if ( isset($post_data['post_type']) )
       
   426 		$ptype = get_post_type_object($post_data['post_type']);
       
   427 	else
       
   428 		$ptype = get_post_type_object('post');
       
   429 
       
   430 	if ( !current_user_can( $ptype->cap->edit_posts ) ) {
       
   431 		if ( 'page' == $ptype->name )
       
   432 			wp_die( __('Sorry, you are not allowed to edit pages.'));
       
   433 		else
       
   434 			wp_die( __('Sorry, you are not allowed to edit posts.'));
       
   435 	}
       
   436 
       
   437 	if ( -1 == $post_data['_status'] ) {
       
   438 		$post_data['post_status'] = null;
       
   439 		unset($post_data['post_status']);
       
   440 	} else {
       
   441 		$post_data['post_status'] = $post_data['_status'];
       
   442 	}
       
   443 	unset($post_data['_status']);
       
   444 
       
   445 	if ( ! empty( $post_data['post_status'] ) ) {
       
   446 		$post_data['post_status'] = sanitize_key( $post_data['post_status'] );
       
   447 
       
   448 		if ( 'inherit' == $post_data['post_status'] ) {
       
   449 			unset( $post_data['post_status'] );
       
   450 		}
       
   451 	}
       
   452 
       
   453 	$post_IDs = array_map( 'intval', (array) $post_data['post'] );
       
   454 
       
   455 	$reset = array(
       
   456 		'post_author', 'post_status', 'post_password',
       
   457 		'post_parent', 'page_template', 'comment_status',
       
   458 		'ping_status', 'keep_private', 'tax_input',
       
   459 		'post_category', 'sticky', 'post_format',
       
   460 	);
       
   461 
       
   462 	foreach ( $reset as $field ) {
       
   463 		if ( isset($post_data[$field]) && ( '' == $post_data[$field] || -1 == $post_data[$field] ) )
       
   464 			unset($post_data[$field]);
       
   465 	}
       
   466 
       
   467 	if ( isset($post_data['post_category']) ) {
       
   468 		if ( is_array($post_data['post_category']) && ! empty($post_data['post_category']) )
       
   469 			$new_cats = array_map( 'absint', $post_data['post_category'] );
       
   470 		else
       
   471 			unset($post_data['post_category']);
       
   472 	}
       
   473 
       
   474 	$tax_input = array();
       
   475 	if ( isset($post_data['tax_input'])) {
       
   476 		foreach ( $post_data['tax_input'] as $tax_name => $terms ) {
       
   477 			if ( empty($terms) )
       
   478 				continue;
       
   479 			if ( is_taxonomy_hierarchical( $tax_name ) ) {
       
   480 				$tax_input[ $tax_name ] = array_map( 'absint', $terms );
       
   481 			} else {
       
   482 				$comma = _x( ',', 'tag delimiter' );
       
   483 				if ( ',' !== $comma )
       
   484 					$terms = str_replace( $comma, ',', $terms );
       
   485 				$tax_input[ $tax_name ] = explode( ',', trim( $terms, " \n\t\r\0\x0B," ) );
   529 				$tax_input[ $tax_name ] = explode( ',', trim( $terms, " \n\t\r\0\x0B," ) );
   486 			}
   530 			}
   487 		}
   531 		}
   488 	}
   532 	}
   489 
   533 
   490 	if ( isset($post_data['post_parent']) && ($parent = (int) $post_data['post_parent']) ) {
   534 	if ( isset( $post_data['post_parent'] ) && ( $parent = (int) $post_data['post_parent'] ) ) {
   491 		$pages = $wpdb->get_results("SELECT ID, post_parent FROM $wpdb->posts WHERE post_type = 'page'");
   535 		$pages    = $wpdb->get_results( "SELECT ID, post_parent FROM $wpdb->posts WHERE post_type = 'page'" );
   492 		$children = array();
   536 		$children = array();
   493 
   537 
   494 		for ( $i = 0; $i < 50 && $parent > 0; $i++ ) {
   538 		for ( $i = 0; $i < 50 && $parent > 0; $i++ ) {
   495 			$children[] = $parent;
   539 			$children[] = $parent;
   496 
   540 
   501 				}
   545 				}
   502 			}
   546 			}
   503 		}
   547 		}
   504 	}
   548 	}
   505 
   549 
   506 	$updated = $skipped = $locked = array();
   550 	$updated          = $skipped = $locked = array();
   507 	$shared_post_data = $post_data;
   551 	$shared_post_data = $post_data;
   508 
   552 
   509 	foreach ( $post_IDs as $post_ID ) {
   553 	foreach ( $post_IDs as $post_ID ) {
   510 		// Start with fresh post data with each iteration.
   554 		// Start with fresh post data with each iteration.
   511 		$post_data = $shared_post_data;
   555 		$post_data = $shared_post_data;
   512 
   556 
   513 		$post_type_object = get_post_type_object( get_post_type( $post_ID ) );
   557 		$post_type_object = get_post_type_object( get_post_type( $post_ID ) );
   514 
   558 
   515 		if ( !isset( $post_type_object ) || ( isset($children) && in_array($post_ID, $children) ) || !current_user_can( 'edit_post', $post_ID ) ) {
   559 		if ( ! isset( $post_type_object ) || ( isset( $children ) && in_array( $post_ID, $children ) ) || ! current_user_can( 'edit_post', $post_ID ) ) {
   516 			$skipped[] = $post_ID;
   560 			$skipped[] = $post_ID;
   517 			continue;
   561 			continue;
   518 		}
   562 		}
   519 
   563 
   520 		if ( wp_check_post_lock( $post_ID ) ) {
   564 		if ( wp_check_post_lock( $post_ID ) ) {
   521 			$locked[] = $post_ID;
   565 			$locked[] = $post_ID;
   522 			continue;
   566 			continue;
   523 		}
   567 		}
   524 
   568 
   525 		$post = get_post( $post_ID );
   569 		$post      = get_post( $post_ID );
   526 		$tax_names = get_object_taxonomies( $post );
   570 		$tax_names = get_object_taxonomies( $post );
   527 		foreach ( $tax_names as $tax_name ) {
   571 		foreach ( $tax_names as $tax_name ) {
   528 			$taxonomy_obj = get_taxonomy($tax_name);
   572 			$taxonomy_obj = get_taxonomy( $tax_name );
   529 			if ( isset( $tax_input[$tax_name]) && current_user_can( $taxonomy_obj->cap->assign_terms ) )
   573 			if ( isset( $tax_input[ $tax_name ] ) && current_user_can( $taxonomy_obj->cap->assign_terms ) ) {
   530 				$new_terms = $tax_input[$tax_name];
   574 				$new_terms = $tax_input[ $tax_name ];
   531 			else
   575 			} else {
   532 				$new_terms = array();
   576 				$new_terms = array();
   533 
   577 			}
   534 			if ( $taxonomy_obj->hierarchical )
   578 
   535 				$current_terms = (array) wp_get_object_terms( $post_ID, $tax_name, array('fields' => 'ids') );
   579 			if ( $taxonomy_obj->hierarchical ) {
   536 			else
   580 				$current_terms = (array) wp_get_object_terms( $post_ID, $tax_name, array( 'fields' => 'ids' ) );
   537 				$current_terms = (array) wp_get_object_terms( $post_ID, $tax_name, array('fields' => 'names') );
   581 			} else {
   538 
   582 				$current_terms = (array) wp_get_object_terms( $post_ID, $tax_name, array( 'fields' => 'names' ) );
   539 			$post_data['tax_input'][$tax_name] = array_merge( $current_terms, $new_terms );
   583 			}
   540 		}
   584 
   541 
   585 			$post_data['tax_input'][ $tax_name ] = array_merge( $current_terms, $new_terms );
   542 		if ( isset($new_cats) && in_array( 'category', $tax_names ) ) {
   586 		}
   543 			$cats = (array) wp_get_post_categories($post_ID);
   587 
   544 			$post_data['post_category'] = array_unique( array_merge($cats, $new_cats) );
   588 		if ( isset( $new_cats ) && in_array( 'category', $tax_names ) ) {
       
   589 			$cats                       = (array) wp_get_post_categories( $post_ID );
       
   590 			$post_data['post_category'] = array_unique( array_merge( $cats, $new_cats ) );
   545 			unset( $post_data['tax_input']['category'] );
   591 			unset( $post_data['tax_input']['category'] );
   546 		}
   592 		}
   547 
   593 
   548 		$post_data['post_type'] = $post->post_type;
   594 		$post_data['post_ID']        = $post_ID;
       
   595 		$post_data['post_type']      = $post->post_type;
   549 		$post_data['post_mime_type'] = $post->post_mime_type;
   596 		$post_data['post_mime_type'] = $post->post_mime_type;
   550 		$post_data['guid'] = $post->guid;
       
   551 
   597 
   552 		foreach ( array( 'comment_status', 'ping_status', 'post_author' ) as $field ) {
   598 		foreach ( array( 'comment_status', 'ping_status', 'post_author' ) as $field ) {
   553 			if ( ! isset( $post_data[ $field ] ) ) {
   599 			if ( ! isset( $post_data[ $field ] ) ) {
   554 				$post_data[ $field ] = $post->$field;
   600 				$post_data[ $field ] = $post->$field;
   555 			}
   601 			}
   556 		}
   602 		}
   557 
       
   558 		$post_data['ID'] = $post_ID;
       
   559 		$post_data['post_ID'] = $post_ID;
       
   560 
   603 
   561 		$post_data = _wp_translate_postdata( true, $post_data );
   604 		$post_data = _wp_translate_postdata( true, $post_data );
   562 		if ( is_wp_error( $post_data ) ) {
   605 		if ( is_wp_error( $post_data ) ) {
   563 			$skipped[] = $post_ID;
   606 			$skipped[] = $post_ID;
   564 			continue;
   607 			continue;
   565 		}
   608 		}
   566 
   609 		$post_data = _wp_get_allowed_postdata( $post_data );
   567 		if ( isset( $post_data['post_format'] ) ) {
   610 
   568 			set_post_format( $post_ID, $post_data['post_format'] );
   611 		if ( isset( $shared_post_data['post_format'] ) ) {
   569 			unset( $post_data['tax_input']['post_format'] );
   612 			set_post_format( $post_ID, $shared_post_data['post_format'] );
   570 		}
   613 		}
       
   614 
       
   615 		// Prevent wp_insert_post() from overwriting post format with the old data.
       
   616 		unset( $post_data['tax_input']['post_format'] );
   571 
   617 
   572 		$updated[] = wp_update_post( $post_data );
   618 		$updated[] = wp_update_post( $post_data );
   573 
   619 
   574 		if ( isset( $post_data['sticky'] ) && current_user_can( $ptype->cap->edit_others_posts ) ) {
   620 		if ( isset( $post_data['sticky'] ) && current_user_can( $ptype->cap->edit_others_posts ) ) {
   575 			if ( 'sticky' == $post_data['sticky'] )
   621 			if ( 'sticky' == $post_data['sticky'] ) {
   576 				stick_post( $post_ID );
   622 				stick_post( $post_ID );
   577 			else
   623 			} else {
   578 				unstick_post( $post_ID );
   624 				unstick_post( $post_ID );
   579 		}
   625 			}
   580 	}
   626 		}
   581 
   627 	}
   582 	return array( 'updated' => $updated, 'skipped' => $skipped, 'locked' => $locked );
   628 
       
   629 	return array(
       
   630 		'updated' => $updated,
       
   631 		'skipped' => $skipped,
       
   632 		'locked'  => $locked,
       
   633 	);
   583 }
   634 }
   584 
   635 
   585 /**
   636 /**
   586  * Default post information to use when populating the "Write Post" form.
   637  * Default post information to use when populating the "Write Post" form.
   587  *
   638  *
   591  * @param bool   $create_in_db Optional. Whether to insert the post into database. Default false.
   642  * @param bool   $create_in_db Optional. Whether to insert the post into database. Default false.
   592  * @return WP_Post Post object containing all the default post data as attributes
   643  * @return WP_Post Post object containing all the default post data as attributes
   593  */
   644  */
   594 function get_default_post_to_edit( $post_type = 'post', $create_in_db = false ) {
   645 function get_default_post_to_edit( $post_type = 'post', $create_in_db = false ) {
   595 	$post_title = '';
   646 	$post_title = '';
   596 	if ( !empty( $_REQUEST['post_title'] ) )
   647 	if ( ! empty( $_REQUEST['post_title'] ) ) {
   597 		$post_title = esc_html( wp_unslash( $_REQUEST['post_title'] ));
   648 		$post_title = esc_html( wp_unslash( $_REQUEST['post_title'] ) );
       
   649 	}
   598 
   650 
   599 	$post_content = '';
   651 	$post_content = '';
   600 	if ( !empty( $_REQUEST['content'] ) )
   652 	if ( ! empty( $_REQUEST['content'] ) ) {
   601 		$post_content = esc_html( wp_unslash( $_REQUEST['content'] ));
   653 		$post_content = esc_html( wp_unslash( $_REQUEST['content'] ) );
       
   654 	}
   602 
   655 
   603 	$post_excerpt = '';
   656 	$post_excerpt = '';
   604 	if ( !empty( $_REQUEST['excerpt'] ) )
   657 	if ( ! empty( $_REQUEST['excerpt'] ) ) {
   605 		$post_excerpt = esc_html( wp_unslash( $_REQUEST['excerpt'] ));
   658 		$post_excerpt = esc_html( wp_unslash( $_REQUEST['excerpt'] ) );
       
   659 	}
   606 
   660 
   607 	if ( $create_in_db ) {
   661 	if ( $create_in_db ) {
   608 		$post_id = wp_insert_post( array( 'post_title' => __( 'Auto Draft' ), 'post_type' => $post_type, 'post_status' => 'auto-draft' ) );
   662 		$post_id = wp_insert_post(
   609 		$post = get_post( $post_id );
   663 			array(
   610 		if ( current_theme_supports( 'post-formats' ) && post_type_supports( $post->post_type, 'post-formats' ) && get_option( 'default_post_format' ) )
   664 				'post_title'  => __( 'Auto Draft' ),
       
   665 				'post_type'   => $post_type,
       
   666 				'post_status' => 'auto-draft',
       
   667 			)
       
   668 		);
       
   669 		$post    = get_post( $post_id );
       
   670 		if ( current_theme_supports( 'post-formats' ) && post_type_supports( $post->post_type, 'post-formats' ) && get_option( 'default_post_format' ) ) {
   611 			set_post_format( $post, get_option( 'default_post_format' ) );
   671 			set_post_format( $post, get_option( 'default_post_format' ) );
       
   672 		}
       
   673 
       
   674 		// Schedule auto-draft cleanup
       
   675 		if ( ! wp_next_scheduled( 'wp_scheduled_auto_draft_delete' ) ) {
       
   676 			wp_schedule_event( time(), 'daily', 'wp_scheduled_auto_draft_delete' );
       
   677 		}
   612 	} else {
   678 	} else {
   613 		$post = new stdClass;
   679 		$post                 = new stdClass;
   614 		$post->ID = 0;
   680 		$post->ID             = 0;
   615 		$post->post_author = '';
   681 		$post->post_author    = '';
   616 		$post->post_date = '';
   682 		$post->post_date      = '';
   617 		$post->post_date_gmt = '';
   683 		$post->post_date_gmt  = '';
   618 		$post->post_password = '';
   684 		$post->post_password  = '';
   619 		$post->post_name = '';
   685 		$post->post_name      = '';
   620 		$post->post_type = $post_type;
   686 		$post->post_type      = $post_type;
   621 		$post->post_status = 'draft';
   687 		$post->post_status    = 'draft';
   622 		$post->to_ping = '';
   688 		$post->to_ping        = '';
   623 		$post->pinged = '';
   689 		$post->pinged         = '';
   624 		$post->comment_status = get_default_comment_status( $post_type );
   690 		$post->comment_status = get_default_comment_status( $post_type );
   625 		$post->ping_status = get_default_comment_status( $post_type, 'pingback' );
   691 		$post->ping_status    = get_default_comment_status( $post_type, 'pingback' );
   626 		$post->post_pingback = get_option( 'default_pingback_flag' );
   692 		$post->post_pingback  = get_option( 'default_pingback_flag' );
   627 		$post->post_category = get_option( 'default_category' );
   693 		$post->post_category  = get_option( 'default_category' );
   628 		$post->page_template = 'default';
   694 		$post->page_template  = 'default';
   629 		$post->post_parent = 0;
   695 		$post->post_parent    = 0;
   630 		$post->menu_order = 0;
   696 		$post->menu_order     = 0;
   631 		$post = new WP_Post( $post );
   697 		$post                 = new WP_Post( $post );
   632 	}
   698 	}
   633 
   699 
   634 	/**
   700 	/**
   635 	 * Filters the default post content initially used in the "Write Post" form.
   701 	 * Filters the default post content initially used in the "Write Post" form.
   636 	 *
   702 	 *
   637 	 * @since 1.5.0
   703 	 * @since 1.5.0
   638 	 *
   704 	 *
   639 	 * @param string  $post_content Default post content.
   705 	 * @param string  $post_content Default post content.
   640 	 * @param WP_Post $post         Post object.
   706 	 * @param WP_Post $post         Post object.
   641 	 */
   707 	 */
   642 	$post->post_content = apply_filters( 'default_content', $post_content, $post );
   708 	$post->post_content = (string) apply_filters( 'default_content', $post_content, $post );
   643 
   709 
   644 	/**
   710 	/**
   645 	 * Filters the default post title initially used in the "Write Post" form.
   711 	 * Filters the default post title initially used in the "Write Post" form.
   646 	 *
   712 	 *
   647 	 * @since 1.5.0
   713 	 * @since 1.5.0
   648 	 *
   714 	 *
   649 	 * @param string  $post_title Default post title.
   715 	 * @param string  $post_title Default post title.
   650 	 * @param WP_Post $post       Post object.
   716 	 * @param WP_Post $post       Post object.
   651 	 */
   717 	 */
   652 	$post->post_title = apply_filters( 'default_title', $post_title, $post );
   718 	$post->post_title = (string) apply_filters( 'default_title', $post_title, $post );
   653 
   719 
   654 	/**
   720 	/**
   655 	 * Filters the default post excerpt initially used in the "Write Post" form.
   721 	 * Filters the default post excerpt initially used in the "Write Post" form.
   656 	 *
   722 	 *
   657 	 * @since 1.5.0
   723 	 * @since 1.5.0
   658 	 *
   724 	 *
   659 	 * @param string  $post_excerpt Default post excerpt.
   725 	 * @param string  $post_excerpt Default post excerpt.
   660 	 * @param WP_Post $post         Post object.
   726 	 * @param WP_Post $post         Post object.
   661 	 */
   727 	 */
   662 	$post->post_excerpt = apply_filters( 'default_excerpt', $post_excerpt, $post );
   728 	$post->post_excerpt = (string) apply_filters( 'default_excerpt', $post_excerpt, $post );
   663 
   729 
   664 	return $post;
   730 	return $post;
   665 }
   731 }
   666 
   732 
   667 /**
   733 /**
   668  * Determine if a post exists based on title, content, and date
   734  * Determines if a post exists based on title, content, date and type.
   669  *
   735  *
   670  * @since 2.0.0
   736  * @since 2.0.0
       
   737  * @since 5.2.0 Added the `$type` parameter.
   671  *
   738  *
   672  * @global wpdb $wpdb WordPress database abstraction object.
   739  * @global wpdb $wpdb WordPress database abstraction object.
   673  *
   740  *
   674  * @param string $title Post title
   741  * @param string $title   Post title.
   675  * @param string $content Optional post content
   742  * @param string $content Optional post content.
   676  * @param string $date Optional post date
   743  * @param string $date    Optional post date.
       
   744  * @param string $type    Optional post type.
   677  * @return int Post ID if post exists, 0 otherwise.
   745  * @return int Post ID if post exists, 0 otherwise.
   678  */
   746  */
   679 function post_exists($title, $content = '', $date = '') {
   747 function post_exists( $title, $content = '', $date = '', $type = '' ) {
   680 	global $wpdb;
   748 	global $wpdb;
   681 
   749 
   682 	$post_title = wp_unslash( sanitize_post_field( 'post_title', $title, 0, 'db' ) );
   750 	$post_title   = wp_unslash( sanitize_post_field( 'post_title', $title, 0, 'db' ) );
   683 	$post_content = wp_unslash( sanitize_post_field( 'post_content', $content, 0, 'db' ) );
   751 	$post_content = wp_unslash( sanitize_post_field( 'post_content', $content, 0, 'db' ) );
   684 	$post_date = wp_unslash( sanitize_post_field( 'post_date', $date, 0, 'db' ) );
   752 	$post_date    = wp_unslash( sanitize_post_field( 'post_date', $date, 0, 'db' ) );
       
   753 	$post_type    = wp_unslash( sanitize_post_field( 'post_type', $type, 0, 'db' ) );
   685 
   754 
   686 	$query = "SELECT ID FROM $wpdb->posts WHERE 1=1";
   755 	$query = "SELECT ID FROM $wpdb->posts WHERE 1=1";
   687 	$args = array();
   756 	$args  = array();
   688 
   757 
   689 	if ( !empty ( $date ) ) {
   758 	if ( ! empty( $date ) ) {
   690 		$query .= ' AND post_date = %s';
   759 		$query .= ' AND post_date = %s';
   691 		$args[] = $post_date;
   760 		$args[] = $post_date;
   692 	}
   761 	}
   693 
   762 
   694 	if ( !empty ( $title ) ) {
   763 	if ( ! empty( $title ) ) {
   695 		$query .= ' AND post_title = %s';
   764 		$query .= ' AND post_title = %s';
   696 		$args[] = $post_title;
   765 		$args[] = $post_title;
   697 	}
   766 	}
   698 
   767 
   699 	if ( !empty ( $content ) ) {
   768 	if ( ! empty( $content ) ) {
   700 		$query .= ' AND post_content = %s';
   769 		$query .= ' AND post_content = %s';
   701 		$args[] = $post_content;
   770 		$args[] = $post_content;
   702 	}
   771 	}
   703 
   772 
   704 	if ( !empty ( $args ) )
   773 	if ( ! empty( $type ) ) {
   705 		return (int) $wpdb->get_var( $wpdb->prepare($query, $args) );
   774 		$query .= ' AND post_type = %s';
       
   775 		$args[] = $post_type;
       
   776 	}
       
   777 
       
   778 	if ( ! empty( $args ) ) {
       
   779 		return (int) $wpdb->get_var( $wpdb->prepare( $query, $args ) );
       
   780 	}
   706 
   781 
   707 	return 0;
   782 	return 0;
   708 }
   783 }
   709 
   784 
   710 /**
   785 /**
   715  * @global WP_User $current_user
   790  * @global WP_User $current_user
   716  *
   791  *
   717  * @return int|WP_Error
   792  * @return int|WP_Error
   718  */
   793  */
   719 function wp_write_post() {
   794 function wp_write_post() {
   720 	if ( isset($_POST['post_type']) )
   795 	if ( isset( $_POST['post_type'] ) ) {
   721 		$ptype = get_post_type_object($_POST['post_type']);
   796 		$ptype = get_post_type_object( $_POST['post_type'] );
   722 	else
   797 	} else {
   723 		$ptype = get_post_type_object('post');
   798 		$ptype = get_post_type_object( 'post' );
   724 
   799 	}
   725 	if ( !current_user_can( $ptype->cap->edit_posts ) ) {
   800 
   726 		if ( 'page' == $ptype->name )
   801 	if ( ! current_user_can( $ptype->cap->edit_posts ) ) {
       
   802 		if ( 'page' == $ptype->name ) {
   727 			return new WP_Error( 'edit_pages', __( 'Sorry, you are not allowed to create pages on this site.' ) );
   803 			return new WP_Error( 'edit_pages', __( 'Sorry, you are not allowed to create pages on this site.' ) );
   728 		else
   804 		} else {
   729 			return new WP_Error( 'edit_posts', __( 'Sorry, you are not allowed to create posts or drafts on this site.' ) );
   805 			return new WP_Error( 'edit_posts', __( 'Sorry, you are not allowed to create posts or drafts on this site.' ) );
       
   806 		}
   730 	}
   807 	}
   731 
   808 
   732 	$_POST['post_mime_type'] = '';
   809 	$_POST['post_mime_type'] = '';
   733 
   810 
   734 	// Clear out any data in internal vars.
   811 	// Clear out any data in internal vars.
   735 	unset( $_POST['filter'] );
   812 	unset( $_POST['filter'] );
   736 
   813 
   737 	// Edit don't write if we have a post id.
   814 	// Edit don't write if we have a post id.
   738 	if ( isset( $_POST['post_ID'] ) )
   815 	if ( isset( $_POST['post_ID'] ) ) {
   739 		return edit_post();
   816 		return edit_post();
   740 
   817 	}
   741 	if ( isset($_POST['visibility']) ) {
   818 
       
   819 	if ( isset( $_POST['visibility'] ) ) {
   742 		switch ( $_POST['visibility'] ) {
   820 		switch ( $_POST['visibility'] ) {
   743 			case 'public' :
   821 			case 'public':
   744 				$_POST['post_password'] = '';
   822 				$_POST['post_password'] = '';
   745 				break;
   823 				break;
   746 			case 'password' :
   824 			case 'password':
   747 				unset( $_POST['sticky'] );
   825 				unset( $_POST['sticky'] );
   748 				break;
   826 				break;
   749 			case 'private' :
   827 			case 'private':
   750 				$_POST['post_status'] = 'private';
   828 				$_POST['post_status']   = 'private';
   751 				$_POST['post_password'] = '';
   829 				$_POST['post_password'] = '';
   752 				unset( $_POST['sticky'] );
   830 				unset( $_POST['sticky'] );
   753 				break;
   831 				break;
   754 		}
   832 		}
   755 	}
   833 	}
   756 
   834 
   757 	$translated = _wp_translate_postdata( false );
   835 	$translated = _wp_translate_postdata( false );
   758 	if ( is_wp_error($translated) )
   836 	if ( is_wp_error( $translated ) ) {
   759 		return $translated;
   837 		return $translated;
       
   838 	}
       
   839 	$translated = _wp_get_allowed_postdata( $translated );
   760 
   840 
   761 	// Create the post.
   841 	// Create the post.
   762 	$post_ID = wp_insert_post( $_POST );
   842 	$post_ID = wp_insert_post( $translated );
   763 	if ( is_wp_error( $post_ID ) )
   843 	if ( is_wp_error( $post_ID ) ) {
   764 		return $post_ID;
   844 		return $post_ID;
   765 
   845 	}
   766 	if ( empty($post_ID) )
   846 
       
   847 	if ( empty( $post_ID ) ) {
   767 		return 0;
   848 		return 0;
       
   849 	}
   768 
   850 
   769 	add_meta( $post_ID );
   851 	add_meta( $post_ID );
   770 
   852 
   771 	add_post_meta( $post_ID, '_edit_last', $GLOBALS['current_user']->ID );
   853 	add_post_meta( $post_ID, '_edit_last', $GLOBALS['current_user']->ID );
   772 
   854 
   785  *
   867  *
   786  * @return int|null
   868  * @return int|null
   787  */
   869  */
   788 function write_post() {
   870 function write_post() {
   789 	$result = wp_write_post();
   871 	$result = wp_write_post();
   790 	if ( is_wp_error( $result ) )
   872 	if ( is_wp_error( $result ) ) {
   791 		wp_die( $result->get_error_message() );
   873 		wp_die( $result->get_error_message() );
   792 	else
   874 	} else {
   793 		return $result;
   875 		return $result;
       
   876 	}
   794 }
   877 }
   795 
   878 
   796 //
   879 //
   797 // Post Meta
   880 // Post Meta
   798 //
   881 //
   806  * @return int|bool
   889  * @return int|bool
   807  */
   890  */
   808 function add_meta( $post_ID ) {
   891 function add_meta( $post_ID ) {
   809 	$post_ID = (int) $post_ID;
   892 	$post_ID = (int) $post_ID;
   810 
   893 
   811 	$metakeyselect = isset($_POST['metakeyselect']) ? wp_unslash( trim( $_POST['metakeyselect'] ) ) : '';
   894 	$metakeyselect = isset( $_POST['metakeyselect'] ) ? wp_unslash( trim( $_POST['metakeyselect'] ) ) : '';
   812 	$metakeyinput = isset($_POST['metakeyinput']) ? wp_unslash( trim( $_POST['metakeyinput'] ) ) : '';
   895 	$metakeyinput  = isset( $_POST['metakeyinput'] ) ? wp_unslash( trim( $_POST['metakeyinput'] ) ) : '';
   813 	$metavalue = isset($_POST['metavalue']) ? $_POST['metavalue'] : '';
   896 	$metavalue     = isset( $_POST['metavalue'] ) ? $_POST['metavalue'] : '';
   814 	if ( is_string( $metavalue ) )
   897 	if ( is_string( $metavalue ) ) {
   815 		$metavalue = trim( $metavalue );
   898 		$metavalue = trim( $metavalue );
   816 
   899 	}
   817 	if ( ('0' === $metavalue || ! empty ( $metavalue ) ) && ( ( ( '#NONE#' != $metakeyselect ) && !empty ( $metakeyselect) ) || !empty ( $metakeyinput ) ) ) {
   900 
       
   901 	if ( ( ( '#NONE#' != $metakeyselect ) && ! empty( $metakeyselect ) ) || ! empty( $metakeyinput ) ) {
   818 		/*
   902 		/*
   819 		 * We have a key/value pair. If both the select and the input
   903 		 * We have a key/value pair. If both the select and the input
   820 		 * for the key have data, the input takes precedence.
   904 		 * for the key have data, the input takes precedence.
   821 		 */
   905 		 */
   822  		if ( '#NONE#' != $metakeyselect )
   906 		if ( '#NONE#' != $metakeyselect ) {
   823 			$metakey = $metakeyselect;
   907 			$metakey = $metakeyselect;
   824 
   908 		}
   825 		if ( $metakeyinput )
   909 
       
   910 		if ( $metakeyinput ) {
   826 			$metakey = $metakeyinput; // default
   911 			$metakey = $metakeyinput; // default
   827 
   912 		}
   828 		if ( is_protected_meta( $metakey, 'post' ) || ! current_user_can( 'add_post_meta', $post_ID, $metakey ) )
   913 
       
   914 		if ( is_protected_meta( $metakey, 'post' ) || ! current_user_can( 'add_post_meta', $post_ID, $metakey ) ) {
   829 			return false;
   915 			return false;
       
   916 		}
   830 
   917 
   831 		$metakey = wp_slash( $metakey );
   918 		$metakey = wp_slash( $metakey );
   832 
   919 
   833 		return add_post_meta( $post_ID, $metakey, $metavalue );
   920 		return add_post_meta( $post_ID, $metakey, $metavalue );
   834 	}
   921 	}
   843  *
   930  *
   844  * @param int $mid
   931  * @param int $mid
   845  * @return bool
   932  * @return bool
   846  */
   933  */
   847 function delete_meta( $mid ) {
   934 function delete_meta( $mid ) {
   848 	return delete_metadata_by_mid( 'post' , $mid );
   935 	return delete_metadata_by_mid( 'post', $mid );
   849 }
   936 }
   850 
   937 
   851 /**
   938 /**
   852  * Get a list of previously defined keys.
   939  * Get a list of previously defined keys.
   853  *
   940  *
   858  * @return mixed
   945  * @return mixed
   859  */
   946  */
   860 function get_meta_keys() {
   947 function get_meta_keys() {
   861 	global $wpdb;
   948 	global $wpdb;
   862 
   949 
   863 	$keys = $wpdb->get_col( "
   950 	$keys = $wpdb->get_col(
       
   951 		"
   864 			SELECT meta_key
   952 			SELECT meta_key
   865 			FROM $wpdb->postmeta
   953 			FROM $wpdb->postmeta
   866 			GROUP BY meta_key
   954 			GROUP BY meta_key
   867 			ORDER BY meta_key" );
   955 			ORDER BY meta_key"
       
   956 	);
   868 
   957 
   869 	return $keys;
   958 	return $keys;
   870 }
   959 }
   871 
   960 
   872 /**
   961 /**
   892  * @return mixed
   981  * @return mixed
   893  */
   982  */
   894 function has_meta( $postid ) {
   983 function has_meta( $postid ) {
   895 	global $wpdb;
   984 	global $wpdb;
   896 
   985 
   897 	return $wpdb->get_results( $wpdb->prepare("SELECT meta_key, meta_value, meta_id, post_id
   986 	return $wpdb->get_results(
       
   987 		$wpdb->prepare(
       
   988 			"SELECT meta_key, meta_value, meta_id, post_id
   898 			FROM $wpdb->postmeta WHERE post_id = %d
   989 			FROM $wpdb->postmeta WHERE post_id = %d
   899 			ORDER BY meta_key,meta_id", $postid), ARRAY_A );
   990 			ORDER BY meta_key,meta_id",
       
   991 			$postid
       
   992 		),
       
   993 		ARRAY_A
       
   994 	);
   900 }
   995 }
   901 
   996 
   902 /**
   997 /**
   903  * Update post meta data by meta ID.
   998  * Update post meta data by meta ID.
   904  *
   999  *
   908  * @param string $meta_key Expect Slashed
  1003  * @param string $meta_key Expect Slashed
   909  * @param string $meta_value Expect Slashed
  1004  * @param string $meta_value Expect Slashed
   910  * @return bool
  1005  * @return bool
   911  */
  1006  */
   912 function update_meta( $meta_id, $meta_key, $meta_value ) {
  1007 function update_meta( $meta_id, $meta_key, $meta_value ) {
   913 	$meta_key = wp_unslash( $meta_key );
  1008 	$meta_key   = wp_unslash( $meta_key );
   914 	$meta_value = wp_unslash( $meta_value );
  1009 	$meta_value = wp_unslash( $meta_value );
   915 
  1010 
   916 	return update_metadata_by_mid( 'post', $meta_id, $meta_value, $meta_key );
  1011 	return update_metadata_by_mid( 'post', $meta_id, $meta_value, $meta_key );
   917 }
  1012 }
   918 
  1013 
   928  *
  1023  *
   929  * @param int|object $post Post ID or post object.
  1024  * @param int|object $post Post ID or post object.
   930  * @return void|int|WP_Error Void if nothing fixed. 0 or WP_Error on update failure. The post ID on update success.
  1025  * @return void|int|WP_Error Void if nothing fixed. 0 or WP_Error on update failure. The post ID on update success.
   931  */
  1026  */
   932 function _fix_attachment_links( $post ) {
  1027 function _fix_attachment_links( $post ) {
   933 	$post = get_post( $post, ARRAY_A );
  1028 	$post    = get_post( $post, ARRAY_A );
   934 	$content = $post['post_content'];
  1029 	$content = $post['post_content'];
   935 
  1030 
   936 	// Don't run if no pretty permalinks or post is not published, scheduled, or privately published.
  1031 	// Don't run if no pretty permalinks or post is not published, scheduled, or privately published.
   937 	if ( ! get_option( 'permalink_structure' ) || ! in_array( $post['post_status'], array( 'publish', 'future', 'private' ) ) )
  1032 	if ( ! get_option( 'permalink_structure' ) || ! in_array( $post['post_status'], array( 'publish', 'future', 'private' ) ) ) {
   938 		return;
  1033 		return;
       
  1034 	}
   939 
  1035 
   940 	// Short if there aren't any links or no '?attachment_id=' strings (strpos cannot be zero)
  1036 	// Short if there aren't any links or no '?attachment_id=' strings (strpos cannot be zero)
   941 	if ( !strpos($content, '?attachment_id=') || !preg_match_all( '/<a ([^>]+)>[\s\S]+?<\/a>/', $content, $link_matches ) )
  1037 	if ( ! strpos( $content, '?attachment_id=' ) || ! preg_match_all( '/<a ([^>]+)>[\s\S]+?<\/a>/', $content, $link_matches ) ) {
   942 		return;
  1038 		return;
   943 
  1039 	}
   944 	$site_url = get_bloginfo('url');
  1040 
   945 	$site_url = substr( $site_url, (int) strpos($site_url, '://') ); // remove the http(s)
  1041 	$site_url = get_bloginfo( 'url' );
   946 	$replace = '';
  1042 	$site_url = substr( $site_url, (int) strpos( $site_url, '://' ) ); // remove the http(s)
       
  1043 	$replace  = '';
   947 
  1044 
   948 	foreach ( $link_matches[1] as $key => $value ) {
  1045 	foreach ( $link_matches[1] as $key => $value ) {
   949 		if ( !strpos($value, '?attachment_id=') || !strpos($value, 'wp-att-')
  1046 		if ( ! strpos( $value, '?attachment_id=' ) || ! strpos( $value, 'wp-att-' )
   950 			|| !preg_match( '/href=(["\'])[^"\']*\?attachment_id=(\d+)[^"\']*\\1/', $value, $url_match )
  1047 			|| ! preg_match( '/href=(["\'])[^"\']*\?attachment_id=(\d+)[^"\']*\\1/', $value, $url_match )
   951 			|| !preg_match( '/rel=["\'][^"\']*wp-att-(\d+)/', $value, $rel_match ) )
  1048 			|| ! preg_match( '/rel=["\'][^"\']*wp-att-(\d+)/', $value, $rel_match ) ) {
   952 				continue;
  1049 				continue;
   953 
  1050 		}
   954 		$quote = $url_match[1]; // the quote (single or double)
  1051 
       
  1052 		$quote  = $url_match[1]; // the quote (single or double)
   955 		$url_id = (int) $url_match[2];
  1053 		$url_id = (int) $url_match[2];
   956 		$rel_id = (int) $rel_match[1];
  1054 		$rel_id = (int) $rel_match[1];
   957 
  1055 
   958 		if ( !$url_id || !$rel_id || $url_id != $rel_id || strpos($url_match[0], $site_url) === false )
  1056 		if ( ! $url_id || ! $rel_id || $url_id != $rel_id || strpos( $url_match[0], $site_url ) === false ) {
   959 			continue;
  1057 			continue;
   960 
  1058 		}
   961 		$link = $link_matches[0][$key];
  1059 
       
  1060 		$link    = $link_matches[0][ $key ];
   962 		$replace = str_replace( $url_match[0], 'href=' . $quote . get_attachment_link( $url_id ) . $quote, $link );
  1061 		$replace = str_replace( $url_match[0], 'href=' . $quote . get_attachment_link( $url_id ) . $quote, $link );
   963 
  1062 
   964 		$content = str_replace( $link, $replace, $content );
  1063 		$content = str_replace( $link, $replace, $content );
   965 	}
  1064 	}
   966 
  1065 
   967 	if ( $replace ) {
  1066 	if ( $replace ) {
   968 		$post['post_content'] = $content;
  1067 		$post['post_content'] = $content;
   969 		// Escape data pulled from DB.
  1068 		// Escape data pulled from DB.
   970 		$post = add_magic_quotes($post);
  1069 		$post = add_magic_quotes( $post );
   971 
  1070 
   972 		return wp_update_post($post);
  1071 		return wp_update_post( $post );
   973 	}
  1072 	}
   974 }
  1073 }
   975 
  1074 
   976 /**
  1075 /**
   977  * Get all the possible statuses for a post_type
  1076  * Get all the possible statuses for a post_type
   979  * @since 2.5.0
  1078  * @since 2.5.0
   980  *
  1079  *
   981  * @param string $type The post_type you want the statuses for
  1080  * @param string $type The post_type you want the statuses for
   982  * @return array As array of all the statuses for the supplied post type
  1081  * @return array As array of all the statuses for the supplied post type
   983  */
  1082  */
   984 function get_available_post_statuses($type = 'post') {
  1083 function get_available_post_statuses( $type = 'post' ) {
   985 	$stati = wp_count_posts($type);
  1084 	$stati = wp_count_posts( $type );
   986 
  1085 
   987 	return array_keys(get_object_vars($stati));
  1086 	return array_keys( get_object_vars( $stati ) );
   988 }
  1087 }
   989 
  1088 
   990 /**
  1089 /**
   991  * Run the wp query to fetch the posts for listing on the edit posts page
  1090  * Run the wp query to fetch the posts for listing on the edit posts page
   992  *
  1091  *
   994  *
  1093  *
   995  * @param array|bool $q Array of query variables to use to build the query or false to use $_GET superglobal.
  1094  * @param array|bool $q Array of query variables to use to build the query or false to use $_GET superglobal.
   996  * @return array
  1095  * @return array
   997  */
  1096  */
   998 function wp_edit_posts_query( $q = false ) {
  1097 function wp_edit_posts_query( $q = false ) {
   999 	if ( false === $q )
  1098 	if ( false === $q ) {
  1000 		$q = $_GET;
  1099 		$q = $_GET;
  1001 	$q['m'] = isset($q['m']) ? (int) $q['m'] : 0;
  1100 	}
  1002 	$q['cat'] = isset($q['cat']) ? (int) $q['cat'] : 0;
  1101 	$q['m']     = isset( $q['m'] ) ? (int) $q['m'] : 0;
  1003 	$post_stati  = get_post_stati();
  1102 	$q['cat']   = isset( $q['cat'] ) ? (int) $q['cat'] : 0;
  1004 
  1103 	$post_stati = get_post_stati();
  1005 	if ( isset($q['post_type']) && in_array( $q['post_type'], get_post_types() ) )
  1104 
       
  1105 	if ( isset( $q['post_type'] ) && in_array( $q['post_type'], get_post_types() ) ) {
  1006 		$post_type = $q['post_type'];
  1106 		$post_type = $q['post_type'];
  1007 	else
  1107 	} else {
  1008 		$post_type = 'post';
  1108 		$post_type = 'post';
  1009 
  1109 	}
  1010 	$avail_post_stati = get_available_post_statuses($post_type);
  1110 
  1011 
  1111 	$avail_post_stati = get_available_post_statuses( $post_type );
  1012 	if ( isset($q['post_status']) && in_array( $q['post_status'], $post_stati ) ) {
  1112 	$post_status      = '';
       
  1113 	$perm             = '';
       
  1114 
       
  1115 	if ( isset( $q['post_status'] ) && in_array( $q['post_status'], $post_stati ) ) {
  1013 		$post_status = $q['post_status'];
  1116 		$post_status = $q['post_status'];
  1014 		$perm = 'readable';
  1117 		$perm        = 'readable';
  1015 	}
  1118 	}
       
  1119 
       
  1120 	$orderby = '';
  1016 
  1121 
  1017 	if ( isset( $q['orderby'] ) ) {
  1122 	if ( isset( $q['orderby'] ) ) {
  1018 		$orderby = $q['orderby'];
  1123 		$orderby = $q['orderby'];
  1019 	} elseif ( isset( $q['post_status'] ) && in_array( $q['post_status'], array( 'pending', 'draft' ) ) ) {
  1124 	} elseif ( isset( $q['post_status'] ) && in_array( $q['post_status'], array( 'pending', 'draft' ) ) ) {
  1020 		$orderby = 'modified';
  1125 		$orderby = 'modified';
  1021 	}
  1126 	}
  1022 
  1127 
       
  1128 	$order = '';
       
  1129 
  1023 	if ( isset( $q['order'] ) ) {
  1130 	if ( isset( $q['order'] ) ) {
  1024 		$order = $q['order'];
  1131 		$order = $q['order'];
  1025 	} elseif ( isset( $q['post_status'] ) && 'pending' == $q['post_status'] ) {
  1132 	} elseif ( isset( $q['post_status'] ) && 'pending' == $q['post_status'] ) {
  1026 		$order = 'ASC';
  1133 		$order = 'ASC';
  1027 	}
  1134 	}
  1028 
  1135 
  1029 	$per_page = "edit_{$post_type}_per_page";
  1136 	$per_page       = "edit_{$post_type}_per_page";
  1030 	$posts_per_page = (int) get_user_option( $per_page );
  1137 	$posts_per_page = (int) get_user_option( $per_page );
  1031 	if ( empty( $posts_per_page ) || $posts_per_page < 1 )
  1138 	if ( empty( $posts_per_page ) || $posts_per_page < 1 ) {
  1032 		$posts_per_page = 20;
  1139 		$posts_per_page = 20;
       
  1140 	}
  1033 
  1141 
  1034 	/**
  1142 	/**
  1035 	 * Filters the number of items per page to show for a specific 'per_page' type.
  1143 	 * Filters the number of items per page to show for a specific 'per_page' type.
  1036 	 *
  1144 	 *
  1037 	 * The dynamic portion of the hook name, `$post_type`, refers to the post type.
  1145 	 * The dynamic portion of the hook name, `$post_type`, refers to the post type.
  1054 	 * @param int    $posts_per_page Number of posts to be displayed. Default 20.
  1162 	 * @param int    $posts_per_page Number of posts to be displayed. Default 20.
  1055 	 * @param string $post_type      The post type.
  1163 	 * @param string $post_type      The post type.
  1056 	 */
  1164 	 */
  1057 	$posts_per_page = apply_filters( 'edit_posts_per_page', $posts_per_page, $post_type );
  1165 	$posts_per_page = apply_filters( 'edit_posts_per_page', $posts_per_page, $post_type );
  1058 
  1166 
  1059 	$query = compact('post_type', 'post_status', 'perm', 'order', 'orderby', 'posts_per_page');
  1167 	$query = compact( 'post_type', 'post_status', 'perm', 'order', 'orderby', 'posts_per_page' );
  1060 
  1168 
  1061 	// Hierarchical types require special args.
  1169 	// Hierarchical types require special args.
  1062 	if ( is_post_type_hierarchical( $post_type ) && !isset($orderby) ) {
  1170 	if ( is_post_type_hierarchical( $post_type ) && empty( $orderby ) ) {
  1063 		$query['orderby'] = 'menu_order title';
  1171 		$query['orderby']                = 'menu_order title';
  1064 		$query['order'] = 'asc';
  1172 		$query['order']                  = 'asc';
  1065 		$query['posts_per_page'] = -1;
  1173 		$query['posts_per_page']         = -1;
  1066 		$query['posts_per_archive_page'] = -1;
  1174 		$query['posts_per_archive_page'] = -1;
  1067 		$query['fields'] = 'id=>parent';
  1175 		$query['fields']                 = 'id=>parent';
  1068 	}
  1176 	}
  1069 
  1177 
  1070 	if ( ! empty( $q['show_sticky'] ) )
  1178 	if ( ! empty( $q['show_sticky'] ) ) {
  1071 		$query['post__in'] = (array) get_option( 'sticky_posts' );
  1179 		$query['post__in'] = (array) get_option( 'sticky_posts' );
       
  1180 	}
  1072 
  1181 
  1073 	wp( $query );
  1182 	wp( $query );
  1074 
  1183 
  1075 	return $avail_post_stati;
  1184 	return $avail_post_stati;
  1076 }
       
  1077 
       
  1078 /**
       
  1079  * Get all available post MIME types for a given post type.
       
  1080  *
       
  1081  * @since 2.5.0
       
  1082  *
       
  1083  * @global wpdb $wpdb WordPress database abstraction object.
       
  1084  *
       
  1085  * @param string $type
       
  1086  * @return mixed
       
  1087  */
       
  1088 function get_available_post_mime_types($type = 'attachment') {
       
  1089 	global $wpdb;
       
  1090 
       
  1091 	$types = $wpdb->get_col($wpdb->prepare("SELECT DISTINCT post_mime_type FROM $wpdb->posts WHERE post_type = %s", $type));
       
  1092 	return $types;
       
  1093 }
  1185 }
  1094 
  1186 
  1095 /**
  1187 /**
  1096  * Get the query variables for the current attachments request.
  1188  * Get the query variables for the current attachments request.
  1097  *
  1189  *
  1103  */
  1195  */
  1104 function wp_edit_attachments_query_vars( $q = false ) {
  1196 function wp_edit_attachments_query_vars( $q = false ) {
  1105 	if ( false === $q ) {
  1197 	if ( false === $q ) {
  1106 		$q = $_GET;
  1198 		$q = $_GET;
  1107 	}
  1199 	}
  1108 	$q['m']   = isset( $q['m'] ) ? (int) $q['m'] : 0;
  1200 	$q['m']         = isset( $q['m'] ) ? (int) $q['m'] : 0;
  1109 	$q['cat'] = isset( $q['cat'] ) ? (int) $q['cat'] : 0;
  1201 	$q['cat']       = isset( $q['cat'] ) ? (int) $q['cat'] : 0;
  1110 	$q['post_type'] = 'attachment';
  1202 	$q['post_type'] = 'attachment';
  1111 	$post_type = get_post_type_object( 'attachment' );
  1203 	$post_type      = get_post_type_object( 'attachment' );
  1112 	$states = 'inherit';
  1204 	$states         = 'inherit';
  1113 	if ( current_user_can( $post_type->cap->read_private_posts ) ) {
  1205 	if ( current_user_can( $post_type->cap->read_private_posts ) ) {
  1114 		$states .= ',private';
  1206 		$states .= ',private';
  1115 	}
  1207 	}
  1116 
  1208 
  1117 	$q['post_status'] = isset( $q['status'] ) && 'trash' == $q['status'] ? 'trash' : $states;
  1209 	$q['post_status'] = isset( $q['status'] ) && 'trash' == $q['status'] ? 'trash' : $states;
  1130 	 * @param int $media_per_page Number of media to list. Default 20.
  1222 	 * @param int $media_per_page Number of media to list. Default 20.
  1131 	 */
  1223 	 */
  1132 	$q['posts_per_page'] = apply_filters( 'upload_per_page', $media_per_page );
  1224 	$q['posts_per_page'] = apply_filters( 'upload_per_page', $media_per_page );
  1133 
  1225 
  1134 	$post_mime_types = get_post_mime_types();
  1226 	$post_mime_types = get_post_mime_types();
  1135 	if ( isset($q['post_mime_type']) && !array_intersect( (array) $q['post_mime_type'], array_keys($post_mime_types) ) ) {
  1227 	if ( isset( $q['post_mime_type'] ) && ! array_intersect( (array) $q['post_mime_type'], array_keys( $post_mime_types ) ) ) {
  1136 		unset($q['post_mime_type']);
  1228 		unset( $q['post_mime_type'] );
  1137 	}
  1229 	}
  1138 
  1230 
  1139 	foreach ( array_keys( $post_mime_types ) as $type ) {
  1231 	foreach ( array_keys( $post_mime_types ) as $type ) {
  1140 		if ( isset( $q['attachment-filter'] ) && "post_mime_type:$type" == $q['attachment-filter'] ) {
  1232 		if ( isset( $q['attachment-filter'] ) && "post_mime_type:$type" == $q['attachment-filter'] ) {
  1141 			$q['post_mime_type'] = $type;
  1233 			$q['post_mime_type'] = $type;
  1169  * @return array
  1261  * @return array
  1170  */
  1262  */
  1171 function wp_edit_attachments_query( $q = false ) {
  1263 function wp_edit_attachments_query( $q = false ) {
  1172 	wp( wp_edit_attachments_query_vars( $q ) );
  1264 	wp( wp_edit_attachments_query_vars( $q ) );
  1173 
  1265 
  1174 	$post_mime_types = get_post_mime_types();
  1266 	$post_mime_types       = get_post_mime_types();
  1175 	$avail_post_mime_types = get_available_post_mime_types( 'attachment' );
  1267 	$avail_post_mime_types = get_available_post_mime_types( 'attachment' );
  1176 
  1268 
  1177 	return array( $post_mime_types, $avail_post_mime_types );
  1269 	return array( $post_mime_types, $avail_post_mime_types );
  1178 }
  1270 }
  1179 
  1271 
  1180 /**
  1272 /**
  1181  * Returns the list of classes to be used by a meta box.
  1273  * Returns the list of classes to be used by a meta box.
  1182  *
  1274  *
  1183  * @since 2.5.0
  1275  * @since 2.5.0
  1184  *
  1276  *
  1185  * @param string $id
  1277  * @param string $box_id    Meta box ID (used in the 'id' attribute for the meta box).
  1186  * @param string $page
  1278  * @param string $screen_id The screen on which the meta box is shown.
  1187  * @return string
  1279  * @return string Space-separated string of class names.
  1188  */
  1280  */
  1189 function postbox_classes( $id, $page ) {
  1281 function postbox_classes( $box_id, $screen_id ) {
  1190 	if ( isset( $_GET['edit'] ) && $_GET['edit'] == $id ) {
  1282 	if ( isset( $_GET['edit'] ) && $_GET['edit'] == $box_id ) {
  1191 		$classes = array( '' );
  1283 		$classes = array( '' );
  1192 	} elseif ( $closed = get_user_option('closedpostboxes_'.$page ) ) {
  1284 	} elseif ( $closed = get_user_option( 'closedpostboxes_' . $screen_id ) ) {
  1193 		if ( !is_array( $closed ) ) {
  1285 		if ( ! is_array( $closed ) ) {
  1194 			$classes = array( '' );
  1286 			$classes = array( '' );
  1195 		} else {
  1287 		} else {
  1196 			$classes = in_array( $id, $closed ) ? array( 'closed' ) : array( '' );
  1288 			$classes = in_array( $box_id, $closed ) ? array( 'closed' ) : array( '' );
  1197 		}
  1289 		}
  1198 	} else {
  1290 	} else {
  1199 		$classes = array( '' );
  1291 		$classes = array( '' );
  1200 	}
  1292 	}
  1201 
  1293 
  1202 	/**
  1294 	/**
  1203 	 * Filters the postbox classes for a specific screen and screen ID combo.
  1295 	 * Filters the postbox classes for a specific screen and box ID combo.
  1204 	 *
  1296 	 *
  1205 	 * The dynamic portions of the hook name, `$page` and `$id`, refer to
  1297 	 * The dynamic portions of the hook name, `$screen_id` and `$box_id`, refer to
  1206 	 * the screen and screen ID, respectively.
  1298 	 * the screen ID and meta box ID, respectively.
  1207 	 *
  1299 	 *
  1208 	 * @since 3.2.0
  1300 	 * @since 3.2.0
  1209 	 *
  1301 	 *
  1210 	 * @param array $classes An array of postbox classes.
  1302 	 * @param string[] $classes An array of postbox classes.
  1211 	 */
  1303 	 */
  1212 	$classes = apply_filters( "postbox_classes_{$page}_{$id}", $classes );
  1304 	$classes = apply_filters( "postbox_classes_{$screen_id}_{$box_id}", $classes );
  1213 	return implode( ' ', $classes );
  1305 	return implode( ' ', $classes );
  1214 }
  1306 }
  1215 
  1307 
  1216 /**
  1308 /**
  1217  * Get a sample permalink based off of the post name.
  1309  * Get a sample permalink based off of the post name.
  1221  * @param int    $id    Post ID or post object.
  1313  * @param int    $id    Post ID or post object.
  1222  * @param string $title Optional. Title to override the post's current title when generating the post name. Default null.
  1314  * @param string $title Optional. Title to override the post's current title when generating the post name. Default null.
  1223  * @param string $name  Optional. Name to override the post name. Default null.
  1315  * @param string $name  Optional. Name to override the post name. Default null.
  1224  * @return array Array containing the sample permalink with placeholder for the post name, and the post name.
  1316  * @return array Array containing the sample permalink with placeholder for the post name, and the post name.
  1225  */
  1317  */
  1226 function get_sample_permalink($id, $title = null, $name = null) {
  1318 function get_sample_permalink( $id, $title = null, $name = null ) {
  1227 	$post = get_post( $id );
  1319 	$post = get_post( $id );
  1228 	if ( ! $post )
  1320 	if ( ! $post ) {
  1229 		return array( '', '' );
  1321 		return array( '', '' );
  1230 
  1322 	}
  1231 	$ptype = get_post_type_object($post->post_type);
  1323 
       
  1324 	$ptype = get_post_type_object( $post->post_type );
  1232 
  1325 
  1233 	$original_status = $post->post_status;
  1326 	$original_status = $post->post_status;
  1234 	$original_date = $post->post_date;
  1327 	$original_date   = $post->post_date;
  1235 	$original_name = $post->post_name;
  1328 	$original_name   = $post->post_name;
  1236 
  1329 
  1237 	// Hack: get_permalink() would return ugly permalink for drafts, so we will fake that our post is published.
  1330 	// Hack: get_permalink() would return ugly permalink for drafts, so we will fake that our post is published.
  1238 	if ( in_array( $post->post_status, array( 'draft', 'pending', 'future' ) ) ) {
  1331 	if ( in_array( $post->post_status, array( 'draft', 'pending', 'future' ) ) ) {
  1239 		$post->post_status = 'publish';
  1332 		$post->post_status = 'publish';
  1240 		$post->post_name = sanitize_title($post->post_name ? $post->post_name : $post->post_title, $post->ID);
  1333 		$post->post_name   = sanitize_title( $post->post_name ? $post->post_name : $post->post_title, $post->ID );
  1241 	}
  1334 	}
  1242 
  1335 
  1243 	// If the user wants to set a new name -- override the current one
  1336 	// If the user wants to set a new name -- override the current one
  1244 	// Note: if empty name is supplied -- use the title instead, see #6072
  1337 	// Note: if empty name is supplied -- use the title instead, see #6072
  1245 	if ( !is_null($name) )
  1338 	if ( ! is_null( $name ) ) {
  1246 		$post->post_name = sanitize_title($name ? $name : $title, $post->ID);
  1339 		$post->post_name = sanitize_title( $name ? $name : $title, $post->ID );
  1247 
  1340 	}
  1248 	$post->post_name = wp_unique_post_slug($post->post_name, $post->ID, $post->post_status, $post->post_type, $post->post_parent);
  1341 
       
  1342 	$post->post_name = wp_unique_post_slug( $post->post_name, $post->ID, $post->post_status, $post->post_type, $post->post_parent );
  1249 
  1343 
  1250 	$post->filter = 'sample';
  1344 	$post->filter = 'sample';
  1251 
  1345 
  1252 	$permalink = get_permalink($post, true);
  1346 	$permalink = get_permalink( $post, true );
  1253 
  1347 
  1254 	// Replace custom post_type Token with generic pagename token for ease of use.
  1348 	// Replace custom post_type Token with generic pagename token for ease of use.
  1255 	$permalink = str_replace("%$post->post_type%", '%pagename%', $permalink);
  1349 	$permalink = str_replace( "%$post->post_type%", '%pagename%', $permalink );
  1256 
  1350 
  1257 	// Handle page hierarchy
  1351 	// Handle page hierarchy
  1258 	if ( $ptype->hierarchical ) {
  1352 	if ( $ptype->hierarchical ) {
  1259 		$uri = get_page_uri($post);
  1353 		$uri = get_page_uri( $post );
  1260 		if ( $uri ) {
  1354 		if ( $uri ) {
  1261 			$uri = untrailingslashit($uri);
  1355 			$uri = untrailingslashit( $uri );
  1262 			$uri = strrev( stristr( strrev( $uri ), '/' ) );
  1356 			$uri = strrev( stristr( strrev( $uri ), '/' ) );
  1263 			$uri = untrailingslashit($uri);
  1357 			$uri = untrailingslashit( $uri );
  1264 		}
  1358 		}
  1265 
  1359 
  1266 		/** This filter is documented in wp-admin/edit-tag-form.php */
  1360 		/** This filter is documented in wp-admin/edit-tag-form.php */
  1267 		$uri = apply_filters( 'editable_slug', $uri, $post );
  1361 		$uri = apply_filters( 'editable_slug', $uri, $post );
  1268 		if ( !empty($uri) )
  1362 		if ( ! empty( $uri ) ) {
  1269 			$uri .= '/';
  1363 			$uri .= '/';
  1270 		$permalink = str_replace('%pagename%', "{$uri}%pagename%", $permalink);
  1364 		}
       
  1365 		$permalink = str_replace( '%pagename%', "{$uri}%pagename%", $permalink );
  1271 	}
  1366 	}
  1272 
  1367 
  1273 	/** This filter is documented in wp-admin/edit-tag-form.php */
  1368 	/** This filter is documented in wp-admin/edit-tag-form.php */
  1274 	$permalink = array( $permalink, apply_filters( 'editable_slug', $post->post_name, $post ) );
  1369 	$permalink         = array( $permalink, apply_filters( 'editable_slug', $post->post_name, $post ) );
  1275 	$post->post_status = $original_status;
  1370 	$post->post_status = $original_status;
  1276 	$post->post_date = $original_date;
  1371 	$post->post_date   = $original_date;
  1277 	$post->post_name = $original_name;
  1372 	$post->post_name   = $original_name;
  1278 	unset($post->filter);
  1373 	unset( $post->filter );
  1279 
  1374 
  1280 	/**
  1375 	/**
  1281 	 * Filters the sample permalink.
  1376 	 * Filters the sample permalink.
  1282 	 *
  1377 	 *
  1283 	 * @since 4.4.0
  1378 	 * @since 4.4.0
  1301  * @param string $new_slug  Optional. New slug. Default null.
  1396  * @param string $new_slug  Optional. New slug. Default null.
  1302  * @return string The HTML of the sample permalink slug editor.
  1397  * @return string The HTML of the sample permalink slug editor.
  1303  */
  1398  */
  1304 function get_sample_permalink_html( $id, $new_title = null, $new_slug = null ) {
  1399 function get_sample_permalink_html( $id, $new_title = null, $new_slug = null ) {
  1305 	$post = get_post( $id );
  1400 	$post = get_post( $id );
  1306 	if ( ! $post )
  1401 	if ( ! $post ) {
  1307 		return '';
  1402 		return '';
  1308 
  1403 	}
  1309 	list($permalink, $post_name) = get_sample_permalink($post->ID, $new_title, $new_slug);
  1404 
  1310 
  1405 	list($permalink, $post_name) = get_sample_permalink( $post->ID, $new_title, $new_slug );
  1311 	$view_link = false;
  1406 
       
  1407 	$view_link      = false;
  1312 	$preview_target = '';
  1408 	$preview_target = '';
  1313 
  1409 
  1314 	if ( current_user_can( 'read_post', $post->ID ) ) {
  1410 	if ( current_user_can( 'read_post', $post->ID ) ) {
  1315 		if ( 'draft' === $post->post_status || empty( $post->post_name ) ) {
  1411 		if ( 'draft' === $post->post_status || empty( $post->post_name ) ) {
  1316 			$view_link = get_preview_post_link( $post );
  1412 			$view_link      = get_preview_post_link( $post );
  1317 			$preview_target = " target='wp-preview-{$post->ID}'";
  1413 			$preview_target = " target='wp-preview-{$post->ID}'";
  1318 		} else {
  1414 		} else {
  1319 			if ( 'publish' === $post->post_status || 'attachment' === $post->post_type ) {
  1415 			if ( 'publish' === $post->post_status || 'attachment' === $post->post_type ) {
  1320 				$view_link = get_permalink( $post );
  1416 				$view_link = get_permalink( $post );
  1321 			} else {
  1417 			} else {
  1329 	if ( false === strpos( $permalink, '%postname%' ) && false === strpos( $permalink, '%pagename%' ) ) {
  1425 	if ( false === strpos( $permalink, '%postname%' ) && false === strpos( $permalink, '%pagename%' ) ) {
  1330 		$return = '<strong>' . __( 'Permalink:' ) . "</strong>\n";
  1426 		$return = '<strong>' . __( 'Permalink:' ) . "</strong>\n";
  1331 
  1427 
  1332 		if ( false !== $view_link ) {
  1428 		if ( false !== $view_link ) {
  1333 			$display_link = urldecode( $view_link );
  1429 			$display_link = urldecode( $view_link );
  1334 			$return .= '<a id="sample-permalink" href="' . esc_url( $view_link ) . '"' . $preview_target . '>' . esc_html( $display_link ) . "</a>\n";
  1430 			$return      .= '<a id="sample-permalink" href="' . esc_url( $view_link ) . '"' . $preview_target . '>' . esc_html( $display_link ) . "</a>\n";
  1335 		} else {
  1431 		} else {
  1336 			$return .= '<span id="sample-permalink">' . $permalink . "</span>\n";
  1432 			$return .= '<span id="sample-permalink">' . $permalink . "</span>\n";
  1337 		}
  1433 		}
  1338 
  1434 
  1339 		// Encourage a pretty permalink setting
  1435 		// Encourage a pretty permalink setting
  1340 		if ( '' == get_option( 'permalink_structure' ) && current_user_can( 'manage_options' ) && !( 'page' == get_option('show_on_front') && $id == get_option('page_on_front') ) ) {
  1436 		if ( '' == get_option( 'permalink_structure' ) && current_user_can( 'manage_options' ) && ! ( 'page' == get_option( 'show_on_front' ) && $id == get_option( 'page_on_front' ) ) ) {
  1341 			$return .= '<span id="change-permalinks"><a href="options-permalink.php" class="button button-small" target="_blank">' . __('Change Permalinks') . "</a></span>\n";
  1437 			$return .= '<span id="change-permalinks"><a href="options-permalink.php" class="button button-small" target="_blank">' . __( 'Change Permalinks' ) . "</a></span>\n";
  1342 		}
  1438 		}
  1343 	} else {
  1439 	} else {
  1344 		if ( mb_strlen( $post_name ) > 34 ) {
  1440 		if ( mb_strlen( $post_name ) > 34 ) {
  1345 			$post_name_abridged = mb_substr( $post_name, 0, 16 ) . '&hellip;' . mb_substr( $post_name, -16 );
  1441 			$post_name_abridged = mb_substr( $post_name, 0, 16 ) . '&hellip;' . mb_substr( $post_name, -16 );
  1346 		} else {
  1442 		} else {
  1347 			$post_name_abridged = $post_name;
  1443 			$post_name_abridged = $post_name;
  1348 		}
  1444 		}
  1349 
  1445 
  1350 		$post_name_html = '<span id="editable-post-name">' . esc_html( $post_name_abridged ) . '</span>';
  1446 		$post_name_html = '<span id="editable-post-name">' . esc_html( $post_name_abridged ) . '</span>';
  1351 		$display_link = str_replace( array( '%pagename%', '%postname%' ), $post_name_html, esc_html( urldecode( $permalink ) ) );
  1447 		$display_link   = str_replace( array( '%pagename%', '%postname%' ), $post_name_html, esc_html( urldecode( $permalink ) ) );
  1352 
  1448 
  1353 		$return = '<strong>' . __( 'Permalink:' ) . "</strong>\n";
  1449 		$return  = '<strong>' . __( 'Permalink:' ) . "</strong>\n";
  1354 		$return .= '<span id="sample-permalink"><a href="' . esc_url( $view_link ) . '"' . $preview_target . '>' . $display_link . "</a></span>\n";
  1450 		$return .= '<span id="sample-permalink"><a href="' . esc_url( $view_link ) . '"' . $preview_target . '>' . $display_link . "</a></span>\n";
  1355 		$return .= '&lrm;'; // Fix bi-directional text display defect in RTL languages.
  1451 		$return .= '&lrm;'; // Fix bi-directional text display defect in RTL languages.
  1356 		$return .= '<span id="edit-slug-buttons"><button type="button" class="edit-slug button button-small hide-if-no-js" aria-label="' . __( 'Edit permalink' ) . '">' . __( 'Edit' ) . "</button></span>\n";
  1452 		$return .= '<span id="edit-slug-buttons"><button type="button" class="edit-slug button button-small hide-if-no-js" aria-label="' . __( 'Edit permalink' ) . '">' . __( 'Edit' ) . "</button></span>\n";
  1357 		$return .= '<span id="editable-post-name-full">' . esc_html( $post_name ) . "</span>\n";
  1453 		$return .= '<span id="editable-post-name-full">' . esc_html( $post_name ) . "</span>\n";
  1358 	}
  1454 	}
  1389 	$post               = get_post( $post );
  1485 	$post               = get_post( $post );
  1390 	$post_type_object   = get_post_type_object( $post->post_type );
  1486 	$post_type_object   = get_post_type_object( $post->post_type );
  1391 	$set_thumbnail_link = '<p class="hide-if-no-js"><a href="%s" id="set-post-thumbnail"%s class="thickbox">%s</a></p>';
  1487 	$set_thumbnail_link = '<p class="hide-if-no-js"><a href="%s" id="set-post-thumbnail"%s class="thickbox">%s</a></p>';
  1392 	$upload_iframe_src  = get_upload_iframe_src( 'image', $post->ID );
  1488 	$upload_iframe_src  = get_upload_iframe_src( 'image', $post->ID );
  1393 
  1489 
  1394 	$content = sprintf( $set_thumbnail_link,
  1490 	$content = sprintf(
       
  1491 		$set_thumbnail_link,
  1395 		esc_url( $upload_iframe_src ),
  1492 		esc_url( $upload_iframe_src ),
  1396 		'', // Empty when there's no featured image set, `aria-describedby` attribute otherwise.
  1493 		'', // Empty when there's no featured image set, `aria-describedby` attribute otherwise.
  1397 		esc_html( $post_type_object->labels->set_featured_image )
  1494 		esc_html( $post_type_object->labels->set_featured_image )
  1398 	);
  1495 	);
  1399 
  1496 
  1420 		$size = apply_filters( 'admin_post_thumbnail_size', $size, $thumbnail_id, $post );
  1517 		$size = apply_filters( 'admin_post_thumbnail_size', $size, $thumbnail_id, $post );
  1421 
  1518 
  1422 		$thumbnail_html = wp_get_attachment_image( $thumbnail_id, $size );
  1519 		$thumbnail_html = wp_get_attachment_image( $thumbnail_id, $size );
  1423 
  1520 
  1424 		if ( ! empty( $thumbnail_html ) ) {
  1521 		if ( ! empty( $thumbnail_html ) ) {
  1425 			$content = sprintf( $set_thumbnail_link,
  1522 			$content  = sprintf(
       
  1523 				$set_thumbnail_link,
  1426 				esc_url( $upload_iframe_src ),
  1524 				esc_url( $upload_iframe_src ),
  1427 				' aria-describedby="set-post-thumbnail-desc"',
  1525 				' aria-describedby="set-post-thumbnail-desc"',
  1428 				$thumbnail_html
  1526 				$thumbnail_html
  1429 			);
  1527 			);
  1430 			$content .= '<p class="hide-if-no-js howto" id="set-post-thumbnail-desc">' . __( 'Click the image to edit or update' ) . '</p>';
  1528 			$content .= '<p class="hide-if-no-js howto" id="set-post-thumbnail-desc">' . __( 'Click the image to edit or update' ) . '</p>';
  1439 	 *
  1537 	 *
  1440 	 * @since 2.9.0
  1538 	 * @since 2.9.0
  1441 	 * @since 3.5.0 Added the `$post_id` parameter.
  1539 	 * @since 3.5.0 Added the `$post_id` parameter.
  1442 	 * @since 4.6.0 Added the `$thumbnail_id` parameter.
  1540 	 * @since 4.6.0 Added the `$thumbnail_id` parameter.
  1443 	 *
  1541 	 *
  1444 	 * @param string $content      Admin post thumbnail HTML markup.
  1542 	 * @param string   $content      Admin post thumbnail HTML markup.
  1445 	 * @param int    $post_id      Post ID.
  1543 	 * @param int      $post_id      Post ID.
  1446 	 * @param int    $thumbnail_id Thumbnail ID.
  1544 	 * @param int|null $thumbnail_id Thumbnail attachment ID, or null if there isn't one.
  1447 	 */
  1545 	 */
  1448 	return apply_filters( 'admin_post_thumbnail_html', $content, $post->ID, $thumbnail_id );
  1546 	return apply_filters( 'admin_post_thumbnail_html', $content, $post->ID, $thumbnail_id );
  1449 }
  1547 }
  1450 
  1548 
  1451 /**
  1549 /**
  1500 
  1598 
  1501 	if ( 0 == ( $user_id = get_current_user_id() ) ) {
  1599 	if ( 0 == ( $user_id = get_current_user_id() ) ) {
  1502 		return false;
  1600 		return false;
  1503 	}
  1601 	}
  1504 
  1602 
  1505 	$now = time();
  1603 	$now  = time();
  1506 	$lock = "$now:$user_id";
  1604 	$lock = "$now:$user_id";
  1507 
  1605 
  1508 	update_post_meta( $post->ID, '_edit_lock', $lock );
  1606 	update_post_meta( $post->ID, '_edit_lock', $lock );
  1509 
  1607 
  1510 	return array( $now, $user_id );
  1608 	return array( $now, $user_id );
  1515  *
  1613  *
  1516  * @since 2.8.5
  1614  * @since 2.8.5
  1517  * @return none
  1615  * @return none
  1518  */
  1616  */
  1519 function _admin_notice_post_locked() {
  1617 function _admin_notice_post_locked() {
  1520 	if ( ! $post = get_post() )
  1618 	if ( ! $post = get_post() ) {
  1521 		return;
  1619 		return;
       
  1620 	}
  1522 
  1621 
  1523 	$user = null;
  1622 	$user = null;
  1524 	if (  $user_id = wp_check_post_lock( $post->ID ) )
  1623 	if ( $user_id = wp_check_post_lock( $post->ID ) ) {
  1525 		$user = get_userdata( $user_id );
  1624 		$user = get_userdata( $user_id );
       
  1625 	}
  1526 
  1626 
  1527 	if ( $user ) {
  1627 	if ( $user ) {
  1528 
  1628 
  1529 		/**
  1629 		/**
  1530 		 * Filters whether to show the post locked dialog.
  1630 		 * Filters whether to show the post locked dialog.
  1535 		 *
  1635 		 *
  1536 		 * @param bool         $display Whether to display the dialog. Default true.
  1636 		 * @param bool         $display Whether to display the dialog. Default true.
  1537 		 * @param WP_Post      $post    Post object.
  1637 		 * @param WP_Post      $post    Post object.
  1538 		 * @param WP_User|bool $user    WP_User object on success, false otherwise.
  1638 		 * @param WP_User|bool $user    WP_User object on success, false otherwise.
  1539 		 */
  1639 		 */
  1540 		if ( ! apply_filters( 'show_post_locked_dialog', true, $post, $user ) )
  1640 		if ( ! apply_filters( 'show_post_locked_dialog', true, $post, $user ) ) {
  1541 			return;
  1641 			return;
       
  1642 		}
  1542 
  1643 
  1543 		$locked = true;
  1644 		$locked = true;
  1544 	} else {
  1645 	} else {
  1545 		$locked = false;
  1646 		$locked = false;
  1546 	}
  1647 	}
  1547 
  1648 
  1548 	if ( $locked && ( $sendback = wp_get_referer() ) &&
  1649 	if ( $locked && ( $sendback = wp_get_referer() ) &&
  1549 		false === strpos( $sendback, 'post.php' ) && false === strpos( $sendback, 'post-new.php' ) ) {
  1650 		false === strpos( $sendback, 'post.php' ) && false === strpos( $sendback, 'post-new.php' ) ) {
  1550 
  1651 
  1551 		$sendback_text = __('Go back');
  1652 		$sendback_text = __( 'Go back' );
  1552 	} else {
  1653 	} else {
  1553 		$sendback = admin_url( 'edit.php' );
  1654 		$sendback = admin_url( 'edit.php' );
  1554 
  1655 
  1555 		if ( 'post' != $post->post_type )
  1656 		if ( 'post' != $post->post_type ) {
  1556 			$sendback = add_query_arg( 'post_type', $post->post_type, $sendback );
  1657 			$sendback = add_query_arg( 'post_type', $post->post_type, $sendback );
       
  1658 		}
  1557 
  1659 
  1558 		$sendback_text = get_post_type_object( $post->post_type )->labels->all_items;
  1660 		$sendback_text = get_post_type_object( $post->post_type )->labels->all_items;
  1559 	}
  1661 	}
  1560 
  1662 
  1561 	$hidden = $locked ? '' : ' hidden';
  1663 	$hidden = $locked ? '' : ' hidden';
  1569 	if ( $locked ) {
  1671 	if ( $locked ) {
  1570 		$query_args = array();
  1672 		$query_args = array();
  1571 		if ( get_post_type_object( $post->post_type )->public ) {
  1673 		if ( get_post_type_object( $post->post_type )->public ) {
  1572 			if ( 'publish' == $post->post_status || $user->ID != $post->post_author ) {
  1674 			if ( 'publish' == $post->post_status || $user->ID != $post->post_author ) {
  1573 				// Latest content is in autosave
  1675 				// Latest content is in autosave
  1574 				$nonce = wp_create_nonce( 'post_preview_' . $post->ID );
  1676 				$nonce                       = wp_create_nonce( 'post_preview_' . $post->ID );
  1575 				$query_args['preview_id'] = $post->ID;
  1677 				$query_args['preview_id']    = $post->ID;
  1576 				$query_args['preview_nonce'] = $nonce;
  1678 				$query_args['preview_nonce'] = $nonce;
  1577 			}
  1679 			}
  1578 		}
  1680 		}
  1579 
  1681 
  1580 		$preview_link = get_preview_post_link( $post->ID, $query_args );
  1682 		$preview_link = get_preview_post_link( $post->ID, $query_args );
  1597 		?>
  1699 		?>
  1598 		<div class="post-locked-message">
  1700 		<div class="post-locked-message">
  1599 		<div class="post-locked-avatar"><?php echo get_avatar( $user->ID, 64 ); ?></div>
  1701 		<div class="post-locked-avatar"><?php echo get_avatar( $user->ID, 64 ); ?></div>
  1600 		<p class="currently-editing wp-tab-first" tabindex="0">
  1702 		<p class="currently-editing wp-tab-first" tabindex="0">
  1601 		<?php
  1703 		<?php
  1602 			if ( $override ) {
  1704 		if ( $override ) {
  1603 				/* translators: %s: user's display name */
  1705 			/* translators: %s: user's display name */
  1604 				printf( __( '%s is already editing this post. Do you want to take over?' ), esc_html( $user->display_name ) );
  1706 			printf( __( '%s is already editing this post. Do you want to take over?' ), esc_html( $user->display_name ) );
  1605 			} else {
  1707 		} else {
  1606 				/* translators: %s: user's display name */
  1708 			/* translators: %s: user's display name */
  1607 				printf( __( '%s is already editing this post.' ), esc_html( $user->display_name ) );
  1709 			printf( __( '%s is already editing this post.' ), esc_html( $user->display_name ) );
  1608 			}
  1710 		}
  1609 		?>
  1711 		?>
  1610 		</p>
  1712 		</p>
  1611 		<?php
  1713 		<?php
  1612 		/**
  1714 		/**
  1613 		 * Fires inside the post locked dialog before the buttons are displayed.
  1715 		 * Fires inside the post locked dialog before the buttons are displayed.
  1619 		do_action( 'post_locked_dialog', $post );
  1721 		do_action( 'post_locked_dialog', $post );
  1620 		?>
  1722 		?>
  1621 		<p>
  1723 		<p>
  1622 		<a class="button" href="<?php echo esc_url( $sendback ); ?>"><?php echo $sendback_text; ?></a>
  1724 		<a class="button" href="<?php echo esc_url( $sendback ); ?>"><?php echo $sendback_text; ?></a>
  1623 		<?php if ( $preview_link ) { ?>
  1725 		<?php if ( $preview_link ) { ?>
  1624 		<a class="button<?php echo $tab_last; ?>" href="<?php echo esc_url( $preview_link ); ?>"><?php _e('Preview'); ?></a>
  1726 		<a class="button<?php echo $tab_last; ?>" href="<?php echo esc_url( $preview_link ); ?>"><?php _e( 'Preview' ); ?></a>
  1625 		<?php
  1727 			<?php
  1626 		}
  1728 		}
  1627 
  1729 
  1628 		// Allow plugins to prevent some users overriding the post lock
  1730 		// Allow plugins to prevent some users overriding the post lock
  1629 		if ( $override ) {
  1731 		if ( $override ) {
  1630 			?>
  1732 			?>
  1631 			<a class="button button-primary wp-tab-last" href="<?php echo esc_url( add_query_arg( 'get-post-lock', '1', wp_nonce_url( get_edit_post_link( $post->ID, 'url' ), 'lock-post_' . $post->ID ) ) ); ?>"><?php _e('Take over'); ?></a>
  1733 	<a class="button button-primary wp-tab-last" href="<?php echo esc_url( add_query_arg( 'get-post-lock', '1', wp_nonce_url( get_edit_post_link( $post->ID, 'url' ), 'lock-post_' . $post->ID ) ) ); ?>"><?php _e( 'Take over' ); ?></a>
  1632 			<?php
  1734 			<?php
  1633 		}
  1735 		}
  1634 
  1736 
  1635 		?>
  1737 		?>
  1636 		</p>
  1738 		</p>
  1641 		<div class="post-taken-over">
  1743 		<div class="post-taken-over">
  1642 			<div class="post-locked-avatar"></div>
  1744 			<div class="post-locked-avatar"></div>
  1643 			<p class="wp-tab-first" tabindex="0">
  1745 			<p class="wp-tab-first" tabindex="0">
  1644 			<span class="currently-editing"></span><br />
  1746 			<span class="currently-editing"></span><br />
  1645 			<span class="locked-saving hidden"><img src="<?php echo esc_url( admin_url( 'images/spinner-2x.gif' ) ); ?>" width="16" height="16" alt="" /> <?php _e( 'Saving revision&hellip;' ); ?></span>
  1747 			<span class="locked-saving hidden"><img src="<?php echo esc_url( admin_url( 'images/spinner-2x.gif' ) ); ?>" width="16" height="16" alt="" /> <?php _e( 'Saving revision&hellip;' ); ?></span>
  1646 			<span class="locked-saved hidden"><?php _e('Your latest changes were saved as a revision.'); ?></span>
  1748 			<span class="locked-saved hidden"><?php _e( 'Your latest changes were saved as a revision.' ); ?></span>
  1647 			</p>
  1749 			</p>
  1648 			<?php
  1750 			<?php
  1649 			/**
  1751 			/**
  1650 			 * Fires inside the dialog displayed when a user has lost the post lock.
  1752 			 * Fires inside the dialog displayed when a user has lost the post lock.
  1651 			 *
  1753 			 *
  1674  * @param mixed $post_data Associative array containing the post data or int post ID.
  1776  * @param mixed $post_data Associative array containing the post data or int post ID.
  1675  * @return mixed The autosave revision ID. WP_Error or 0 on error.
  1777  * @return mixed The autosave revision ID. WP_Error or 0 on error.
  1676  */
  1778  */
  1677 function wp_create_post_autosave( $post_data ) {
  1779 function wp_create_post_autosave( $post_data ) {
  1678 	if ( is_numeric( $post_data ) ) {
  1780 	if ( is_numeric( $post_data ) ) {
  1679 		$post_id = $post_data;
  1781 		$post_id   = $post_data;
  1680 		$post_data = $_POST;
  1782 		$post_data = $_POST;
  1681 	} else {
  1783 	} else {
  1682 		$post_id = (int) $post_data['post_ID'];
  1784 		$post_id = (int) $post_data['post_ID'];
  1683 	}
  1785 	}
  1684 
  1786 
  1685 	$post_data = _wp_translate_postdata( true, $post_data );
  1787 	$post_data = _wp_translate_postdata( true, $post_data );
  1686 	if ( is_wp_error( $post_data ) )
  1788 	if ( is_wp_error( $post_data ) ) {
  1687 		return $post_data;
  1789 		return $post_data;
       
  1790 	}
       
  1791 	$post_data = _wp_get_allowed_postdata( $post_data );
  1688 
  1792 
  1689 	$post_author = get_current_user_id();
  1793 	$post_author = get_current_user_id();
  1690 
  1794 
  1691 	// Store one autosave per author. If there is already an autosave, overwrite it.
  1795 	// Store one autosave per author. If there is already an autosave, overwrite it.
  1692 	if ( $old_autosave = wp_get_post_autosave( $post_id, $post_author ) ) {
  1796 	if ( $old_autosave = wp_get_post_autosave( $post_id, $post_author ) ) {
  1693 		$new_autosave = _wp_post_revision_data( $post_data, true );
  1797 		$new_autosave                = _wp_post_revision_data( $post_data, true );
  1694 		$new_autosave['ID'] = $old_autosave->ID;
  1798 		$new_autosave['ID']          = $old_autosave->ID;
  1695 		$new_autosave['post_author'] = $post_author;
  1799 		$new_autosave['post_author'] = $post_author;
  1696 
  1800 
  1697 		// If the new autosave has the same content as the post, delete the autosave.
  1801 		// If the new autosave has the same content as the post, delete the autosave.
  1698 		$post = get_post( $post_id );
  1802 		$post                  = get_post( $post_id );
  1699 		$autosave_is_different = false;
  1803 		$autosave_is_different = false;
  1700 		foreach ( array_intersect( array_keys( $new_autosave ), array_keys( _wp_post_revision_fields( $post ) ) ) as $field ) {
  1804 		foreach ( array_intersect( array_keys( $new_autosave ), array_keys( _wp_post_revision_fields( $post ) ) ) as $field ) {
  1701 			if ( normalize_whitespace( $new_autosave[ $field ] ) != normalize_whitespace( $post->$field ) ) {
  1805 			if ( normalize_whitespace( $new_autosave[ $field ] ) != normalize_whitespace( $post->$field ) ) {
  1702 				$autosave_is_different = true;
  1806 				$autosave_is_different = true;
  1703 				break;
  1807 				break;
  1735  *
  1839  *
  1736  * @return string URL to redirect to show the preview.
  1840  * @return string URL to redirect to show the preview.
  1737  */
  1841  */
  1738 function post_preview() {
  1842 function post_preview() {
  1739 
  1843 
  1740 	$post_ID = (int) $_POST['post_ID'];
  1844 	$post_ID     = (int) $_POST['post_ID'];
  1741 	$_POST['ID'] = $post_ID;
  1845 	$_POST['ID'] = $post_ID;
  1742 
  1846 
  1743 	if ( ! $post = get_post( $post_ID ) ) {
  1847 	if ( ! $post = get_post( $post_ID ) ) {
  1744 		wp_die( __( 'Sorry, you are not allowed to edit this post.' ) );
  1848 		wp_die( __( 'Sorry, you are not allowed to edit this post.' ) );
  1745 	}
  1849 	}
  1753 	if ( ! wp_check_post_lock( $post->ID ) && get_current_user_id() == $post->post_author && ( 'draft' == $post->post_status || 'auto-draft' == $post->post_status ) ) {
  1857 	if ( ! wp_check_post_lock( $post->ID ) && get_current_user_id() == $post->post_author && ( 'draft' == $post->post_status || 'auto-draft' == $post->post_status ) ) {
  1754 		$saved_post_id = edit_post();
  1858 		$saved_post_id = edit_post();
  1755 	} else {
  1859 	} else {
  1756 		$is_autosave = true;
  1860 		$is_autosave = true;
  1757 
  1861 
  1758 		if ( isset( $_POST['post_status'] ) && 'auto-draft' == $_POST['post_status'] )
  1862 		if ( isset( $_POST['post_status'] ) && 'auto-draft' == $_POST['post_status'] ) {
  1759 			$_POST['post_status'] = 'draft';
  1863 			$_POST['post_status'] = 'draft';
       
  1864 		}
  1760 
  1865 
  1761 		$saved_post_id = wp_create_post_autosave( $post->ID );
  1866 		$saved_post_id = wp_create_post_autosave( $post->ID );
  1762 	}
  1867 	}
  1763 
  1868 
  1764 	if ( is_wp_error( $saved_post_id ) )
  1869 	if ( is_wp_error( $saved_post_id ) ) {
  1765 		wp_die( $saved_post_id->get_error_message() );
  1870 		wp_die( $saved_post_id->get_error_message() );
       
  1871 	}
  1766 
  1872 
  1767 	$query_args = array();
  1873 	$query_args = array();
  1768 
  1874 
  1769 	if ( $is_autosave && $saved_post_id ) {
  1875 	if ( $is_autosave && $saved_post_id ) {
  1770 		$query_args['preview_id'] = $post->ID;
  1876 		$query_args['preview_id']    = $post->ID;
  1771 		$query_args['preview_nonce'] = wp_create_nonce( 'post_preview_' . $post->ID );
  1877 		$query_args['preview_nonce'] = wp_create_nonce( 'post_preview_' . $post->ID );
  1772 
  1878 
  1773 		if ( isset( $_POST['post_format'] ) ) {
  1879 		if ( isset( $_POST['post_format'] ) ) {
  1774 			$query_args['post_format'] = empty( $_POST['post_format'] ) ? 'standard' : sanitize_key( $_POST['post_format'] );
  1880 			$query_args['post_format'] = empty( $_POST['post_format'] ) ? 'standard' : sanitize_key( $_POST['post_format'] );
  1775 		}
  1881 		}
  1793  * @return mixed The value 0 or WP_Error on failure. The saved post ID on success.
  1899  * @return mixed The value 0 or WP_Error on failure. The saved post ID on success.
  1794  *               The ID can be the draft post_id or the autosave revision post_id.
  1900  *               The ID can be the draft post_id or the autosave revision post_id.
  1795  */
  1901  */
  1796 function wp_autosave( $post_data ) {
  1902 function wp_autosave( $post_data ) {
  1797 	// Back-compat
  1903 	// Back-compat
  1798 	if ( ! defined( 'DOING_AUTOSAVE' ) )
  1904 	if ( ! defined( 'DOING_AUTOSAVE' ) ) {
  1799 		define( 'DOING_AUTOSAVE', true );
  1905 		define( 'DOING_AUTOSAVE', true );
  1800 
  1906 	}
  1801 	$post_id = (int) $post_data['post_id'];
  1907 
       
  1908 	$post_id         = (int) $post_data['post_id'];
  1802 	$post_data['ID'] = $post_data['post_ID'] = $post_id;
  1909 	$post_data['ID'] = $post_data['post_ID'] = $post_id;
  1803 
  1910 
  1804 	if ( false === wp_verify_nonce( $post_data['_wpnonce'], 'update-post_' . $post_id ) ) {
  1911 	if ( false === wp_verify_nonce( $post_data['_wpnonce'], 'update-post_' . $post_id ) ) {
  1805 		return new WP_Error( 'invalid_nonce', __( 'Error while saving.' ) );
  1912 		return new WP_Error( 'invalid_nonce', __( 'Error while saving.' ) );
  1806 	}
  1913 	}
  1809 
  1916 
  1810 	if ( ! current_user_can( 'edit_post', $post->ID ) ) {
  1917 	if ( ! current_user_can( 'edit_post', $post->ID ) ) {
  1811 		return new WP_Error( 'edit_posts', __( 'Sorry, you are not allowed to edit this item.' ) );
  1918 		return new WP_Error( 'edit_posts', __( 'Sorry, you are not allowed to edit this item.' ) );
  1812 	}
  1919 	}
  1813 
  1920 
  1814 	if ( 'auto-draft' == $post->post_status )
  1921 	if ( 'auto-draft' == $post->post_status ) {
  1815 		$post_data['post_status'] = 'draft';
  1922 		$post_data['post_status'] = 'draft';
  1816 
  1923 	}
  1817 	if ( $post_data['post_type'] != 'page' && ! empty( $post_data['catslist'] ) )
  1924 
       
  1925 	if ( $post_data['post_type'] != 'page' && ! empty( $post_data['catslist'] ) ) {
  1818 		$post_data['post_category'] = explode( ',', $post_data['catslist'] );
  1926 		$post_data['post_category'] = explode( ',', $post_data['catslist'] );
       
  1927 	}
  1819 
  1928 
  1820 	if ( ! wp_check_post_lock( $post->ID ) && get_current_user_id() == $post->post_author && ( 'auto-draft' == $post->post_status || 'draft' == $post->post_status ) ) {
  1929 	if ( ! wp_check_post_lock( $post->ID ) && get_current_user_id() == $post->post_author && ( 'auto-draft' == $post->post_status || 'draft' == $post->post_status ) ) {
  1821 		// Drafts and auto-drafts are just overwritten by autosave for the same user if the post is not locked
  1930 		// Drafts and auto-drafts are just overwritten by autosave for the same user if the post is not locked
  1822 		return edit_post( wp_slash( $post_data ) );
  1931 		return edit_post( wp_slash( $post_data ) );
  1823 	} else {
  1932 	} else {
  1829 /**
  1938 /**
  1830  * Redirect to previous page.
  1939  * Redirect to previous page.
  1831  *
  1940  *
  1832  * @param int $post_id Optional. Post ID.
  1941  * @param int $post_id Optional. Post ID.
  1833  */
  1942  */
  1834 function redirect_post($post_id = '') {
  1943 function redirect_post( $post_id = '' ) {
  1835 	if ( isset($_POST['save']) || isset($_POST['publish']) ) {
  1944 	if ( isset( $_POST['save'] ) || isset( $_POST['publish'] ) ) {
  1836 		$status = get_post_status( $post_id );
  1945 		$status = get_post_status( $post_id );
  1837 
  1946 
  1838 		if ( isset( $_POST['publish'] ) ) {
  1947 		if ( isset( $_POST['publish'] ) ) {
  1839 			switch ( $status ) {
  1948 			switch ( $status ) {
  1840 				case 'pending':
  1949 				case 'pending':
  1849 		} else {
  1958 		} else {
  1850 			$message = 'draft' == $status ? 10 : 1;
  1959 			$message = 'draft' == $status ? 10 : 1;
  1851 		}
  1960 		}
  1852 
  1961 
  1853 		$location = add_query_arg( 'message', $message, get_edit_post_link( $post_id, 'url' ) );
  1962 		$location = add_query_arg( 'message', $message, get_edit_post_link( $post_id, 'url' ) );
  1854 	} elseif ( isset($_POST['addmeta']) && $_POST['addmeta'] ) {
  1963 	} elseif ( isset( $_POST['addmeta'] ) && $_POST['addmeta'] ) {
  1855 		$location = add_query_arg( 'message', 2, wp_get_referer() );
  1964 		$location = add_query_arg( 'message', 2, wp_get_referer() );
  1856 		$location = explode('#', $location);
  1965 		$location = explode( '#', $location );
  1857 		$location = $location[0] . '#postcustom';
  1966 		$location = $location[0] . '#postcustom';
  1858 	} elseif ( isset($_POST['deletemeta']) && $_POST['deletemeta'] ) {
  1967 	} elseif ( isset( $_POST['deletemeta'] ) && $_POST['deletemeta'] ) {
  1859 		$location = add_query_arg( 'message', 3, wp_get_referer() );
  1968 		$location = add_query_arg( 'message', 3, wp_get_referer() );
  1860 		$location = explode('#', $location);
  1969 		$location = explode( '#', $location );
  1861 		$location = $location[0] . '#postcustom';
  1970 		$location = $location[0] . '#postcustom';
  1862 	} else {
  1971 	} else {
  1863 		$location = add_query_arg( 'message', 4, get_edit_post_link( $post_id, 'url' ) );
  1972 		$location = add_query_arg( 'message', 4, get_edit_post_link( $post_id, 'url' ) );
  1864 	}
  1973 	}
  1865 
  1974 
  1872 	 * @param int    $post_id  The post ID.
  1981 	 * @param int    $post_id  The post ID.
  1873 	 */
  1982 	 */
  1874 	wp_redirect( apply_filters( 'redirect_post_location', $location, $post_id ) );
  1983 	wp_redirect( apply_filters( 'redirect_post_location', $location, $post_id ) );
  1875 	exit;
  1984 	exit;
  1876 }
  1985 }
       
  1986 
       
  1987 /**
       
  1988  * Sanitizes POST values from a checkbox taxonomy metabox.
       
  1989  *
       
  1990  * @since 5.1.0
       
  1991  *
       
  1992  * @param mixed $terms Raw term data from the 'tax_input' field.
       
  1993  * @return array
       
  1994  */
       
  1995 function taxonomy_meta_box_sanitize_cb_checkboxes( $taxonomy, $terms ) {
       
  1996 	return array_map( 'intval', $terms );
       
  1997 }
       
  1998 
       
  1999 /**
       
  2000  * Sanitizes POST values from an input taxonomy metabox.
       
  2001  *
       
  2002  * @since 5.1.0
       
  2003  *
       
  2004  * @param mixed $terms Raw term data from the 'tax_input' field.
       
  2005  * @return array
       
  2006  */
       
  2007 function taxonomy_meta_box_sanitize_cb_input( $taxonomy, $terms ) {
       
  2008 	/*
       
  2009 	 * Assume that a 'tax_input' string is a comma-separated list of term names.
       
  2010 	 * Some languages may use a character other than a comma as a delimiter, so we standardize on
       
  2011 	 * commas before parsing the list.
       
  2012 	 */
       
  2013 	if ( ! is_array( $terms ) ) {
       
  2014 		$comma = _x( ',', 'tag delimiter' );
       
  2015 		if ( ',' !== $comma ) {
       
  2016 			$terms = str_replace( $comma, ',', $terms );
       
  2017 		}
       
  2018 		$terms = explode( ',', trim( $terms, " \n\t\r\0\x0B," ) );
       
  2019 	}
       
  2020 
       
  2021 	$clean_terms = array();
       
  2022 	foreach ( $terms as $term ) {
       
  2023 		// Empty terms are invalid input.
       
  2024 		if ( empty( $term ) ) {
       
  2025 			continue;
       
  2026 		}
       
  2027 
       
  2028 		$_term = get_terms(
       
  2029 			$taxonomy,
       
  2030 			array(
       
  2031 				'name'       => $term,
       
  2032 				'fields'     => 'ids',
       
  2033 				'hide_empty' => false,
       
  2034 			)
       
  2035 		);
       
  2036 
       
  2037 		if ( ! empty( $_term ) ) {
       
  2038 			$clean_terms[] = intval( $_term[0] );
       
  2039 		} else {
       
  2040 			// No existing term was found, so pass the string. A new term will be created.
       
  2041 			$clean_terms[] = $term;
       
  2042 		}
       
  2043 	}
       
  2044 
       
  2045 	return $clean_terms;
       
  2046 }
       
  2047 
       
  2048 /**
       
  2049  * Return whether the post can be edited in the block editor.
       
  2050  *
       
  2051  * @since 5.0.0
       
  2052  *
       
  2053  * @param int|WP_Post $post Post ID or WP_Post object.
       
  2054  * @return bool Whether the post can be edited in the block editor.
       
  2055  */
       
  2056 function use_block_editor_for_post( $post ) {
       
  2057 	$post = get_post( $post );
       
  2058 
       
  2059 	if ( ! $post ) {
       
  2060 		return false;
       
  2061 	}
       
  2062 
       
  2063 	// We're in the meta box loader, so don't use the block editor.
       
  2064 	if ( isset( $_GET['meta-box-loader'] ) ) {
       
  2065 		check_admin_referer( 'meta-box-loader', 'meta-box-loader-nonce' );
       
  2066 		return false;
       
  2067 	}
       
  2068 
       
  2069 	// The posts page can't be edited in the block editor.
       
  2070 	if ( absint( get_option( 'page_for_posts' ) ) === $post->ID && empty( $post->post_content ) ) {
       
  2071 		return false;
       
  2072 	}
       
  2073 
       
  2074 	$use_block_editor = use_block_editor_for_post_type( $post->post_type );
       
  2075 
       
  2076 	/**
       
  2077 	 * Filter whether a post is able to be edited in the block editor.
       
  2078 	 *
       
  2079 	 * @since 5.0.0
       
  2080 	 *
       
  2081 	 * @param bool    $use_block_editor Whether the post can be edited or not.
       
  2082 	 * @param WP_Post $post             The post being checked.
       
  2083 	 */
       
  2084 	return apply_filters( 'use_block_editor_for_post', $use_block_editor, $post );
       
  2085 }
       
  2086 
       
  2087 /**
       
  2088  * Return whether a post type is compatible with the block editor.
       
  2089  *
       
  2090  * The block editor depends on the REST API, and if the post type is not shown in the
       
  2091  * REST API, then it won't work with the block editor.
       
  2092  *
       
  2093  * @since 5.0.0
       
  2094  *
       
  2095  * @param string $post_type The post type.
       
  2096  * @return bool Whether the post type can be edited with the block editor.
       
  2097  */
       
  2098 function use_block_editor_for_post_type( $post_type ) {
       
  2099 	if ( ! post_type_exists( $post_type ) ) {
       
  2100 		return false;
       
  2101 	}
       
  2102 
       
  2103 	if ( ! post_type_supports( $post_type, 'editor' ) ) {
       
  2104 		return false;
       
  2105 	}
       
  2106 
       
  2107 	$post_type_object = get_post_type_object( $post_type );
       
  2108 	if ( $post_type_object && ! $post_type_object->show_in_rest ) {
       
  2109 		return false;
       
  2110 	}
       
  2111 
       
  2112 	/**
       
  2113 	 * Filter whether a post is able to be edited in the block editor.
       
  2114 	 *
       
  2115 	 * @since 5.0.0
       
  2116 	 *
       
  2117 	 * @param bool   $use_block_editor  Whether the post type can be edited or not. Default true.
       
  2118 	 * @param string $post_type         The post type being checked.
       
  2119 	 */
       
  2120 	return apply_filters( 'use_block_editor_for_post_type', true, $post_type );
       
  2121 }
       
  2122 
       
  2123 /**
       
  2124  * Returns all the block categories that will be shown in the block editor.
       
  2125  *
       
  2126  * @since 5.0.0
       
  2127  *
       
  2128  * @param WP_Post $post Post object.
       
  2129  * @return array Array of block categories.
       
  2130  */
       
  2131 function get_block_categories( $post ) {
       
  2132 	$default_categories = array(
       
  2133 		array(
       
  2134 			'slug'  => 'common',
       
  2135 			'title' => __( 'Common Blocks' ),
       
  2136 			'icon'  => null,
       
  2137 		),
       
  2138 		array(
       
  2139 			'slug'  => 'formatting',
       
  2140 			'title' => __( 'Formatting' ),
       
  2141 			'icon'  => null,
       
  2142 		),
       
  2143 		array(
       
  2144 			'slug'  => 'layout',
       
  2145 			'title' => __( 'Layout Elements' ),
       
  2146 			'icon'  => null,
       
  2147 		),
       
  2148 		array(
       
  2149 			'slug'  => 'widgets',
       
  2150 			'title' => __( 'Widgets' ),
       
  2151 			'icon'  => null,
       
  2152 		),
       
  2153 		array(
       
  2154 			'slug'  => 'embed',
       
  2155 			'title' => __( 'Embeds' ),
       
  2156 			'icon'  => null,
       
  2157 		),
       
  2158 		array(
       
  2159 			'slug'  => 'reusable',
       
  2160 			'title' => __( 'Reusable Blocks' ),
       
  2161 			'icon'  => null,
       
  2162 		),
       
  2163 	);
       
  2164 
       
  2165 	/**
       
  2166 	 * Filter the default array of block categories.
       
  2167 	 *
       
  2168 	 * @since 5.0.0
       
  2169 	 *
       
  2170 	 * @param array   $default_categories Array of block categories.
       
  2171 	 * @param WP_Post $post               Post being loaded.
       
  2172 	 */
       
  2173 	return apply_filters( 'block_categories', $default_categories, $post );
       
  2174 }
       
  2175 
       
  2176 /**
       
  2177  * Prepares server-registered blocks for the block editor.
       
  2178  *
       
  2179  * Returns an associative array of registered block data keyed by block name. Data includes properties
       
  2180  * of a block relevant for client registration.
       
  2181  *
       
  2182  * @since 5.0.0
       
  2183  *
       
  2184  * @return array An associative array of registered block data.
       
  2185  */
       
  2186 function get_block_editor_server_block_settings() {
       
  2187 	$block_registry = WP_Block_Type_Registry::get_instance();
       
  2188 	$blocks         = array();
       
  2189 	$keys_to_pick   = array( 'title', 'description', 'icon', 'category', 'keywords', 'supports', 'attributes' );
       
  2190 
       
  2191 	foreach ( $block_registry->get_all_registered() as $block_name => $block_type ) {
       
  2192 		foreach ( $keys_to_pick as $key ) {
       
  2193 			if ( ! isset( $block_type->{ $key } ) ) {
       
  2194 				continue;
       
  2195 			}
       
  2196 
       
  2197 			if ( ! isset( $blocks[ $block_name ] ) ) {
       
  2198 				$blocks[ $block_name ] = array();
       
  2199 			}
       
  2200 
       
  2201 			$blocks[ $block_name ][ $key ] = $block_type->{ $key };
       
  2202 		}
       
  2203 	}
       
  2204 
       
  2205 	return $blocks;
       
  2206 }
       
  2207 
       
  2208 /**
       
  2209  * Renders the meta boxes forms.
       
  2210  *
       
  2211  * @since 5.0.0
       
  2212  */
       
  2213 function the_block_editor_meta_boxes() {
       
  2214 	global $post, $current_screen, $wp_meta_boxes;
       
  2215 
       
  2216 	// Handle meta box state.
       
  2217 	$_original_meta_boxes = $wp_meta_boxes;
       
  2218 
       
  2219 	/**
       
  2220 	 * Fires right before the meta boxes are rendered.
       
  2221 	 *
       
  2222 	 * This allows for the filtering of meta box data, that should already be
       
  2223 	 * present by this point. Do not use as a means of adding meta box data.
       
  2224 	 *
       
  2225 	 * @since 5.0.0
       
  2226 	 *
       
  2227 	 * @param array $wp_meta_boxes Global meta box state.
       
  2228 	 */
       
  2229 	$wp_meta_boxes = apply_filters( 'filter_block_editor_meta_boxes', $wp_meta_boxes );
       
  2230 	$locations     = array( 'side', 'normal', 'advanced' );
       
  2231 	$priorities    = array( 'high', 'sorted', 'core', 'default', 'low' );
       
  2232 
       
  2233 	// Render meta boxes.
       
  2234 	?>
       
  2235 	<form class="metabox-base-form">
       
  2236 	<?php the_block_editor_meta_box_post_form_hidden_fields( $post ); ?>
       
  2237 	</form>
       
  2238 	<form id="toggle-custom-fields-form" method="post" action="<?php echo esc_attr( admin_url( 'post.php' ) ); ?>">
       
  2239 		<?php wp_nonce_field( 'toggle-custom-fields' ); ?>
       
  2240 		<input type="hidden" name="action" value="toggle-custom-fields" />
       
  2241 	</form>
       
  2242 	<?php foreach ( $locations as $location ) : ?>
       
  2243 		<form class="metabox-location-<?php echo esc_attr( $location ); ?>" onsubmit="return false;">
       
  2244 			<div id="poststuff" class="sidebar-open">
       
  2245 				<div id="postbox-container-2" class="postbox-container">
       
  2246 					<?php
       
  2247 					do_meta_boxes(
       
  2248 						$current_screen,
       
  2249 						$location,
       
  2250 						$post
       
  2251 					);
       
  2252 					?>
       
  2253 				</div>
       
  2254 			</div>
       
  2255 		</form>
       
  2256 	<?php endforeach; ?>
       
  2257 	<?php
       
  2258 
       
  2259 	$meta_boxes_per_location = array();
       
  2260 	foreach ( $locations as $location ) {
       
  2261 		$meta_boxes_per_location[ $location ] = array();
       
  2262 
       
  2263 		if ( ! isset( $wp_meta_boxes[ $current_screen->id ][ $location ] ) ) {
       
  2264 			continue;
       
  2265 		}
       
  2266 
       
  2267 		foreach ( $priorities as $priority ) {
       
  2268 			if ( ! isset( $wp_meta_boxes[ $current_screen->id ][ $location ][ $priority ] ) ) {
       
  2269 				continue;
       
  2270 			}
       
  2271 
       
  2272 			$meta_boxes = (array) $wp_meta_boxes[ $current_screen->id ][ $location ][ $priority ];
       
  2273 			foreach ( $meta_boxes as $meta_box ) {
       
  2274 				if ( false == $meta_box || ! $meta_box['title'] ) {
       
  2275 					continue;
       
  2276 				}
       
  2277 
       
  2278 				// If a meta box is just here for back compat, don't show it in the block editor.
       
  2279 				if ( isset( $meta_box['args']['__back_compat_meta_box'] ) && $meta_box['args']['__back_compat_meta_box'] ) {
       
  2280 					continue;
       
  2281 				}
       
  2282 
       
  2283 				$meta_boxes_per_location[ $location ][] = array(
       
  2284 					'id'    => $meta_box['id'],
       
  2285 					'title' => $meta_box['title'],
       
  2286 				);
       
  2287 			}
       
  2288 		}
       
  2289 	}
       
  2290 
       
  2291 	/**
       
  2292 	 * Sadly we probably can not add this data directly into editor settings.
       
  2293 	 *
       
  2294 	 * Some meta boxes need admin_head to fire for meta box registry.
       
  2295 	 * admin_head fires after admin_enqueue_scripts, which is where we create our
       
  2296 	 * editor instance.
       
  2297 	 */
       
  2298 	$script = 'window._wpLoadBlockEditor.then( function() {
       
  2299 		wp.data.dispatch( \'core/edit-post\' ).setAvailableMetaBoxesPerLocation( ' . wp_json_encode( $meta_boxes_per_location ) . ' );
       
  2300 	} );';
       
  2301 
       
  2302 	wp_add_inline_script( 'wp-edit-post', $script );
       
  2303 
       
  2304 	/**
       
  2305 	 * When `wp-edit-post` is output in the `<head>`, the inline script needs to be manually printed. Otherwise,
       
  2306 	 * meta boxes will not display because inline scripts for `wp-edit-post` will not be printed again after this point.
       
  2307 	 */
       
  2308 	if ( wp_script_is( 'wp-edit-post', 'done' ) ) {
       
  2309 		printf( "<script type='text/javascript'>\n%s\n</script>\n", trim( $script ) );
       
  2310 	}
       
  2311 
       
  2312 	/**
       
  2313 	 * If the 'postcustom' meta box is enabled, then we need to perform some
       
  2314 	 * extra initialization on it.
       
  2315 	 */
       
  2316 	$enable_custom_fields = (bool) get_user_meta( get_current_user_id(), 'enable_custom_fields', true );
       
  2317 	if ( $enable_custom_fields ) {
       
  2318 		$script = "( function( $ ) {
       
  2319 			if ( $('#postcustom').length ) {
       
  2320 				$( '#the-list' ).wpList( {
       
  2321 					addBefore: function( s ) {
       
  2322 						s.data += '&post_id=$post->ID';
       
  2323 						return s;
       
  2324 					},
       
  2325 					addAfter: function() {
       
  2326 						$('table#list-table').show();
       
  2327 					}
       
  2328 				});
       
  2329 			}
       
  2330 		} )( jQuery );";
       
  2331 		wp_enqueue_script( 'wp-lists' );
       
  2332 		wp_add_inline_script( 'wp-lists', $script );
       
  2333 	}
       
  2334 
       
  2335 	// Reset meta box data.
       
  2336 	$wp_meta_boxes = $_original_meta_boxes;
       
  2337 }
       
  2338 
       
  2339 /**
       
  2340  * Renders the hidden form required for the meta boxes form.
       
  2341  *
       
  2342  * @since 5.0.0
       
  2343  *
       
  2344  * @param WP_Post $post Current post object.
       
  2345  */
       
  2346 function the_block_editor_meta_box_post_form_hidden_fields( $post ) {
       
  2347 	$form_extra = '';
       
  2348 	if ( 'auto-draft' === $post->post_status ) {
       
  2349 		$form_extra .= "<input type='hidden' id='auto_draft' name='auto_draft' value='1' />";
       
  2350 	}
       
  2351 	$form_action  = 'editpost';
       
  2352 	$nonce_action = 'update-post_' . $post->ID;
       
  2353 	$form_extra  .= "<input type='hidden' id='post_ID' name='post_ID' value='" . esc_attr( $post->ID ) . "' />";
       
  2354 	$referer      = wp_get_referer();
       
  2355 	$current_user = wp_get_current_user();
       
  2356 	$user_id      = $current_user->ID;
       
  2357 	wp_nonce_field( $nonce_action );
       
  2358 
       
  2359 	/*
       
  2360 	 * Some meta boxes hook into these actions to add hidden input fields in the classic post form. For backwards
       
  2361 	 * compatibility, we can capture the output from these actions, and extract the hidden input fields.
       
  2362 	 */
       
  2363 	ob_start();
       
  2364 	/** This filter is documented in wp-admin/edit-form-advanced.php */
       
  2365 	do_action( 'edit_form_after_title', $post );
       
  2366 	/** This filter is documented in wp-admin/edit-form-advanced.php */
       
  2367 	do_action( 'edit_form_advanced', $post );
       
  2368 	$classic_output = ob_get_clean();
       
  2369 
       
  2370 	$classic_elements = wp_html_split( $classic_output );
       
  2371 	$hidden_inputs    = '';
       
  2372 	foreach ( $classic_elements as $element ) {
       
  2373 		if ( 0 !== strpos( $element, '<input ' ) ) {
       
  2374 			continue;
       
  2375 		}
       
  2376 
       
  2377 		if ( preg_match( '/\stype=[\'"]hidden[\'"]\s/', $element ) ) {
       
  2378 			echo $element;
       
  2379 		}
       
  2380 	}
       
  2381 	?>
       
  2382 	<input type="hidden" id="user-id" name="user_ID" value="<?php echo (int) $user_id; ?>" />
       
  2383 	<input type="hidden" id="hiddenaction" name="action" value="<?php echo esc_attr( $form_action ); ?>" />
       
  2384 	<input type="hidden" id="originalaction" name="originalaction" value="<?php echo esc_attr( $form_action ); ?>" />
       
  2385 	<input type="hidden" id="post_type" name="post_type" value="<?php echo esc_attr( $post->post_type ); ?>" />
       
  2386 	<input type="hidden" id="original_post_status" name="original_post_status" value="<?php echo esc_attr( $post->post_status ); ?>" />
       
  2387 	<input type="hidden" id="referredby" name="referredby" value="<?php echo $referer ? esc_url( $referer ) : ''; ?>" />
       
  2388 
       
  2389 	<?php
       
  2390 	if ( 'draft' !== get_post_status( $post ) ) {
       
  2391 		wp_original_referer_field( true, 'previous' );
       
  2392 	}
       
  2393 	echo $form_extra;
       
  2394 	wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false );
       
  2395 	wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false );
       
  2396 	// Permalink title nonce.
       
  2397 	wp_nonce_field( 'samplepermalink', 'samplepermalinknonce', false );
       
  2398 
       
  2399 	/**
       
  2400 	 * Add hidden input fields to the meta box save form.
       
  2401 	 *
       
  2402 	 * Hook into this action to print `<input type="hidden" ... />` fields, which will be POSTed back to
       
  2403 	 * the server when meta boxes are saved.
       
  2404 	 *
       
  2405 	 * @since 5.0.0
       
  2406 	 *
       
  2407 	 * @params WP_Post $post The post that is being edited.
       
  2408 	 */
       
  2409 	do_action( 'block_editor_meta_box_hidden_fields', $post );
       
  2410 }