PageRenderTime 84ms CodeModel.GetById 38ms app.highlight 35ms RepoModel.GetById 2ms app.codeStats 0ms

/wp-admin/includes/post.php

https://github.com/dipakdotyadav/WordPress
PHP | 1353 lines | 827 code | 223 blank | 303 comment | 291 complexity | 61462856716c8ee4b144d45a4a43db80 MD5 | raw file
   1<?php
   2/**
   3 * WordPress Post Administration API.
   4 *
   5 * @package WordPress
   6 * @subpackage Administration
   7 */
   8
   9/**
  10 * Rename $_POST data from form names to DB post columns.
  11 *
  12 * Manipulates $_POST directly.
  13 *
  14 * @package WordPress
  15 * @since 2.6.0
  16 *
  17 * @param bool $update Are we updating a pre-existing post?
  18 * @param array $post_data Array of post data. Defaults to the contents of $_POST.
  19 * @return object|bool WP_Error on failure, true on success.
  20 */
  21function _wp_translate_postdata( $update = false, $post_data = null ) {
  22
  23	if ( empty($post_data) )
  24		$post_data = &$_POST;
  25
  26	if ( $update )
  27		$post_data['ID'] = (int) $post_data['post_ID'];
  28
  29	$ptype = get_post_type_object( $post_data['post_type'] );
  30
  31	if ( $update && ! current_user_can( $ptype->cap->edit_post, $post_data['ID'] ) ) {
  32		if ( 'page' == $post_data['post_type'] )
  33			return new WP_Error( 'edit_others_pages', __( 'You are not allowed to edit pages as this user.' ) );
  34		else
  35			return new WP_Error( 'edit_others_posts', __( 'You are not allowed to edit posts as this user.' ) );
  36	} elseif ( ! $update && ! current_user_can( $ptype->cap->create_posts ) ) {
  37		if ( 'page' == $post_data['post_type'] )
  38			return new WP_Error( 'edit_others_pages', __( 'You are not allowed to create pages as this user.' ) );
  39		else
  40			return new WP_Error( 'edit_others_posts', __( 'You are not allowed to create posts as this user.' ) );
  41	}
  42
  43	if ( isset( $post_data['content'] ) )
  44		$post_data['post_content'] = $post_data['content'];
  45
  46	if ( isset( $post_data['excerpt'] ) )
  47		$post_data['post_excerpt'] = $post_data['excerpt'];
  48
  49	if ( isset( $post_data['parent_id'] ) )
  50		$post_data['post_parent'] = (int) $post_data['parent_id'];
  51
  52	if ( isset($post_data['trackback_url']) )
  53		$post_data['to_ping'] = $post_data['trackback_url'];
  54
  55	if ( !isset($post_data['user_ID']) )
  56		$post_data['user_ID'] = $GLOBALS['user_ID'];
  57
  58	if (!empty ( $post_data['post_author_override'] ) ) {
  59		$post_data['post_author'] = (int) $post_data['post_author_override'];
  60	} else {
  61		if (!empty ( $post_data['post_author'] ) ) {
  62			$post_data['post_author'] = (int) $post_data['post_author'];
  63		} else {
  64			$post_data['post_author'] = (int) $post_data['user_ID'];
  65		}
  66	}
  67
  68	if ( ! $update && isset( $post_data['user_ID'] ) && ( $post_data['post_author'] != $post_data['user_ID'] )
  69		 && ! current_user_can( $ptype->cap->edit_others_posts ) ) {
  70
  71		if ( 'page' == $post_data['post_type'] )
  72			return new WP_Error( 'edit_others_pages', __( 'You are not allowed to create pages as this user.' ) );
  73		else
  74			return new WP_Error( 'edit_others_posts', __( 'You are not allowed to create posts as this user.' ) );
  75	}
  76
  77	// What to do based on which button they pressed
  78	if ( isset($post_data['saveasdraft']) && '' != $post_data['saveasdraft'] )
  79		$post_data['post_status'] = 'draft';
  80	if ( isset($post_data['saveasprivate']) && '' != $post_data['saveasprivate'] )
  81		$post_data['post_status'] = 'private';
  82	if ( isset($post_data['publish']) && ( '' != $post_data['publish'] ) && ( !isset($post_data['post_status']) || $post_data['post_status'] != 'private' ) )
  83		$post_data['post_status'] = 'publish';
  84	if ( isset($post_data['advanced']) && '' != $post_data['advanced'] )
  85		$post_data['post_status'] = 'draft';
  86	if ( isset($post_data['pending']) && '' != $post_data['pending'] )
  87		$post_data['post_status'] = 'pending';
  88
  89	if ( isset( $post_data['ID'] ) )
  90		$post_id = $post_data['ID'];
  91	else
  92		$post_id = false;
  93	$previous_status = $post_id ? get_post_field( 'post_status', $post_id ) : false;
  94
  95	// Posts 'submitted for approval' present are submitted to $_POST the same as if they were being published.
  96	// Change status from 'publish' to 'pending' if user lacks permissions to publish or to resave published posts.
  97	if ( isset($post_data['post_status']) && ('publish' == $post_data['post_status'] && !current_user_can( $ptype->cap->publish_posts )) )
  98		if ( $previous_status != 'publish' || !current_user_can( 'edit_post', $post_id ) )
  99			$post_data['post_status'] = 'pending';
 100
 101	if ( ! isset($post_data['post_status']) )
 102		$post_data['post_status'] = $previous_status;
 103
 104	if (!isset( $post_data['comment_status'] ))
 105		$post_data['comment_status'] = 'closed';
 106
 107	if (!isset( $post_data['ping_status'] ))
 108		$post_data['ping_status'] = 'closed';
 109
 110	foreach ( array('aa', 'mm', 'jj', 'hh', 'mn') as $timeunit ) {
 111		if ( !empty( $post_data['hidden_' . $timeunit] ) && $post_data['hidden_' . $timeunit] != $post_data[$timeunit] ) {
 112			$post_data['edit_date'] = '1';
 113			break;
 114		}
 115	}
 116
 117	if ( !empty( $post_data['edit_date'] ) ) {
 118		$aa = $post_data['aa'];
 119		$mm = $post_data['mm'];
 120		$jj = $post_data['jj'];
 121		$hh = $post_data['hh'];
 122		$mn = $post_data['mn'];
 123		$ss = $post_data['ss'];
 124		$aa = ($aa <= 0 ) ? date('Y') : $aa;
 125		$mm = ($mm <= 0 ) ? date('n') : $mm;
 126		$jj = ($jj > 31 ) ? 31 : $jj;
 127		$jj = ($jj <= 0 ) ? date('j') : $jj;
 128		$hh = ($hh > 23 ) ? $hh -24 : $hh;
 129		$mn = ($mn > 59 ) ? $mn -60 : $mn;
 130		$ss = ($ss > 59 ) ? $ss -60 : $ss;
 131		$post_data['post_date'] = sprintf( "%04d-%02d-%02d %02d:%02d:%02d", $aa, $mm, $jj, $hh, $mn, $ss );
 132		$valid_date = wp_checkdate( $mm, $jj, $aa, $post_data['post_date'] );
 133		if ( !$valid_date ) {
 134			return new WP_Error( 'invalid_date', __( 'Whoops, the provided date is invalid.' ) );
 135		}
 136		$post_data['post_date_gmt'] = get_gmt_from_date( $post_data['post_date'] );
 137	}
 138
 139	return $post_data;
 140}
 141
 142/**
 143 * Update an existing post with values provided in $_POST.
 144 *
 145 * @since 1.5.0
 146 *
 147 * @param array $post_data Optional.
 148 * @return int Post ID.
 149 */
 150function edit_post( $post_data = null ) {
 151
 152	if ( empty($post_data) )
 153		$post_data = &$_POST;
 154
 155	// Clear out any data in internal vars.
 156	unset( $post_data['filter'] );
 157
 158	$post_ID = (int) $post_data['post_ID'];
 159	$post = get_post( $post_ID );
 160	$post_data['post_type'] = $post->post_type;
 161	$post_data['post_mime_type'] = $post->post_mime_type;
 162
 163	$ptype = get_post_type_object($post_data['post_type']);
 164	if ( !current_user_can( $ptype->cap->edit_post, $post_ID ) ) {
 165		if ( 'page' == $post_data['post_type'] )
 166			wp_die( __('You are not allowed to edit this page.' ));
 167		else
 168			wp_die( __('You are not allowed to edit this post.' ));
 169	}
 170
 171	$post_data = _wp_translate_postdata( true, $post_data );
 172	if ( is_wp_error($post_data) )
 173		wp_die( $post_data->get_error_message() );
 174	if ( ( empty( $post_data['action'] ) || 'autosave' != $post_data['action'] ) && 'auto-draft' == $post_data['post_status'] ) {
 175		$post_data['post_status'] = 'draft';
 176	}
 177
 178	if ( isset($post_data['visibility']) ) {
 179		switch ( $post_data['visibility'] ) {
 180			case 'public' :
 181				$post_data['post_password'] = '';
 182				break;
 183			case 'password' :
 184				unset( $post_data['sticky'] );
 185				break;
 186			case 'private' :
 187				$post_data['post_status'] = 'private';
 188				$post_data['post_password'] = '';
 189				unset( $post_data['sticky'] );
 190				break;
 191		}
 192	}
 193
 194	// Post Formats
 195	if ( isset( $post_data['post_format'] ) ) {
 196		set_post_format( $post_ID, $post_data['post_format'] );
 197	}
 198
 199	if ( isset( $post_data[ '_wp_format_url' ] ) ) {
 200		update_post_meta( $post_ID, '_wp_format_url', wp_slash( esc_url_raw( wp_unslash( $post_data['_wp_format_url'] ) ) ) );
 201	}
 202
 203	$format_keys = array( 'quote', 'quote_source', 'image', 'gallery', 'media' );
 204
 205	foreach ( $format_keys as $key ) {
 206		if ( isset( $post_data[ '_wp_format_' . $key ] ) )
 207		 	update_post_meta( $post_ID, '_wp_format_' . $key, wp_filter_post_kses( $post_data[ '_wp_format_' . $key ] ) );
 208	}
 209
 210	// Meta Stuff
 211	if ( isset($post_data['meta']) && $post_data['meta'] ) {
 212		foreach ( $post_data['meta'] as $key => $value ) {
 213			if ( !$meta = get_post_meta_by_id( $key ) )
 214				continue;
 215			if ( $meta->post_id != $post_ID )
 216				continue;
 217			if ( is_protected_meta( $value['key'], 'post' ) || ! current_user_can( 'edit_post_meta', $post_ID, $value['key'] ) )
 218				continue;
 219			update_meta( $key, $value['key'], $value['value'] );
 220		}
 221	}
 222
 223	if ( isset($post_data['deletemeta']) && $post_data['deletemeta'] ) {
 224		foreach ( $post_data['deletemeta'] as $key => $value ) {
 225			if ( !$meta = get_post_meta_by_id( $key ) )
 226				continue;
 227			if ( $meta->post_id != $post_ID )
 228				continue;
 229			if ( is_protected_meta( $meta->meta_key, 'post' ) || ! current_user_can( 'delete_post_meta', $post_ID, $meta->meta_key ) )
 230				continue;
 231			delete_meta( $key );
 232		}
 233	}
 234
 235	// Attachment stuff
 236	if ( 'attachment' == $post_data['post_type'] ) {
 237		if ( isset( $post_data[ '_wp_attachment_image_alt' ] ) ) {
 238			$image_alt = wp_unslash( $post_data['_wp_attachment_image_alt'] );
 239			if ( $image_alt != get_post_meta( $post_ID, '_wp_attachment_image_alt', true ) ) {
 240				$image_alt = wp_strip_all_tags( $image_alt, true );
 241				// update_meta expects slashed
 242				update_post_meta( $post_ID, '_wp_attachment_image_alt', wp_slash( $image_alt ) );
 243			}
 244		}
 245
 246		$attachment_data = isset( $post_data['attachments'][ $post_ID ] ) ? $post_data['attachments'][ $post_ID ] : array();
 247		$post_data = apply_filters( 'attachment_fields_to_save', $post_data, $attachment_data );
 248	}
 249
 250	add_meta( $post_ID );
 251
 252	update_post_meta( $post_ID, '_edit_last', $GLOBALS['current_user']->ID );
 253
 254	wp_update_post( $post_data );
 255
 256	// Now that we have an ID we can fix any attachment anchor hrefs
 257	_fix_attachment_links( $post_ID );
 258
 259	wp_set_post_lock( $post_ID );
 260
 261	if ( current_user_can( $ptype->cap->edit_others_posts ) ) {
 262		if ( ! empty( $post_data['sticky'] ) )
 263			stick_post( $post_ID );
 264		else
 265			unstick_post( $post_ID );
 266	}
 267
 268	return $post_ID;
 269}
 270
 271/**
 272 * Process the post data for the bulk editing of posts.
 273 *
 274 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 275 * categories. Skips pages when they would be their own parent or child.
 276 *
 277 * @since 2.7.0
 278 *
 279 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 280 * @return array
 281 */
 282function bulk_edit_posts( $post_data = null ) {
 283	global $wpdb;
 284
 285	if ( empty($post_data) )
 286		$post_data = &$_POST;
 287
 288	if ( isset($post_data['post_type']) )
 289		$ptype = get_post_type_object($post_data['post_type']);
 290	else
 291		$ptype = get_post_type_object('post');
 292
 293	if ( !current_user_can( $ptype->cap->edit_posts ) ) {
 294		if ( 'page' == $ptype->name )
 295			wp_die( __('You are not allowed to edit pages.'));
 296		else
 297			wp_die( __('You are not allowed to edit posts.'));
 298	}
 299
 300	if ( -1 == $post_data['_status'] ) {
 301		$post_data['post_status'] = null;
 302		unset($post_data['post_status']);
 303	} else {
 304		$post_data['post_status'] = $post_data['_status'];
 305	}
 306	unset($post_data['_status']);
 307
 308	$post_IDs = array_map( 'intval', (array) $post_data['post'] );
 309
 310	$reset = array( 'post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky' );
 311	foreach ( $reset as $field ) {
 312		if ( isset($post_data[$field]) && ( '' == $post_data[$field] || -1 == $post_data[$field] ) )
 313			unset($post_data[$field]);
 314	}
 315
 316	if ( isset($post_data['post_category']) ) {
 317		if ( is_array($post_data['post_category']) && ! empty($post_data['post_category']) )
 318			$new_cats = array_map( 'absint', $post_data['post_category'] );
 319		else
 320			unset($post_data['post_category']);
 321	}
 322
 323	$tax_input = array();
 324	if ( isset($post_data['tax_input'])) {
 325		foreach ( $post_data['tax_input'] as $tax_name => $terms ) {
 326			if ( empty($terms) )
 327				continue;
 328			if ( is_taxonomy_hierarchical( $tax_name ) ) {
 329				$tax_input[ $tax_name ] = array_map( 'absint', $terms );
 330			} else {
 331				$comma = _x( ',', 'tag delimiter' );
 332				if ( ',' !== $comma )
 333					$terms = str_replace( $comma, ',', $terms );
 334				$tax_input[ $tax_name ] = explode( ',', trim( $terms, " \n\t\r\0\x0B," ) );
 335			}
 336		}
 337	}
 338
 339	if ( isset($post_data['post_parent']) && ($parent = (int) $post_data['post_parent']) ) {
 340		$pages = $wpdb->get_results("SELECT ID, post_parent FROM $wpdb->posts WHERE post_type = 'page'");
 341		$children = array();
 342
 343		for ( $i = 0; $i < 50 && $parent > 0; $i++ ) {
 344			$children[] = $parent;
 345
 346			foreach ( $pages as $page ) {
 347				if ( $page->ID == $parent ) {
 348					$parent = $page->post_parent;
 349					break;
 350				}
 351			}
 352		}
 353	}
 354
 355	$updated = $skipped = $locked = array();
 356	foreach ( $post_IDs as $post_ID ) {
 357		$post_type_object = get_post_type_object( get_post_type( $post_ID ) );
 358
 359		if ( !isset( $post_type_object ) || ( isset($children) && in_array($post_ID, $children) ) || !current_user_can( $post_type_object->cap->edit_post, $post_ID ) ) {
 360			$skipped[] = $post_ID;
 361			continue;
 362		}
 363
 364		if ( wp_check_post_lock( $post_ID ) ) {
 365			$locked[] = $post_ID;
 366			continue;
 367		}
 368
 369		$post = get_post( $post_ID );
 370		$tax_names = get_object_taxonomies( $post );
 371		foreach ( $tax_names as $tax_name ) {
 372			$taxonomy_obj = get_taxonomy($tax_name);
 373			if ( isset( $tax_input[$tax_name]) && current_user_can( $taxonomy_obj->cap->assign_terms ) )
 374				$new_terms = $tax_input[$tax_name];
 375			else
 376				$new_terms = array();
 377
 378			if ( $taxonomy_obj->hierarchical )
 379				$current_terms = (array) wp_get_object_terms( $post_ID, $tax_name, array('fields' => 'ids') );
 380			else
 381				$current_terms = (array) wp_get_object_terms( $post_ID, $tax_name, array('fields' => 'names') );
 382
 383			$post_data['tax_input'][$tax_name] = array_merge( $current_terms, $new_terms );
 384		}
 385
 386		if ( isset($new_cats) && in_array( 'category', $tax_names ) ) {
 387			$cats = (array) wp_get_post_categories($post_ID);
 388			$post_data['post_category'] = array_unique( array_merge($cats, $new_cats) );
 389			unset( $post_data['tax_input']['category'] );
 390		}
 391
 392		$post_data['post_mime_type'] = $post->post_mime_type;
 393		$post_data['guid'] = $post->guid;
 394
 395		$post_data['ID'] = $post_ID;
 396		$updated[] = wp_update_post( $post_data );
 397
 398		if ( isset( $post_data['sticky'] ) && current_user_can( $ptype->cap->edit_others_posts ) ) {
 399			if ( 'sticky' == $post_data['sticky'] )
 400				stick_post( $post_ID );
 401			else
 402				unstick_post( $post_ID );
 403		}
 404	}
 405
 406	return array( 'updated' => $updated, 'skipped' => $skipped, 'locked' => $locked );
 407}
 408
 409/**
 410 * Default post information to use when populating the "Write Post" form.
 411 *
 412 * @since 2.0.0
 413 *
 414 * @param string $post_type A post type string, defaults to 'post'.
 415 * @return WP_Post Post object containing all the default post data as attributes
 416 */
 417function get_default_post_to_edit( $post_type = 'post', $create_in_db = false ) {
 418	global $wpdb;
 419
 420	$post_title = '';
 421	if ( !empty( $_REQUEST['post_title'] ) )
 422		$post_title = esc_html( wp_unslash( $_REQUEST['post_title'] ));
 423
 424	$post_content = '';
 425	if ( !empty( $_REQUEST['content'] ) )
 426		$post_content = esc_html( wp_unslash( $_REQUEST['content'] ));
 427
 428	$post_excerpt = '';
 429	if ( !empty( $_REQUEST['excerpt'] ) )
 430		$post_excerpt = esc_html( wp_unslash( $_REQUEST['excerpt'] ));
 431
 432	if ( $create_in_db ) {
 433		$post_id = wp_insert_post( array( 'post_title' => __( 'Auto Draft' ), 'post_type' => $post_type, 'post_status' => 'auto-draft' ) );
 434		$post = get_post( $post_id );
 435		if ( current_theme_supports( 'post-formats' ) && post_type_supports( $post->post_type, 'post-formats' ) && get_option( 'default_post_format' ) )
 436			set_post_format( $post, get_option( 'default_post_format' ) );
 437	} else {
 438		$post = new stdClass;
 439		$post->ID = 0;
 440		$post->post_author = '';
 441		$post->post_date = '';
 442		$post->post_date_gmt = '';
 443		$post->post_password = '';
 444		$post->post_type = $post_type;
 445		$post->post_status = 'draft';
 446		$post->to_ping = '';
 447		$post->pinged = '';
 448		$post->comment_status = get_option( 'default_comment_status' );
 449		$post->ping_status = get_option( 'default_ping_status' );
 450		$post->post_pingback = get_option( 'default_pingback_flag' );
 451		$post->post_category = get_option( 'default_category' );
 452		$post->page_template = 'default';
 453		$post->post_parent = 0;
 454		$post->menu_order = 0;
 455		$post = new WP_Post( $post );
 456	}
 457
 458	$post->post_content = apply_filters( 'default_content', $post_content, $post );
 459	$post->post_title   = apply_filters( 'default_title',   $post_title, $post   );
 460	$post->post_excerpt = apply_filters( 'default_excerpt', $post_excerpt, $post );
 461	$post->post_name = '';
 462
 463	return $post;
 464}
 465
 466/**
 467 * Determine if a post exists based on title, content, and date
 468 *
 469 * @since 2.0.0
 470 *
 471 * @param string $title Post title
 472 * @param string $content Optional post content
 473 * @param string $date Optional post date
 474 * @return int Post ID if post exists, 0 otherwise.
 475 */
 476function post_exists($title, $content = '', $date = '') {
 477	global $wpdb;
 478
 479	$post_title = wp_unslash( sanitize_post_field( 'post_title', $title, 0, 'db' ) );
 480	$post_content = wp_unslash( sanitize_post_field( 'post_content', $content, 0, 'db' ) );
 481	$post_date = wp_unslash( sanitize_post_field( 'post_date', $date, 0, 'db' ) );
 482
 483	$query = "SELECT ID FROM $wpdb->posts WHERE 1=1";
 484	$args = array();
 485
 486	if ( !empty ( $date ) ) {
 487		$query .= ' AND post_date = %s';
 488		$args[] = $post_date;
 489	}
 490
 491	if ( !empty ( $title ) ) {
 492		$query .= ' AND post_title = %s';
 493		$args[] = $post_title;
 494	}
 495
 496	if ( !empty ( $content ) ) {
 497		$query .= 'AND post_content = %s';
 498		$args[] = $post_content;
 499	}
 500
 501	if ( !empty ( $args ) )
 502		return (int) $wpdb->get_var( $wpdb->prepare($query, $args) );
 503
 504	return 0;
 505}
 506
 507/**
 508 * Creates a new post from the "Write Post" form using $_POST information.
 509 *
 510 * @since 2.1.0
 511 *
 512 * @return unknown
 513 */
 514function wp_write_post() {
 515	global $user_ID;
 516
 517	if ( isset($_POST['post_type']) )
 518		$ptype = get_post_type_object($_POST['post_type']);
 519	else
 520		$ptype = get_post_type_object('post');
 521
 522	if ( !current_user_can( $ptype->cap->edit_posts ) ) {
 523		if ( 'page' == $ptype->name )
 524			return new WP_Error( 'edit_pages', __( 'You are not allowed to create pages on this site.' ) );
 525		else
 526			return new WP_Error( 'edit_posts', __( 'You are not allowed to create posts or drafts on this site.' ) );
 527	}
 528
 529	$_POST['post_mime_type'] = '';
 530
 531	// Clear out any data in internal vars.
 532	unset( $_POST['filter'] );
 533
 534	// Edit don't write if we have a post id.
 535	if ( isset( $_POST['post_ID'] ) )
 536		return edit_post();
 537
 538	$translated = _wp_translate_postdata( false );
 539	if ( is_wp_error($translated) )
 540		return $translated;
 541
 542	if ( isset($_POST['visibility']) ) {
 543		switch ( $_POST['visibility'] ) {
 544			case 'public' :
 545				$_POST['post_password'] = '';
 546				break;
 547			case 'password' :
 548				unset( $_POST['sticky'] );
 549				break;
 550			case 'private' :
 551				$_POST['post_status'] = 'private';
 552				$_POST['post_password'] = '';
 553				unset( $_POST['sticky'] );
 554				break;
 555		}
 556	}
 557
 558	// Create the post.
 559	$post_ID = wp_insert_post( $_POST );
 560	if ( is_wp_error( $post_ID ) )
 561		return $post_ID;
 562
 563	if ( empty($post_ID) )
 564		return 0;
 565
 566	add_meta( $post_ID );
 567
 568	add_post_meta( $post_ID, '_edit_last', $GLOBALS['current_user']->ID );
 569
 570	// Now that we have an ID we can fix any attachment anchor hrefs
 571	_fix_attachment_links( $post_ID );
 572
 573	wp_set_post_lock( $post_ID );
 574
 575	return $post_ID;
 576}
 577
 578/**
 579 * Calls wp_write_post() and handles the errors.
 580 *
 581 * @since 2.0.0
 582
 583 * @uses wp_write_post()
 584 * @uses is_wp_error()
 585 * @uses wp_die()
 586 * @return unknown
 587 */
 588function write_post() {
 589	$result = wp_write_post();
 590	if ( is_wp_error( $result ) )
 591		wp_die( $result->get_error_message() );
 592	else
 593		return $result;
 594}
 595
 596//
 597// Post Meta
 598//
 599
 600/**
 601 * {@internal Missing Short Description}}
 602 *
 603 * @since 1.2.0
 604 *
 605 * @param unknown_type $post_ID
 606 * @return unknown
 607 */
 608function add_meta( $post_ID ) {
 609	global $wpdb;
 610	$post_ID = (int) $post_ID;
 611
 612	$metakeyselect = isset($_POST['metakeyselect']) ? wp_unslash( trim( $_POST['metakeyselect'] ) ) : '';
 613	$metakeyinput = isset($_POST['metakeyinput']) ? wp_unslash( trim( $_POST['metakeyinput'] ) ) : '';
 614	$metavalue = isset($_POST['metavalue']) ? $_POST['metavalue'] : '';
 615	if ( is_string( $metavalue ) )
 616		$metavalue = trim( $metavalue );
 617
 618	if ( ('0' === $metavalue || ! empty ( $metavalue ) ) && ( ( ( '#NONE#' != $metakeyselect ) && !empty ( $metakeyselect) ) || !empty ( $metakeyinput ) ) ) {
 619		// We have a key/value pair. If both the select and the
 620		// input for the key have data, the input takes precedence:
 621
 622 		if ( '#NONE#' != $metakeyselect )
 623			$metakey = $metakeyselect;
 624
 625		if ( $metakeyinput )
 626			$metakey = $metakeyinput; // default
 627
 628		if ( is_protected_meta( $metakey, 'post' ) || ! current_user_can( 'add_post_meta', $post_ID, $metakey ) )
 629			return false;
 630
 631		$metakey = esc_sql( $metakey );
 632
 633		return add_post_meta( $post_ID, $metakey, $metavalue );
 634	}
 635
 636	return false;
 637} // add_meta
 638
 639/**
 640 * {@internal Missing Short Description}}
 641 *
 642 * @since 1.2.0
 643 *
 644 * @param unknown_type $mid
 645 * @return unknown
 646 */
 647function delete_meta( $mid ) {
 648	return delete_metadata_by_mid( 'post' , $mid );
 649}
 650
 651/**
 652 * Get a list of previously defined keys.
 653 *
 654 * @since 1.2.0
 655 *
 656 * @return unknown
 657 */
 658function get_meta_keys() {
 659	global $wpdb;
 660
 661	$keys = $wpdb->get_col( "
 662			SELECT meta_key
 663			FROM $wpdb->postmeta
 664			GROUP BY meta_key
 665			ORDER BY meta_key" );
 666
 667	return $keys;
 668}
 669
 670/**
 671 * {@internal Missing Short Description}}
 672 *
 673 * @since 2.1.0
 674 *
 675 * @param unknown_type $mid
 676 * @return unknown
 677 */
 678function get_post_meta_by_id( $mid ) {
 679	return get_metadata_by_mid( 'post', $mid );
 680}
 681
 682/**
 683 * {@internal Missing Short Description}}
 684 *
 685 * Some postmeta stuff.
 686 *
 687 * @since 1.2.0
 688 *
 689 * @param unknown_type $postid
 690 * @return unknown
 691 */
 692function has_meta( $postid ) {
 693	global $wpdb;
 694
 695	return $wpdb->get_results( $wpdb->prepare("SELECT meta_key, meta_value, meta_id, post_id
 696			FROM $wpdb->postmeta WHERE post_id = %d
 697			ORDER BY meta_key,meta_id", $postid), ARRAY_A );
 698}
 699
 700/**
 701 * {@internal Missing Short Description}}
 702 *
 703 * @since 1.2.0
 704 *
 705 * @param unknown_type $meta_id
 706 * @param unknown_type $meta_key Expect Slashed
 707 * @param unknown_type $meta_value Expect Slashed
 708 * @return unknown
 709 */
 710function update_meta( $meta_id, $meta_key, $meta_value ) {
 711	$meta_key = wp_unslash( $meta_key );
 712	$meta_value = wp_unslash( $meta_value );
 713
 714	return update_metadata_by_mid( 'post', $meta_id, $meta_value, $meta_key );
 715}
 716
 717//
 718// Private
 719//
 720
 721/**
 722 * Replace hrefs of attachment anchors with up-to-date permalinks.
 723 *
 724 * @since 2.3.0
 725 * @access private
 726 *
 727 * @param unknown_type $post_ID
 728 * @return unknown
 729 */
 730function _fix_attachment_links( $post_ID ) {
 731	$post = get_post( $post_ID, ARRAY_A );
 732	$content = $post['post_content'];
 733
 734	// quick sanity check, don't run if no pretty permalinks or post is not published
 735	if ( !get_option('permalink_structure') || $post['post_status'] != 'publish' )
 736		return;
 737
 738	// Short if there aren't any links or no '?attachment_id=' strings (strpos cannot be zero)
 739	if ( !strpos($content, '?attachment_id=') || !preg_match_all( '/<a ([^>]+)>[\s\S]+?<\/a>/', $content, $link_matches ) )
 740		return;
 741
 742	$site_url = get_bloginfo('url');
 743	$site_url = substr( $site_url, (int) strpos($site_url, '://') ); // remove the http(s)
 744	$replace = '';
 745
 746	foreach ( $link_matches[1] as $key => $value ) {
 747		if ( !strpos($value, '?attachment_id=') || !strpos($value, 'wp-att-')
 748			|| !preg_match( '/href=(["\'])[^"\']*\?attachment_id=(\d+)[^"\']*\\1/', $value, $url_match )
 749			|| !preg_match( '/rel=["\'][^"\']*wp-att-(\d+)/', $value, $rel_match ) )
 750				continue;
 751
 752		$quote = $url_match[1]; // the quote (single or double)
 753		$url_id = (int) $url_match[2];
 754		$rel_id = (int) $rel_match[1];
 755
 756		if ( !$url_id || !$rel_id || $url_id != $rel_id || strpos($url_match[0], $site_url) === false )
 757			continue;
 758
 759		$link = $link_matches[0][$key];
 760		$replace = str_replace( $url_match[0], 'href=' . $quote . get_attachment_link( $url_id ) . $quote, $link );
 761
 762		$content = str_replace( $link, $replace, $content );
 763	}
 764
 765	if ( $replace ) {
 766		$post['post_content'] = $content;
 767		// Escape data pulled from DB.
 768		$post = add_magic_quotes($post);
 769
 770		return wp_update_post($post);
 771	}
 772}
 773
 774/**
 775 * Move child posts to a new parent.
 776 *
 777 * @since 2.3.0
 778 * @access private
 779 *
 780 * @param unknown_type $old_ID
 781 * @param unknown_type $new_ID
 782 * @return unknown
 783 */
 784function _relocate_children( $old_ID, $new_ID ) {
 785	global $wpdb;
 786	$old_ID = (int) $old_ID;
 787	$new_ID = (int) $new_ID;
 788
 789	$children = $wpdb->get_col( $wpdb->prepare("
 790		SELECT post_id
 791		FROM $wpdb->postmeta
 792		WHERE meta_key = '_wp_attachment_temp_parent'
 793		AND meta_value = %d", $old_ID) );
 794
 795	foreach ( $children as $child_id ) {
 796		$wpdb->update($wpdb->posts, array('post_parent' => $new_ID), array('ID' => $child_id) );
 797		delete_post_meta($child_id, '_wp_attachment_temp_parent');
 798	}
 799}
 800
 801/**
 802 * Get all the possible statuses for a post_type
 803 *
 804 * @since 2.5.0
 805 *
 806 * @param string $type The post_type you want the statuses for
 807 * @return array As array of all the statuses for the supplied post type
 808 */
 809function get_available_post_statuses($type = 'post') {
 810	$stati = wp_count_posts($type);
 811
 812	return array_keys(get_object_vars($stati));
 813}
 814
 815/**
 816 * Run the wp query to fetch the posts for listing on the edit posts page
 817 *
 818 * @since 2.5.0
 819 *
 820 * @param array|bool $q Array of query variables to use to build the query or false to use $_GET superglobal.
 821 * @return array
 822 */
 823function wp_edit_posts_query( $q = false ) {
 824	if ( false === $q )
 825		$q = $_GET;
 826	$q['m'] = isset($q['m']) ? (int) $q['m'] : 0;
 827	$q['cat'] = isset($q['cat']) ? (int) $q['cat'] : 0;
 828	$post_stati  = get_post_stati();
 829
 830	if ( isset($q['post_type']) && in_array( $q['post_type'], get_post_types() ) )
 831		$post_type = $q['post_type'];
 832	else
 833		$post_type = 'post';
 834
 835	$avail_post_stati = get_available_post_statuses($post_type);
 836
 837	if ( isset($q['post_status']) && in_array( $q['post_status'], $post_stati ) ) {
 838		$post_status = $q['post_status'];
 839		$perm = 'readable';
 840	}
 841
 842	if ( isset($q['orderby']) )
 843		$orderby = $q['orderby'];
 844	elseif ( isset($q['post_status']) && in_array($q['post_status'], array('pending', 'draft')) )
 845		$orderby = 'modified';
 846
 847	if ( isset($q['order']) )
 848		$order = $q['order'];
 849	elseif ( isset($q['post_status']) && 'pending' == $q['post_status'] )
 850		$order = 'ASC';
 851
 852	$per_page = 'edit_' . $post_type . '_per_page';
 853	$posts_per_page = (int) get_user_option( $per_page );
 854	if ( empty( $posts_per_page ) || $posts_per_page < 1 )
 855		$posts_per_page = 20;
 856
 857	$posts_per_page = apply_filters( $per_page, $posts_per_page );
 858	$posts_per_page = apply_filters( 'edit_posts_per_page', $posts_per_page, $post_type );
 859
 860	$query = compact('post_type', 'post_status', 'perm', 'order', 'orderby', 'posts_per_page');
 861
 862	// Hierarchical types require special args.
 863	if ( is_post_type_hierarchical( $post_type ) && !isset($orderby) ) {
 864		$query['orderby'] = 'menu_order title';
 865		$query['order'] = 'asc';
 866		$query['posts_per_page'] = -1;
 867		$query['posts_per_archive_page'] = -1;
 868	}
 869
 870	if ( ! empty( $q['show_sticky'] ) )
 871		$query['post__in'] = (array) get_option( 'sticky_posts' );
 872
 873	wp( $query );
 874
 875	return $avail_post_stati;
 876}
 877
 878/**
 879 * {@internal Missing Short Description}}
 880 *
 881 * @since 2.5.0
 882 *
 883 * @param unknown_type $type
 884 * @return unknown
 885 */
 886function get_available_post_mime_types($type = 'attachment') {
 887	global $wpdb;
 888
 889	$types = $wpdb->get_col($wpdb->prepare("SELECT DISTINCT post_mime_type FROM $wpdb->posts WHERE post_type = %s", $type));
 890	return $types;
 891}
 892
 893/**
 894 * Executes a query for attachments. An array of WP_Query arguments
 895 * can be passed in, which will override the arguments set by this function.
 896 *
 897 * @since 2.5.0
 898 * @uses apply_filters() Calls 'upload_per_page' on posts_per_page argument
 899 *
 900 * @param array|bool $q Array of query variables to use to build the query or false to use $_GET superglobal.
 901 * @return array
 902 */
 903function wp_edit_attachments_query( $q = false ) {
 904	if ( false === $q )
 905		$q = $_GET;
 906
 907	$q['m']   = isset( $q['m'] ) ? (int) $q['m'] : 0;
 908	$q['cat'] = isset( $q['cat'] ) ? (int) $q['cat'] : 0;
 909	$q['post_type'] = 'attachment';
 910	$post_type = get_post_type_object( 'attachment' );
 911	$states = 'inherit';
 912	if ( current_user_can( $post_type->cap->read_private_posts ) )
 913		$states .= ',private';
 914
 915	$q['post_status'] = isset( $q['status'] ) && 'trash' == $q['status'] ? 'trash' : $states;
 916	$media_per_page = (int) get_user_option( 'upload_per_page' );
 917	if ( empty( $media_per_page ) || $media_per_page < 1 )
 918		$media_per_page = 20;
 919	$q['posts_per_page'] = apply_filters( 'upload_per_page', $media_per_page );
 920
 921	$post_mime_types = get_post_mime_types();
 922	$avail_post_mime_types = get_available_post_mime_types('attachment');
 923
 924	if ( isset($q['post_mime_type']) && !array_intersect( (array) $q['post_mime_type'], array_keys($post_mime_types) ) )
 925		unset($q['post_mime_type']);
 926
 927	if ( isset($q['detached']) )
 928		add_filter('posts_where', '_edit_attachments_query_helper');
 929
 930	wp( $q );
 931
 932	if ( isset($q['detached']) )
 933		remove_filter('posts_where', '_edit_attachments_query_helper');
 934
 935	return array($post_mime_types, $avail_post_mime_types);
 936}
 937
 938function _edit_attachments_query_helper($where) {
 939	global $wpdb;
 940	return $where .= " AND {$wpdb->posts}.post_parent < 1";
 941}
 942
 943/**
 944 * Returns the list of classes to be used by a metabox
 945 *
 946 * @uses get_user_option()
 947 * @since 2.5.0
 948 *
 949 * @param unknown_type $id
 950 * @param unknown_type $page
 951 * @return unknown
 952 */
 953function postbox_classes( $id, $page ) {
 954	if ( isset( $_GET['edit'] ) && $_GET['edit'] == $id ) {
 955		$classes = array( '' );
 956	} elseif ( $closed = get_user_option('closedpostboxes_'.$page ) ) {
 957		if ( !is_array( $closed ) ) {
 958			$classes = array( '' );
 959		} else {
 960			$classes = in_array( $id, $closed ) ? array( 'closed' ) : array( '' );
 961		}
 962	} else {
 963		$classes = array( '' );
 964	}
 965
 966	$classes = apply_filters( "postbox_classes_{$page}_{$id}", $classes );
 967	return implode( ' ', $classes );
 968}
 969
 970/**
 971 * {@internal Missing Short Description}}
 972 *
 973 * @since 2.5.0
 974 *
 975 * @param int|object $id    Post ID or post object.
 976 * @param string $title (optional) Title
 977 * @param string $name (optional) Name
 978 * @return array With two entries of type string
 979 */
 980function get_sample_permalink($id, $title = null, $name = null) {
 981	$post = get_post($id);
 982	if ( !$post->ID )
 983		return array('', '');
 984
 985	$ptype = get_post_type_object($post->post_type);
 986
 987	$original_status = $post->post_status;
 988	$original_date = $post->post_date;
 989	$original_name = $post->post_name;
 990
 991	// Hack: get_permalink would return ugly permalink for
 992	// drafts, so we will fake, that our post is published
 993	if ( in_array($post->post_status, array('draft', 'pending')) ) {
 994		$post->post_status = 'publish';
 995		$post->post_name = sanitize_title($post->post_name ? $post->post_name : $post->post_title, $post->ID);
 996	}
 997
 998	// If the user wants to set a new name -- override the current one
 999	// Note: if empty name is supplied -- use the title instead, see #6072
1000	if ( !is_null($name) )
1001		$post->post_name = sanitize_title($name ? $name : $title, $post->ID);
1002
1003	$post->post_name = wp_unique_post_slug($post->post_name, $post->ID, $post->post_status, $post->post_type, $post->post_parent);
1004
1005	$post->filter = 'sample';
1006
1007	$permalink = get_permalink($post, true);
1008
1009	// Replace custom post_type Token with generic pagename token for ease of use.
1010	$permalink = str_replace("%$post->post_type%", '%pagename%', $permalink);
1011
1012	// Handle page hierarchy
1013	if ( $ptype->hierarchical ) {
1014		$uri = get_page_uri($post);
1015		$uri = untrailingslashit($uri);
1016		$uri = strrev( stristr( strrev( $uri ), '/' ) );
1017		$uri = untrailingslashit($uri);
1018		$uri = apply_filters( 'editable_slug', $uri );
1019		if ( !empty($uri) )
1020			$uri .= '/';
1021		$permalink = str_replace('%pagename%', "{$uri}%pagename%", $permalink);
1022	}
1023
1024	$permalink = array($permalink, apply_filters('editable_slug', $post->post_name));
1025	$post->post_status = $original_status;
1026	$post->post_date = $original_date;
1027	$post->post_name = $original_name;
1028	unset($post->filter);
1029
1030	return $permalink;
1031}
1032
1033/**
1034 * Returns the HTML of the sample permalink slug editor.
1035 *
1036 * @since 2.5.0
1037 *
1038 * @param int|object $id Post ID or post object.
1039 * @param string $new_title Optional. New title.
1040 * @param string $new_slug Optional. New slug.
1041 * @return string The HTML of the sample permalink slug editor.
1042 */
1043function get_sample_permalink_html( $id, $new_title = null, $new_slug = null ) {
1044	global $wpdb;
1045	$post = get_post($id);
1046
1047	list($permalink, $post_name) = get_sample_permalink($post->ID, $new_title, $new_slug);
1048
1049	if ( 'publish' == get_post_status( $post ) ) {
1050		$ptype = get_post_type_object($post->post_type);
1051		$view_post = $ptype->labels->view_item;
1052		$title = __('Click to edit this part of the permalink');
1053	} else {
1054		$title = __('Temporary permalink. Click to edit this part.');
1055	}
1056
1057	if ( false === strpos($permalink, '%postname%') && false === strpos($permalink, '%pagename%') ) {
1058		$return = '<strong>' . __('Permalink:') . "</strong>\n" . '<span id="sample-permalink" tabindex="-1">' . $permalink . "</span>\n";
1059		if ( '' == get_option( 'permalink_structure' ) && current_user_can( 'manage_options' ) && !( 'page' == get_option('show_on_front') && $id == get_option('page_on_front') ) )
1060			$return .= '<span id="change-permalinks"><a href="options-permalink.php" class="button button-small" target="_blank">' . __('Change Permalinks') . "</a></span>\n";
1061		if ( isset( $view_post ) )
1062			$return .= "<span id='view-post-btn'><a href='$permalink' class='button button-small'>$view_post</a></span>\n";
1063
1064		$return = apply_filters('get_sample_permalink_html', $return, $id, $new_title, $new_slug);
1065
1066		return $return;
1067	}
1068
1069	if ( function_exists('mb_strlen') ) {
1070		if ( mb_strlen($post_name) > 30 ) {
1071			$post_name_abridged = mb_substr($post_name, 0, 14). '&hellip;' . mb_substr($post_name, -14);
1072		} else {
1073			$post_name_abridged = $post_name;
1074		}
1075	} else {
1076		if ( strlen($post_name) > 30 ) {
1077			$post_name_abridged = substr($post_name, 0, 14). '&hellip;' . substr($post_name, -14);
1078		} else {
1079			$post_name_abridged = $post_name;
1080		}
1081	}
1082
1083	$post_name_html = '<span id="editable-post-name" title="' . $title . '">' . $post_name_abridged . '</span>';
1084	$display_link = str_replace(array('%pagename%','%postname%'), $post_name_html, $permalink);
1085	$view_link = str_replace(array('%pagename%','%postname%'), $post_name, $permalink);
1086	$return =  '<strong>' . __('Permalink:') . "</strong>\n";
1087	$return .= '<span id="sample-permalink" tabindex="-1">' . $display_link . "</span>\n";
1088	$return .= '&lrm;'; // Fix bi-directional text display defect in RTL languages.
1089	$return .= '<span id="edit-slug-buttons"><a href="#post_name" class="edit-slug button button-small hide-if-no-js" onclick="editPermalink(' . $id . '); return false;">' . __('Edit') . "</a></span>\n";
1090	$return .= '<span id="editable-post-name-full">' . $post_name . "</span>\n";
1091	if ( isset($view_post) )
1092		$return .= "<span id='view-post-btn'><a href='$view_link' class='button button-small'>$view_post</a></span>\n";
1093
1094	$return = apply_filters('get_sample_permalink_html', $return, $id, $new_title, $new_slug);
1095
1096	return $return;
1097}
1098
1099/**
1100 * Output HTML for the post thumbnail meta-box.
1101 *
1102 * @since 2.9.0
1103 *
1104 * @param int $thumbnail_id ID of the attachment used for thumbnail
1105 * @param mixed $post The post ID or object associated with the thumbnail, defaults to global $post.
1106 * @return string html
1107 */
1108function _wp_post_thumbnail_html( $thumbnail_id = null, $post = null ) {
1109	global $content_width, $_wp_additional_image_sizes;
1110
1111	$post = get_post( $post );
1112
1113	$upload_iframe_src = esc_url( get_upload_iframe_src('image', $post->ID ) );
1114	$set_thumbnail_link = '<p class="hide-if-no-js"><a title="' . esc_attr__( 'Set featured image' ) . '" href="%s" id="set-post-thumbnail" class="thickbox">%s</a></p>';
1115	$content = sprintf( $set_thumbnail_link, $upload_iframe_src, esc_html__( 'Set featured image' ) );
1116
1117	if ( $thumbnail_id && get_post( $thumbnail_id ) ) {
1118		$old_content_width = $content_width;
1119		$content_width = 266;
1120		if ( !isset( $_wp_additional_image_sizes['post-thumbnail'] ) )
1121			$thumbnail_html = wp_get_attachment_image( $thumbnail_id, array( $content_width, $content_width ) );
1122		else
1123			$thumbnail_html = wp_get_attachment_image( $thumbnail_id, 'post-thumbnail' );
1124		if ( !empty( $thumbnail_html ) ) {
1125			$ajax_nonce = wp_create_nonce( 'set_post_thumbnail-' . $post->ID );
1126			$content = sprintf( $set_thumbnail_link, $upload_iframe_src, $thumbnail_html );
1127			$content .= '<p class="hide-if-no-js"><a href="#" id="remove-post-thumbnail" onclick="WPRemoveThumbnail(\'' . $ajax_nonce . '\');return false;">' . esc_html__( 'Remove featured image' ) . '</a></p>';
1128		}
1129		$content_width = $old_content_width;
1130	}
1131
1132	return apply_filters( 'admin_post_thumbnail_html', $content, $post->ID );
1133}
1134
1135/**
1136 * Check to see if the post is currently being edited by another user.
1137 *
1138 * @since 2.5.0
1139 *
1140 * @param int $post_id ID of the post to check for editing
1141 * @return bool|int False: not locked or locked by current user. Int: user ID of user with lock.
1142 */
1143function wp_check_post_lock( $post_id ) {
1144	if ( !$post = get_post( $post_id ) )
1145		return false;
1146
1147	if ( !$lock = get_post_meta( $post->ID, '_edit_lock', true ) )
1148		return false;
1149
1150	$lock = explode( ':', $lock );
1151	$time = $lock[0];
1152	$user = isset( $lock[1] ) ? $lock[1] : get_post_meta( $post->ID, '_edit_last', true );
1153
1154	$time_window = apply_filters( 'wp_check_post_lock_window', 120 );
1155
1156	if ( $time && $time > time() - $time_window && $user != get_current_user_id() )
1157		return $user;
1158	return false;
1159}
1160
1161/**
1162 * Mark the post as currently being edited by the current user
1163 *
1164 * @since 2.5.0
1165 *
1166 * @param int $post_id ID of the post to being edited
1167 * @return bool|array Returns false if the post doesn't exist of there is no current user, or
1168 * 	an array of the lock time and the user ID.
1169 */
1170function wp_set_post_lock( $post_id ) {
1171	if ( !$post = get_post( $post_id ) )
1172		return false;
1173	if ( 0 == ($user_id = get_current_user_id()) )
1174		return false;
1175
1176	$now = time();
1177	$lock = "$now:$user_id";
1178
1179	update_post_meta( $post->ID, '_edit_lock', $lock );
1180	return array( $now, $user_id );
1181}
1182
1183/**
1184 * Outputs the HTML for the notice to say that someone else is editing or has taken over editing of this post.
1185 *
1186 * @since 2.8.5
1187 * @return none
1188 */
1189function _admin_notice_post_locked() {
1190	if ( ! $post = get_post() )
1191		return;
1192
1193	if ( $user = wp_check_post_lock( $post->ID ) ) {
1194		$user = get_userdata( $user );
1195		$locked = apply_filters( 'show_post_locked_dialog', true, $post, $user );
1196	} else {
1197		$locked = false;
1198	}
1199
1200	$class = $locked ? '' : ' class="hidden"';
1201
1202	?>
1203	<div id="notification-dialog-wrap"<?php echo $class; ?>>
1204	<div id="notification-dialog-background"></div>
1205	<div id="notification-dialog">
1206	<?php
1207
1208	if ( $locked ) {
1209		$preview_link = set_url_scheme( add_query_arg( 'preview', 'true', get_permalink( $post->ID ) ) );
1210
1211		if ( 'publish' == $post->post_status || $user->ID != $post->post_author ) {
1212			// Latest content is in autosave
1213			$nonce = wp_create_nonce( 'post_preview_' . $post->ID );
1214			$preview_link = add_query_arg( array( 'preview_id' => $post->ID, 'preview_nonce' => $nonce ), $preview_link );
1215		}
1216
1217		$preview_link = apply_filters( 'preview_post_link', $preview_link );
1218
1219		?>
1220		<div class="post-locked-message">
1221		<div class="post-locked-avatar"><?php echo get_avatar( $user->ID, 64 ); ?></div>
1222		<p class="currently-editing" tabindex="0"><?php esc_html_e( sprintf( __( 'This content is currently locked. If you take over, %s will be blocked from continuing to edit.' ), $user->display_name ) ); ?></p>
1223		<p>
1224		<a class="button" href="<?php echo esc_url( wp_get_referer() ); ?>"><?php _e('Go back'); ?></a>
1225		<a class="button" href="<?php echo esc_url( $preview_link ); ?>"><?php _e('Preview'); ?></a>
1226		<?php
1227
1228		// Allow plugins to prevent some users overriding the post lock
1229		if ( apply_filters( 'override_post_lock', true, $post, $user ) ) {
1230			?>
1231			<a class="button button-primary" href="<?php echo esc_url( add_query_arg( 'get-post-lock', '1', get_edit_post_link( $post->ID, 'url' ) ) ); ?>"><?php _e('Take over'); ?></a>
1232			<?php
1233		}
1234
1235		?>
1236		</p>
1237		</div>
1238		<?php
1239	} else {
1240		?>
1241		<div class="post-taken-over">
1242			<div class="post-locked-avatar"></div>
1243			<p class="currently-editing" tabindex="0"></p>
1244			<p><a class="button button-primary" href="<?php echo esc_url( admin_url('edit.php') ); ?>"><?php _e('Go to All Posts'); ?></a></p>
1245		</div>
1246		<?php
1247	}
1248
1249	?>
1250	</div>
1251	</div>
1252	<?php
1253}
1254
1255/**
1256 * Creates autosave data for the specified post from $_POST data.
1257 *
1258 * @package WordPress
1259 * @subpackage Post_Revisions
1260 * @since 2.6.0
1261 *
1262 * @uses _wp_translate_postdata()
1263 * @uses _wp_post_revision_fields()
1264 *
1265 * @return unknown
1266 */
1267function wp_create_post_autosave( $post_id ) {
1268	$translated = _wp_translate_postdata( true );
1269	if ( is_wp_error( $translated ) )
1270		return $translated;
1271
1272	$post_author = get_current_user_id();
1273
1274	// Store one autosave per author. If there is already an autosave, overwrite it.
1275	if ( $old_autosave = wp_get_post_autosave( $post_id, $post_author ) ) {
1276		$new_autosave = _wp_post_revision_fields( $_POST, true );
1277		$new_autosave['ID'] = $old_autosave->ID;
1278		$new_autosave['post_author'] = $post_author;
1279		return wp_update_post( $new_autosave );
1280	}
1281
1282	// _wp_put_post_revision() expects unescaped.
1283	$_POST = wp_unslash($_POST);
1284
1285	// Otherwise create the new autosave as a special post revision
1286	return _wp_put_post_revision( $_POST, true );
1287}
1288
1289/**
1290 * Save draft or manually autosave for showing preview.
1291 *
1292 * @package WordPress
1293 * @since 2.7.0
1294 *
1295 * @uses get_post_status()
1296 * @uses edit_post()
1297 * @uses get_post()
1298 * @uses current_user_can()
1299 * @uses wp_die()
1300 * @uses wp_create_post_autosave()
1301 * @uses add_query_arg()
1302 * @uses wp_create_nonce()
1303 *
1304 * @return str URL to redirect to show the preview
1305 */
1306function post_preview() {
1307
1308	$post_ID = (int) $_POST['post_ID'];
1309	$status = get_post_status( $post_ID );
1310	if ( 'auto-draft' == $status )
1311		wp_die( __('Preview not available. Please save as a draft first.') );
1312
1313	if ( isset($_POST['catslist']) )
1314		$_POST['post_category'] = explode(",", $_POST['catslist']);
1315
1316	if ( isset($_POST['tags_input']) )
1317		$_POST['tags_input'] = explode(",", $_POST['tags_input']);
1318
1319	if ( $_POST['post_type'] == 'page' || empty($_POST['post_category']) )
1320		unset($_POST['post_category']);
1321
1322	$_POST['ID'] = $post_ID;
1323	$post = get_post($post_ID);
1324
1325	if ( 'page' == $post->post_type ) {
1326		if ( !current_user_can('edit_page', $post_ID) )
1327			wp_die(__('You are not allowed to edit this page.'));
1328	} else {
1329		if ( !current_user_can('edit_post', $post_ID) )
1330			wp_die(__('You are not allowed to edit this post.'));
1331	}
1332
1333	$user_id = get_current_user_id();
1334	if ( 'draft' == $post->post_status && $user_id == $post->post_author ) {
1335		$id = edit_post();
1336	} else { // Non drafts are not overwritten. The autosave is stored in a special post revision.
1337		$id = wp_create_post_autosave( $post->ID );
1338		if ( ! is_wp_error($id) )
1339			$id = $post->ID;
1340	}
1341
1342	if ( is_wp_error($id) )
1343		wp_die( $id->get_error_message() );
1344
1345	if ( $_POST['post_status'] == 'draft' && $user_id == $post->post_author ) {
1346		$url = add_query_arg( 'preview', 'true', get_permalink($id) );
1347	} else {
1348		$nonce = wp_create_nonce('post_preview_' . $id);
1349		$url = add_query_arg( array( 'preview' => 'true', 'preview_id' => $id, 'preview_nonce' => $nonce ), get_permalink($id) );
1350	}
1351
1352	return apply_filters( 'preview_post_link', $url );
1353}