web/wp-admin/includes/post.php
branchwordpress
changeset 109 03b0d1493584
child 132 4d4862461b8d
equal deleted inserted replaced
-1:000000000000 109:03b0d1493584
       
     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 post_data array Array of post data. Defaults to the contents of $_POST.
       
    19  * @return object|bool WP_Error on failure, true on success.
       
    20  */
       
    21 function _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 	$post_data['post_content'] = isset($post_data['content']) ? $post_data['content'] : '';
       
    29 	$post_data['post_excerpt'] = isset($post_data['excerpt']) ? $post_data['excerpt'] : '';
       
    30 	$post_data['post_parent'] = isset($post_data['parent_id'])? $post_data['parent_id'] : '';
       
    31 	if ( isset($post_data['trackback_url']) )
       
    32 		$post_data['to_ping'] = $post_data['trackback_url'];
       
    33 
       
    34 	if (!empty ( $post_data['post_author_override'] ) ) {
       
    35 		$post_data['post_author'] = (int) $post_data['post_author_override'];
       
    36 	} else {
       
    37 		if (!empty ( $post_data['post_author'] ) ) {
       
    38 			$post_data['post_author'] = (int) $post_data['post_author'];
       
    39 		} else {
       
    40 			$post_data['post_author'] = (int) $post_data['user_ID'];
       
    41 		}
       
    42 	}
       
    43 
       
    44 	if ( isset($post_data['user_ID']) && ($post_data['post_author'] != $post_data['user_ID']) ) {
       
    45 		if ( 'page' == $post_data['post_type'] ) {
       
    46 			if ( !current_user_can( 'edit_others_pages' ) ) {
       
    47 				return new WP_Error( 'edit_others_pages', $update ?
       
    48 					__( 'You are not allowed to edit pages as this user.' ) :
       
    49 					__( 'You are not allowed to create pages as this user.' )
       
    50 				);
       
    51 			}
       
    52 		} else {
       
    53 			if ( !current_user_can( 'edit_others_posts' ) ) {
       
    54 				return new WP_Error( 'edit_others_posts', $update ?
       
    55 					__( 'You are not allowed to edit posts as this user.' ) :
       
    56 					__( 'You are not allowed to post as this user.' )
       
    57 				);
       
    58 			}
       
    59 		}
       
    60 	}
       
    61 
       
    62 	// What to do based on which button they pressed
       
    63 	if ( isset($post_data['saveasdraft']) && '' != $post_data['saveasdraft'] )
       
    64 		$post_data['post_status'] = 'draft';
       
    65 	if ( isset($post_data['saveasprivate']) && '' != $post_data['saveasprivate'] )
       
    66 		$post_data['post_status'] = 'private';
       
    67 	if ( isset($post_data['publish']) && ( '' != $post_data['publish'] ) && ( $post_data['post_status'] != 'private' ) )
       
    68 		$post_data['post_status'] = 'publish';
       
    69 	if ( isset($post_data['advanced']) && '' != $post_data['advanced'] )
       
    70 		$post_data['post_status'] = 'draft';
       
    71 	if ( isset($post_data['pending']) && '' != $post_data['pending'] )
       
    72 		$post_data['post_status'] = 'pending';
       
    73 
       
    74 	$previous_status = get_post_field('post_status',  isset($post_data['ID']) ? $post_data['ID'] : $post_data['temp_ID']);
       
    75 
       
    76 	// Posts 'submitted for approval' present are submitted to $_POST the same as if they were being published.
       
    77 	// Change status from 'publish' to 'pending' if user lacks permissions to publish or to resave published posts.
       
    78 	if ( 'page' == $post_data['post_type'] ) {
       
    79 		$publish_cap = 'publish_pages';
       
    80 		$edit_cap = 'edit_published_pages';
       
    81 	} else {
       
    82 		$publish_cap = 'publish_posts';
       
    83 		$edit_cap = 'edit_published_posts';
       
    84 	}
       
    85 	if ( isset($post_data['post_status']) && ('publish' == $post_data['post_status'] && !current_user_can( $publish_cap )) )
       
    86 		if ( $previous_status != 'publish' || !current_user_can( $edit_cap ) )
       
    87 			$post_data['post_status'] = 'pending';
       
    88 
       
    89 	if ( ! isset($post_data['post_status']) )
       
    90 		$post_data['post_status'] = $previous_status;
       
    91 
       
    92 	if (!isset( $post_data['comment_status'] ))
       
    93 		$post_data['comment_status'] = 'closed';
       
    94 
       
    95 	if (!isset( $post_data['ping_status'] ))
       
    96 		$post_data['ping_status'] = 'closed';
       
    97 
       
    98 	foreach ( array('aa', 'mm', 'jj', 'hh', 'mn') as $timeunit ) {
       
    99 		if ( !empty( $post_data['hidden_' . $timeunit] ) && $post_data['hidden_' . $timeunit] != $post_data[$timeunit] ) {
       
   100 			$post_data['edit_date'] = '1';
       
   101 			break;
       
   102 		}
       
   103 	}
       
   104 
       
   105 	if ( !empty( $post_data['edit_date'] ) ) {
       
   106 		$aa = $post_data['aa'];
       
   107 		$mm = $post_data['mm'];
       
   108 		$jj = $post_data['jj'];
       
   109 		$hh = $post_data['hh'];
       
   110 		$mn = $post_data['mn'];
       
   111 		$ss = $post_data['ss'];
       
   112 		$aa = ($aa <= 0 ) ? date('Y') : $aa;
       
   113 		$mm = ($mm <= 0 ) ? date('n') : $mm;
       
   114 		$jj = ($jj > 31 ) ? 31 : $jj;
       
   115 		$jj = ($jj <= 0 ) ? date('j') : $jj;
       
   116 		$hh = ($hh > 23 ) ? $hh -24 : $hh;
       
   117 		$mn = ($mn > 59 ) ? $mn -60 : $mn;
       
   118 		$ss = ($ss > 59 ) ? $ss -60 : $ss;
       
   119 		$post_data['post_date'] = sprintf( "%04d-%02d-%02d %02d:%02d:%02d", $aa, $mm, $jj, $hh, $mn, $ss );
       
   120 		$post_data['post_date_gmt'] = get_gmt_from_date( $post_data['post_date'] );
       
   121 	}
       
   122 
       
   123 	return $post_data;
       
   124 }
       
   125 
       
   126 /**
       
   127  * Update an existing post with values provided in $_POST.
       
   128  *
       
   129  * @since unknown
       
   130  *
       
   131  * @param array $post_data Optional.
       
   132  * @return int Post ID.
       
   133  */
       
   134 function edit_post( $post_data = null ) {
       
   135 
       
   136 	if ( empty($post_data) )
       
   137 		$post_data = &$_POST;
       
   138 
       
   139 	$post_ID = (int) $post_data['post_ID'];
       
   140 
       
   141 	if ( 'page' == $post_data['post_type'] ) {
       
   142 		if ( !current_user_can( 'edit_page', $post_ID ) )
       
   143 			wp_die( __('You are not allowed to edit this page.' ));
       
   144 	} else {
       
   145 		if ( !current_user_can( 'edit_post', $post_ID ) )
       
   146 			wp_die( __('You are not allowed to edit this post.' ));
       
   147 	}
       
   148 
       
   149 	// Autosave shouldn't save too soon after a real save
       
   150 	if ( 'autosave' == $post_data['action'] ) {
       
   151 		$post =& get_post( $post_ID );
       
   152 		$now = time();
       
   153 		$then = strtotime($post->post_date_gmt . ' +0000');
       
   154 		$delta = AUTOSAVE_INTERVAL / 2;
       
   155 		if ( ($now - $then) < $delta )
       
   156 			return $post_ID;
       
   157 	}
       
   158 
       
   159 	$post_data = _wp_translate_postdata( true, $post_data );
       
   160 	if ( is_wp_error($post_data) )
       
   161 		wp_die( $post_data->get_error_message() );
       
   162 
       
   163 	if ( isset($post_data['visibility']) ) {
       
   164 		switch ( $post_data['visibility'] ) {
       
   165 			case 'public' :
       
   166 				$post_data['post_password'] = '';
       
   167 				break;
       
   168 			case 'password' :
       
   169 				unset( $post_data['sticky'] );
       
   170 				break;
       
   171 			case 'private' :
       
   172 				$post_data['post_status'] = 'private';
       
   173 				$post_data['post_password'] = '';
       
   174 				unset( $post_data['sticky'] );
       
   175 				break;
       
   176 		}
       
   177 	}
       
   178 
       
   179 	// Meta Stuff
       
   180 	if ( isset($post_data['meta']) && $post_data['meta'] ) {
       
   181 		foreach ( $post_data['meta'] as $key => $value )
       
   182 			update_meta( $key, $value['key'], $value['value'] );
       
   183 	}
       
   184 
       
   185 	if ( isset($post_data['deletemeta']) && $post_data['deletemeta'] ) {
       
   186 		foreach ( $post_data['deletemeta'] as $key => $value )
       
   187 			delete_meta( $key );
       
   188 	}
       
   189 
       
   190 	add_meta( $post_ID );
       
   191 
       
   192 	wp_update_post( $post_data );
       
   193 
       
   194 	// Reunite any orphaned attachments with their parent
       
   195 	if ( !$draft_ids = get_user_option( 'autosave_draft_ids' ) )
       
   196 		$draft_ids = array();
       
   197 	if ( $draft_temp_id = (int) array_search( $post_ID, $draft_ids ) )
       
   198 		_relocate_children( $draft_temp_id, $post_ID );
       
   199 
       
   200 	// Now that we have an ID we can fix any attachment anchor hrefs
       
   201 	_fix_attachment_links( $post_ID );
       
   202 
       
   203 	wp_set_post_lock( $post_ID, $GLOBALS['current_user']->ID );
       
   204 
       
   205 	if ( current_user_can( 'edit_others_posts' ) ) {
       
   206 		if ( !empty($post_data['sticky']) )
       
   207 			stick_post($post_ID);
       
   208 		else
       
   209 			unstick_post($post_ID);
       
   210 	}
       
   211 
       
   212 	return $post_ID;
       
   213 }
       
   214 
       
   215 /**
       
   216  * {@internal Missing Short Description}}
       
   217  *
       
   218  * Updates all bulk edited posts/pages, adding (but not removing) tags and
       
   219  * categories. Skips pages when they would be their own parent or child.
       
   220  *
       
   221  * @since unknown
       
   222  *
       
   223  * @return array
       
   224  */
       
   225 function bulk_edit_posts( $post_data = null ) {
       
   226 	global $wpdb;
       
   227 
       
   228 	if ( empty($post_data) )
       
   229 		$post_data = &$_POST;
       
   230 
       
   231 	if ( isset($post_data['post_type']) && 'page' == $post_data['post_type'] ) {
       
   232 		if ( ! current_user_can( 'edit_pages' ) )
       
   233 			wp_die( __('You are not allowed to edit pages.') );
       
   234 	} else {
       
   235 		if ( ! current_user_can( 'edit_posts' ) )
       
   236 			wp_die( __('You are not allowed to edit posts.') );
       
   237 	}
       
   238 
       
   239 	$post_IDs = array_map( 'intval', (array) $post_data['post'] );
       
   240 
       
   241 	$reset = array( 'post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tags_input', 'post_category', 'sticky' );
       
   242 	foreach ( $reset as $field ) {
       
   243 		if ( isset($post_data[$field]) && ( '' == $post_data[$field] || -1 == $post_data[$field] ) )
       
   244 			unset($post_data[$field]);
       
   245 	}
       
   246 
       
   247 	if ( isset($post_data['post_category']) ) {
       
   248 		if ( is_array($post_data['post_category']) && ! empty($post_data['post_category']) )
       
   249 			$new_cats = array_map( 'absint', $post_data['post_category'] );
       
   250 		else
       
   251 			unset($post_data['post_category']);
       
   252 	}
       
   253 
       
   254 	if ( isset($post_data['tags_input']) ) {
       
   255 		$new_tags = preg_replace( '/\s*,\s*/', ',', rtrim( trim($post_data['tags_input']), ' ,' ) );
       
   256 		$new_tags = explode(',', $new_tags);
       
   257 	}
       
   258 
       
   259 	if ( isset($post_data['post_parent']) && ($parent = (int) $post_data['post_parent']) ) {
       
   260 		$pages = $wpdb->get_results("SELECT ID, post_parent FROM $wpdb->posts WHERE post_type = 'page'");
       
   261 		$children = array();
       
   262 
       
   263 		for ( $i = 0; $i < 50 && $parent > 0; $i++ ) {
       
   264 			$children[] = $parent;
       
   265 
       
   266 			foreach ( $pages as $page ) {
       
   267 				if ( $page->ID == $parent ) {
       
   268 					$parent = $page->post_parent;
       
   269 					break;
       
   270 				}
       
   271 			}
       
   272 		}
       
   273 	}
       
   274 
       
   275 	$updated = $skipped = $locked = array();
       
   276 	foreach ( $post_IDs as $post_ID ) {
       
   277 
       
   278 		if ( isset($children) && in_array($post_ID, $children) ) {
       
   279 			$skipped[] = $post_ID;
       
   280 			continue;
       
   281 		}
       
   282 
       
   283 		if ( wp_check_post_lock( $post_ID ) ) {
       
   284 			$locked[] = $post_ID;
       
   285 			continue;
       
   286 		}
       
   287 
       
   288 		if ( isset($new_cats) ) {
       
   289 			$cats = (array) wp_get_post_categories($post_ID);
       
   290 			$post_data['post_category'] = array_unique( array_merge($cats, $new_cats) );
       
   291 		}
       
   292 
       
   293 		if ( isset($new_tags) ) {
       
   294 			$tags = wp_get_post_tags($post_ID, array('fields' => 'names'));
       
   295 			$post_data['tags_input'] = array_unique( array_merge($tags, $new_tags) );
       
   296 		}
       
   297 
       
   298 		$post_data['ID'] = $post_ID;
       
   299 		$updated[] = wp_update_post( $post_data );
       
   300 
       
   301 		if ( current_user_can( 'edit_others_posts' ) && isset( $post_data['sticky'] ) ) {
       
   302 			if ( 'sticky' == $post_data['sticky'] )
       
   303 				stick_post( $post_ID );
       
   304 			else
       
   305 				unstick_post( $post_ID );
       
   306 		}
       
   307 
       
   308 	}
       
   309 
       
   310 	return array( 'updated' => $updated, 'skipped' => $skipped, 'locked' => $locked );
       
   311 }
       
   312 
       
   313 /**
       
   314  * Default post information to use when populating the "Write Post" form.
       
   315  *
       
   316  * @since unknown
       
   317  *
       
   318  * @return unknown
       
   319  */
       
   320 function get_default_post_to_edit() {
       
   321 	if ( !empty( $_REQUEST['post_title'] ) )
       
   322 		$post_title = esc_html( stripslashes( $_REQUEST['post_title'] ));
       
   323 	else if ( !empty( $_REQUEST['popuptitle'] ) ) {
       
   324 		$post_title = esc_html( stripslashes( $_REQUEST['popuptitle'] ));
       
   325 		$post_title = funky_javascript_fix( $post_title );
       
   326 	} else {
       
   327 		$post_title = '';
       
   328 	}
       
   329 
       
   330 	$post_content = '';
       
   331 	if ( !empty( $_REQUEST['content'] ) )
       
   332 		$post_content = esc_html( stripslashes( $_REQUEST['content'] ));
       
   333 	else if ( !empty( $post_title ) ) {
       
   334 		$text       = esc_html( stripslashes( urldecode( $_REQUEST['text'] ) ) );
       
   335 		$text       = funky_javascript_fix( $text);
       
   336 		$popupurl   = esc_url($_REQUEST['popupurl']);
       
   337 		$post_content = '<a href="'.$popupurl.'">'.$post_title.'</a>'."\n$text";
       
   338 	}
       
   339 
       
   340 	if ( !empty( $_REQUEST['excerpt'] ) )
       
   341 		$post_excerpt = esc_html( stripslashes( $_REQUEST['excerpt'] ));
       
   342 	else
       
   343 		$post_excerpt = '';
       
   344 
       
   345 	$post->ID = 0;
       
   346 	$post->post_name = '';
       
   347 	$post->post_author = '';
       
   348 	$post->post_date = '';
       
   349 	$post->post_date_gmt = '';
       
   350 	$post->post_password = '';
       
   351 	$post->post_status = 'draft';
       
   352 	$post->post_type = 'post';
       
   353 	$post->to_ping = '';
       
   354 	$post->pinged = '';
       
   355 	$post->comment_status = get_option( 'default_comment_status' );
       
   356 	$post->ping_status = get_option( 'default_ping_status' );
       
   357 	$post->post_pingback = get_option( 'default_pingback_flag' );
       
   358 	$post->post_category = get_option( 'default_category' );
       
   359 	$post->post_content = apply_filters( 'default_content', $post_content);
       
   360 	$post->post_title = apply_filters( 'default_title', $post_title );
       
   361 	$post->post_excerpt = apply_filters( 'default_excerpt', $post_excerpt);
       
   362 	$post->page_template = 'default';
       
   363 	$post->post_parent = 0;
       
   364 	$post->menu_order = 0;
       
   365 
       
   366 	return $post;
       
   367 }
       
   368 
       
   369 /**
       
   370  * {@internal Missing Short Description}}
       
   371  *
       
   372  * @since unknown
       
   373  *
       
   374  * @return unknown
       
   375  */
       
   376 function get_default_page_to_edit() {
       
   377 	$page = get_default_post_to_edit();
       
   378 	$page->post_type = 'page';
       
   379 	return $page;
       
   380 }
       
   381 
       
   382 /**
       
   383  * Get an existing post and format it for editing.
       
   384  *
       
   385  * @since unknown
       
   386  *
       
   387  * @param unknown_type $id
       
   388  * @return unknown
       
   389  */
       
   390 function get_post_to_edit( $id ) {
       
   391 
       
   392 	$post = get_post( $id, OBJECT, 'edit' );
       
   393 
       
   394 	if ( $post->post_type == 'page' )
       
   395 		$post->page_template = get_post_meta( $id, '_wp_page_template', true );
       
   396 
       
   397 	return $post;
       
   398 }
       
   399 
       
   400 /**
       
   401  * Determine if a post exists based on title, content, and date
       
   402  *
       
   403  * @since unknown
       
   404  *
       
   405  * @param string $title Post title
       
   406  * @param string $content Optional post content
       
   407  * @param string $date Optional post date
       
   408  * @return int Post ID if post exists, 0 otherwise.
       
   409  */
       
   410 function post_exists($title, $content = '', $date = '') {
       
   411 	global $wpdb;
       
   412 
       
   413 	$post_title = stripslashes( sanitize_post_field( 'post_title', $title, 0, 'db' ) );
       
   414 	$post_content = stripslashes( sanitize_post_field( 'post_content', $content, 0, 'db' ) );
       
   415 	$post_date = stripslashes( sanitize_post_field( 'post_date', $date, 0, 'db' ) );
       
   416 
       
   417 	$query = "SELECT ID FROM $wpdb->posts WHERE 1=1";
       
   418 	$args = array();
       
   419 
       
   420 	if ( !empty ( $date ) ) {
       
   421 		$query .= ' AND post_date = %s';
       
   422 		$args[] = $post_date;
       
   423 	}
       
   424 
       
   425 	if ( !empty ( $title ) ) {
       
   426 		$query .= ' AND post_title = %s';
       
   427 		$args[] = $post_title;
       
   428 	}
       
   429 
       
   430 	if ( !empty ( $content ) ) {
       
   431 		$query .= 'AND post_content = %s';
       
   432 		$args[] = $post_content;
       
   433 	}
       
   434 
       
   435 	if ( !empty ( $args ) )
       
   436 		return $wpdb->get_var( $wpdb->prepare($query, $args) );
       
   437 
       
   438 	return 0;
       
   439 }
       
   440 
       
   441 /**
       
   442  * Creates a new post from the "Write Post" form using $_POST information.
       
   443  *
       
   444  * @since unknown
       
   445  *
       
   446  * @return unknown
       
   447  */
       
   448 function wp_write_post() {
       
   449 	global $user_ID;
       
   450 
       
   451 	if ( 'page' == $_POST['post_type'] ) {
       
   452 		if ( !current_user_can( 'edit_pages' ) )
       
   453 			return new WP_Error( 'edit_pages', __( 'You are not allowed to create pages on this blog.' ) );
       
   454 	} else {
       
   455 		if ( !current_user_can( 'edit_posts' ) )
       
   456 			return new WP_Error( 'edit_posts', __( 'You are not allowed to create posts or drafts on this blog.' ) );
       
   457 	}
       
   458 
       
   459 
       
   460 	// Check for autosave collisions
       
   461 	$temp_id = false;
       
   462 	if ( isset($_POST['temp_ID']) ) {
       
   463 		$temp_id = (int) $_POST['temp_ID'];
       
   464 		if ( !$draft_ids = get_user_option( 'autosave_draft_ids' ) )
       
   465 			$draft_ids = array();
       
   466 		foreach ( $draft_ids as $temp => $real )
       
   467 			if ( time() + $temp > 86400 ) // 1 day: $temp is equal to -1 * time( then )
       
   468 				unset($draft_ids[$temp]);
       
   469 
       
   470 		if ( isset($draft_ids[$temp_id]) ) { // Edit, don't write
       
   471 			$_POST['post_ID'] = $draft_ids[$temp_id];
       
   472 			unset($_POST['temp_ID']);
       
   473 			update_user_option( $user_ID, 'autosave_draft_ids', $draft_ids );
       
   474 			return edit_post();
       
   475 		}
       
   476 	}
       
   477 
       
   478 	$translated = _wp_translate_postdata( false );
       
   479 	if ( is_wp_error($translated) )
       
   480 		return $translated;
       
   481 
       
   482 	if ( isset($_POST['visibility']) ) {
       
   483 		switch ( $_POST['visibility'] ) {
       
   484 			case 'public' :
       
   485 				$_POST['post_password'] = '';
       
   486 				break;
       
   487 			case 'password' :
       
   488 				unset( $_POST['sticky'] );
       
   489 				break;
       
   490 			case 'private' :
       
   491 				$_POST['post_status'] = 'private';
       
   492 				$_POST['post_password'] = '';
       
   493 				unset( $_POST['sticky'] );
       
   494 				break;
       
   495 		}
       
   496 	}
       
   497 
       
   498 	// Create the post.
       
   499 	$post_ID = wp_insert_post( $_POST );
       
   500 	if ( is_wp_error( $post_ID ) )
       
   501 		return $post_ID;
       
   502 
       
   503 	if ( empty($post_ID) )
       
   504 		return 0;
       
   505 
       
   506 	add_meta( $post_ID );
       
   507 
       
   508 	// Reunite any orphaned attachments with their parent
       
   509 	if ( !$draft_ids = get_user_option( 'autosave_draft_ids' ) )
       
   510 		$draft_ids = array();
       
   511 	if ( $draft_temp_id = (int) array_search( $post_ID, $draft_ids ) )
       
   512 		_relocate_children( $draft_temp_id, $post_ID );
       
   513 	if ( $temp_id && $temp_id != $draft_temp_id )
       
   514 		_relocate_children( $temp_id, $post_ID );
       
   515 
       
   516 	// Update autosave collision detection
       
   517 	if ( $temp_id ) {
       
   518 		$draft_ids[$temp_id] = $post_ID;
       
   519 		update_user_option( $user_ID, 'autosave_draft_ids', $draft_ids );
       
   520 	}
       
   521 
       
   522 	// Now that we have an ID we can fix any attachment anchor hrefs
       
   523 	_fix_attachment_links( $post_ID );
       
   524 
       
   525 	wp_set_post_lock( $post_ID, $GLOBALS['current_user']->ID );
       
   526 
       
   527 	return $post_ID;
       
   528 }
       
   529 
       
   530 /**
       
   531  * Calls wp_write_post() and handles the errors.
       
   532  *
       
   533  * @since unknown
       
   534  *
       
   535  * @return unknown
       
   536  */
       
   537 function write_post() {
       
   538 	$result = wp_write_post();
       
   539 	if( is_wp_error( $result ) )
       
   540 		wp_die( $result->get_error_message() );
       
   541 	else
       
   542 		return $result;
       
   543 }
       
   544 
       
   545 //
       
   546 // Post Meta
       
   547 //
       
   548 
       
   549 /**
       
   550  * {@internal Missing Short Description}}
       
   551  *
       
   552  * @since unknown
       
   553  *
       
   554  * @param unknown_type $post_ID
       
   555  * @return unknown
       
   556  */
       
   557 function add_meta( $post_ID ) {
       
   558 	global $wpdb;
       
   559 	$post_ID = (int) $post_ID;
       
   560 
       
   561 	$protected = array( '_wp_attached_file', '_wp_attachment_metadata', '_wp_old_slug', '_wp_page_template' );
       
   562 
       
   563 	$metakeyselect = isset($_POST['metakeyselect']) ? stripslashes( trim( $_POST['metakeyselect'] ) ) : '';
       
   564 	$metakeyinput = isset($_POST['metakeyinput']) ? stripslashes( trim( $_POST['metakeyinput'] ) ) : '';
       
   565 	$metavalue = isset($_POST['metavalue']) ? maybe_serialize( stripslashes( trim( $_POST['metavalue'] ) ) ) : '';
       
   566 
       
   567 	if ( ('0' === $metavalue || !empty ( $metavalue ) ) && ((('#NONE#' != $metakeyselect) && !empty ( $metakeyselect) ) || !empty ( $metakeyinput) ) ) {
       
   568 		// We have a key/value pair. If both the select and the
       
   569 		// input for the key have data, the input takes precedence:
       
   570 
       
   571  		if ('#NONE#' != $metakeyselect)
       
   572 			$metakey = $metakeyselect;
       
   573 
       
   574 		if ( $metakeyinput)
       
   575 			$metakey = $metakeyinput; // default
       
   576 
       
   577 		if ( in_array($metakey, $protected) )
       
   578 			return false;
       
   579 
       
   580 		wp_cache_delete($post_ID, 'post_meta');
       
   581 
       
   582 		$wpdb->query( $wpdb->prepare("INSERT INTO $wpdb->postmeta (post_id,meta_key,meta_value ) VALUES (%s, %s, %s)", $post_ID, $metakey, $metavalue) );
       
   583 		return $wpdb->insert_id;
       
   584 	}
       
   585 	return false;
       
   586 } // add_meta
       
   587 
       
   588 /**
       
   589  * {@internal Missing Short Description}}
       
   590  *
       
   591  * @since unknown
       
   592  *
       
   593  * @param unknown_type $mid
       
   594  * @return unknown
       
   595  */
       
   596 function delete_meta( $mid ) {
       
   597 	global $wpdb;
       
   598 	$mid = (int) $mid;
       
   599 
       
   600 	$post_id = $wpdb->get_var( $wpdb->prepare("SELECT post_id FROM $wpdb->postmeta WHERE meta_id = %d", $mid) );
       
   601 	wp_cache_delete($post_id, 'post_meta');
       
   602 
       
   603 	return $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->postmeta WHERE meta_id = %d", $mid) );
       
   604 }
       
   605 
       
   606 /**
       
   607  * Get a list of previously defined keys.
       
   608  *
       
   609  * @since unknown
       
   610  *
       
   611  * @return unknown
       
   612  */
       
   613 function get_meta_keys() {
       
   614 	global $wpdb;
       
   615 
       
   616 	$keys = $wpdb->get_col( "
       
   617 			SELECT meta_key
       
   618 			FROM $wpdb->postmeta
       
   619 			GROUP BY meta_key
       
   620 			ORDER BY meta_key" );
       
   621 
       
   622 	return $keys;
       
   623 }
       
   624 
       
   625 /**
       
   626  * {@internal Missing Short Description}}
       
   627  *
       
   628  * @since unknown
       
   629  *
       
   630  * @param unknown_type $mid
       
   631  * @return unknown
       
   632  */
       
   633 function get_post_meta_by_id( $mid ) {
       
   634 	global $wpdb;
       
   635 	$mid = (int) $mid;
       
   636 
       
   637 	$meta = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->postmeta WHERE meta_id = %d", $mid) );
       
   638 	if ( is_serialized_string( $meta->meta_value ) )
       
   639 		$meta->meta_value = maybe_unserialize( $meta->meta_value );
       
   640 	return $meta;
       
   641 }
       
   642 
       
   643 /**
       
   644  * {@internal Missing Short Description}}
       
   645  *
       
   646  * Some postmeta stuff.
       
   647  *
       
   648  * @since unknown
       
   649  *
       
   650  * @param unknown_type $postid
       
   651  * @return unknown
       
   652  */
       
   653 function has_meta( $postid ) {
       
   654 	global $wpdb;
       
   655 
       
   656 	return $wpdb->get_results( $wpdb->prepare("SELECT meta_key, meta_value, meta_id, post_id
       
   657 			FROM $wpdb->postmeta WHERE post_id = %d
       
   658 			ORDER BY meta_key,meta_id", $postid), ARRAY_A );
       
   659 
       
   660 }
       
   661 
       
   662 /**
       
   663  * {@internal Missing Short Description}}
       
   664  *
       
   665  * @since unknown
       
   666  *
       
   667  * @param unknown_type $meta_id
       
   668  * @param unknown_type $meta_key
       
   669  * @param unknown_type $meta_value
       
   670  * @return unknown
       
   671  */
       
   672 function update_meta( $meta_id, $meta_key, $meta_value ) {
       
   673 	global $wpdb;
       
   674 
       
   675 	$protected = array( '_wp_attached_file', '_wp_attachment_metadata', '_wp_old_slug', '_wp_page_template' );
       
   676 
       
   677 	if ( in_array($meta_key, $protected) )
       
   678 		return false;
       
   679 
       
   680 	if ( '' === trim( $meta_value ) )
       
   681 		return false;
       
   682 
       
   683 	$post_id = $wpdb->get_var( $wpdb->prepare("SELECT post_id FROM $wpdb->postmeta WHERE meta_id = %d", $meta_id) );
       
   684 	wp_cache_delete($post_id, 'post_meta');
       
   685 
       
   686 	$meta_value = maybe_serialize( stripslashes( $meta_value ) );
       
   687 	$meta_id = (int) $meta_id;
       
   688 
       
   689 	$data  = compact( 'meta_key', 'meta_value' );
       
   690 	$where = compact( 'meta_id' );
       
   691 
       
   692 	return $wpdb->update( $wpdb->postmeta, $data, $where );
       
   693 }
       
   694 
       
   695 //
       
   696 // Private
       
   697 //
       
   698 
       
   699 /**
       
   700  * Replace hrefs of attachment anchors with up-to-date permalinks.
       
   701  *
       
   702  * @since unknown
       
   703  * @access private
       
   704  *
       
   705  * @param unknown_type $post_ID
       
   706  * @return unknown
       
   707  */
       
   708 function _fix_attachment_links( $post_ID ) {
       
   709 
       
   710 	$post = & get_post( $post_ID, ARRAY_A );
       
   711 
       
   712 	$search = "#<a[^>]+rel=('|\")[^'\"]*attachment[^>]*>#ie";
       
   713 
       
   714 	// See if we have any rel="attachment" links
       
   715 	if ( 0 == preg_match_all( $search, $post['post_content'], $anchor_matches, PREG_PATTERN_ORDER ) )
       
   716 		return;
       
   717 
       
   718 	$i = 0;
       
   719 	$search = "#[\s]+rel=(\"|')(.*?)wp-att-(\d+)\\1#i";
       
   720 	foreach ( $anchor_matches[0] as $anchor ) {
       
   721 		if ( 0 == preg_match( $search, $anchor, $id_matches ) )
       
   722 			continue;
       
   723 
       
   724 		$id = (int) $id_matches[3];
       
   725 
       
   726 		// While we have the attachment ID, let's adopt any orphans.
       
   727 		$attachment = & get_post( $id, ARRAY_A );
       
   728 		if ( ! empty( $attachment) && ! is_object( get_post( $attachment['post_parent'] ) ) ) {
       
   729 			$attachment['post_parent'] = $post_ID;
       
   730 			// Escape data pulled from DB.
       
   731 			$attachment = add_magic_quotes( $attachment);
       
   732 			wp_update_post( $attachment);
       
   733 		}
       
   734 
       
   735 		$post_search[$i] = $anchor;
       
   736 		$post_replace[$i] = preg_replace( "#href=(\"|')[^'\"]*\\1#e", "stripslashes( 'href=\\1' ).get_attachment_link( $id ).stripslashes( '\\1' )", $anchor );
       
   737 		++$i;
       
   738 	}
       
   739 
       
   740 	$post['post_content'] = str_replace( $post_search, $post_replace, $post['post_content'] );
       
   741 
       
   742 	// Escape data pulled from DB.
       
   743 	$post = add_magic_quotes( $post);
       
   744 
       
   745 	return wp_update_post( $post);
       
   746 }
       
   747 
       
   748 /**
       
   749  * Move child posts to a new parent.
       
   750  *
       
   751  * @since unknown
       
   752  * @access private
       
   753  *
       
   754  * @param unknown_type $old_ID
       
   755  * @param unknown_type $new_ID
       
   756  * @return unknown
       
   757  */
       
   758 function _relocate_children( $old_ID, $new_ID ) {
       
   759 	global $wpdb;
       
   760 	$old_ID = (int) $old_ID;
       
   761 	$new_ID = (int) $new_ID;
       
   762 	return $wpdb->update($wpdb->posts, array('post_parent' => $new_ID), array('post_parent' => $old_ID) );
       
   763 }
       
   764 
       
   765 /**
       
   766  * {@internal Missing Short Description}}
       
   767  *
       
   768  * @since unknown
       
   769  *
       
   770  * @param unknown_type $type
       
   771  * @return unknown
       
   772  */
       
   773 function get_available_post_statuses($type = 'post') {
       
   774 	$stati = wp_count_posts($type);
       
   775 
       
   776 	return array_keys(get_object_vars($stati));
       
   777 }
       
   778 
       
   779 /**
       
   780  * {@internal Missing Short Description}}
       
   781  *
       
   782  * @since unknown
       
   783  *
       
   784  * @param unknown_type $q
       
   785  * @return unknown
       
   786  */
       
   787 function wp_edit_posts_query( $q = false ) {
       
   788 	if ( false === $q )
       
   789 		$q = $_GET;
       
   790 	$q['m']   = isset($q['m']) ? (int) $q['m'] : 0;
       
   791 	$q['cat'] = isset($q['cat']) ? (int) $q['cat'] : 0;
       
   792 	$post_stati  = array(	//	array( adj, noun )
       
   793 				'publish' => array(_x('Published', 'post'), __('Published posts'), _n_noop('Published <span class="count">(%s)</span>', 'Published <span class="count">(%s)</span>')),
       
   794 				'future' => array(_x('Scheduled', 'post'), __('Scheduled posts'), _n_noop('Scheduled <span class="count">(%s)</span>', 'Scheduled <span class="count">(%s)</span>')),
       
   795 				'pending' => array(_x('Pending Review', 'post'), __('Pending posts'), _n_noop('Pending Review <span class="count">(%s)</span>', 'Pending Review <span class="count">(%s)</span>')),
       
   796 				'draft' => array(_x('Draft', 'post'), _x('Drafts', 'manage posts header'), _n_noop('Draft <span class="count">(%s)</span>', 'Drafts <span class="count">(%s)</span>')),
       
   797 				'private' => array(_x('Private', 'post'), __('Private posts'), _n_noop('Private <span class="count">(%s)</span>', 'Private <span class="count">(%s)</span>')),
       
   798 			);
       
   799 
       
   800 	$post_stati = apply_filters('post_stati', $post_stati);
       
   801 
       
   802 	$avail_post_stati = get_available_post_statuses('post');
       
   803 
       
   804 	$post_status_q = '';
       
   805 	if ( isset($q['post_status']) && in_array( $q['post_status'], array_keys($post_stati) ) ) {
       
   806 		$post_status_q = '&post_status=' . $q['post_status'];
       
   807 		$post_status_q .= '&perm=readable';
       
   808 	}
       
   809 
       
   810 	if ( isset($q['post_status']) && 'pending' === $q['post_status'] ) {
       
   811 		$order = 'ASC';
       
   812 		$orderby = 'modified';
       
   813 	} elseif ( isset($q['post_status']) && 'draft' === $q['post_status'] ) {
       
   814 		$order = 'DESC';
       
   815 		$orderby = 'modified';
       
   816 	} else {
       
   817 		$order = 'DESC';
       
   818 		$orderby = 'date';
       
   819 	}
       
   820 
       
   821 	$posts_per_page = get_user_option('edit_per_page');
       
   822 	if ( empty($posts_per_page) )
       
   823 		$posts_per_page = 15;
       
   824 	$posts_per_page = apply_filters('edit_posts_per_page', $posts_per_page);
       
   825 
       
   826 	wp("post_type=post&$post_status_q&posts_per_page=$posts_per_page&order=$order&orderby=$orderby");
       
   827 
       
   828 	return array($post_stati, $avail_post_stati);
       
   829 }
       
   830 
       
   831 /**
       
   832  * {@internal Missing Short Description}}
       
   833  *
       
   834  * @since unknown
       
   835  *
       
   836  * @param unknown_type $type
       
   837  * @return unknown
       
   838  */
       
   839 function get_available_post_mime_types($type = 'attachment') {
       
   840 	global $wpdb;
       
   841 
       
   842 	$types = $wpdb->get_col($wpdb->prepare("SELECT DISTINCT post_mime_type FROM $wpdb->posts WHERE post_type = %s", $type));
       
   843 	return $types;
       
   844 }
       
   845 
       
   846 /**
       
   847  * {@internal Missing Short Description}}
       
   848  *
       
   849  * @since unknown
       
   850  *
       
   851  * @param unknown_type $q
       
   852  * @return unknown
       
   853  */
       
   854 function wp_edit_attachments_query( $q = false ) {
       
   855 	if ( false === $q )
       
   856 		$q = $_GET;
       
   857 
       
   858 	$q['m']   = isset( $q['m'] ) ? (int) $q['m'] : 0;
       
   859 	$q['cat'] = isset( $q['cat'] ) ? (int) $q['cat'] : 0;
       
   860 	$q['post_type'] = 'attachment';
       
   861 	$q['post_status'] = 'any';
       
   862 	$media_per_page = get_user_option('upload_per_page');
       
   863 	if ( empty($media_per_page) )
       
   864 		$media_per_page = 20;
       
   865 	$q['posts_per_page'] = $media_per_page;
       
   866 	$post_mime_types = array(	//	array( adj, noun )
       
   867 				'image' => array(__('Images'), __('Manage Images'), _n_noop('Image <span class="count">(%s)</span>', 'Images <span class="count">(%s)</span>')),
       
   868 				'audio' => array(__('Audio'), __('Manage Audio'), _n_noop('Audio <span class="count">(%s)</span>', 'Audio <span class="count">(%s)</span>')),
       
   869 				'video' => array(__('Video'), __('Manage Video'), _n_noop('Video <span class="count">(%s)</span>', 'Video <span class="count">(%s)</span>')),
       
   870 			);
       
   871 	$post_mime_types = apply_filters('post_mime_types', $post_mime_types);
       
   872 
       
   873 	$avail_post_mime_types = get_available_post_mime_types('attachment');
       
   874 
       
   875 	if ( isset($q['post_mime_type']) && !array_intersect( (array) $q['post_mime_type'], array_keys($post_mime_types) ) )
       
   876 		unset($q['post_mime_type']);
       
   877 
       
   878 	wp($q);
       
   879 
       
   880 	return array($post_mime_types, $avail_post_mime_types);
       
   881 }
       
   882 
       
   883 /**
       
   884  * {@internal Missing Short Description}}
       
   885  *
       
   886  * @since unknown
       
   887  *
       
   888  * @param unknown_type $id
       
   889  * @param unknown_type $page
       
   890  * @return unknown
       
   891  */
       
   892 function postbox_classes( $id, $page ) {
       
   893 	if ( isset( $_GET['edit'] ) && $_GET['edit'] == $id )
       
   894 		return '';
       
   895 	$current_user = wp_get_current_user();
       
   896 	if ( $closed = get_user_option('closedpostboxes_'.$page, 0, false ) ) {
       
   897 		if ( !is_array( $closed ) ) return '';
       
   898 		return in_array( $id, $closed )? 'closed' : '';
       
   899 	} else {
       
   900 		return '';
       
   901 	}
       
   902 }
       
   903 
       
   904 /**
       
   905  * {@internal Missing Short Description}}
       
   906  *
       
   907  * @since unknown
       
   908  *
       
   909  * @param unknown_type $id
       
   910  * @param unknown_type $title
       
   911  * @param unknown_type $name
       
   912  * @return unknown
       
   913  */
       
   914 function get_sample_permalink($id, $title=null, $name = null) {
       
   915 	$post = &get_post($id);
       
   916 	if (!$post->ID) {
       
   917 		return array('', '');
       
   918 	}
       
   919 	$original_status = $post->post_status;
       
   920 	$original_date = $post->post_date;
       
   921 	$original_name = $post->post_name;
       
   922 
       
   923 	// Hack: get_permalink would return ugly permalink for
       
   924 	// drafts, so we will fake, that our post is published
       
   925 	if (in_array($post->post_status, array('draft', 'pending'))) {
       
   926 		$post->post_status = 'publish';
       
   927 		$post->post_name = sanitize_title($post->post_name? $post->post_name : $post->post_title, $post->ID);
       
   928 	}
       
   929 
       
   930 	$post->post_name = wp_unique_post_slug($post->post_name, $post->ID, $post->post_status, $post->post_type, $post->post_parent);
       
   931 
       
   932 	// If the user wants to set a new name -- override the current one
       
   933 	// Note: if empty name is supplied -- use the title instead, see #6072
       
   934 	if (!is_null($name)) {
       
   935 		$post->post_name = sanitize_title($name? $name : $title, $post->ID);
       
   936 	}
       
   937 
       
   938 	$post->filter = 'sample';
       
   939 
       
   940 	$permalink = get_permalink($post, true);
       
   941 
       
   942 	// Handle page hierarchy
       
   943 	if ( 'page' == $post->post_type ) {
       
   944 		$uri = get_page_uri($post->ID);
       
   945 		$uri = untrailingslashit($uri);
       
   946 		$uri = strrev( stristr( strrev( $uri ), '/' ) );
       
   947 		$uri = untrailingslashit($uri);
       
   948 		if ( !empty($uri) )
       
   949 			$uri .='/';
       
   950 		$permalink = str_replace('%pagename%', "${uri}%pagename%", $permalink);
       
   951 	}
       
   952 
       
   953 	$permalink = array($permalink, apply_filters('editable_slug', $post->post_name));
       
   954 	$post->post_status = $original_status;
       
   955 	$post->post_date = $original_date;
       
   956 	$post->post_name = $original_name;
       
   957 	unset($post->filter);
       
   958 
       
   959 	return $permalink;
       
   960 }
       
   961 
       
   962 /**
       
   963  * {@internal Missing Short Description}}
       
   964  *
       
   965  * @since unknown
       
   966  *
       
   967  * @param unknown_type $id
       
   968  * @param unknown_type $new_title
       
   969  * @param unknown_type $new_slug
       
   970  * @return unknown
       
   971  */
       
   972 function get_sample_permalink_html( $id, $new_title = null, $new_slug = null ) {
       
   973 	$post = &get_post($id);
       
   974 	list($permalink, $post_name) = get_sample_permalink($post->ID, $new_title, $new_slug);
       
   975 	if ( 'publish' == $post->post_status )
       
   976 		$view_post = 'post' == $post->post_type ? __('View Post') : __('View Page');
       
   977 
       
   978 	if ( false === strpos($permalink, '%postname%') && false === strpos($permalink, '%pagename%') ) {
       
   979 		$return = '<strong>' . __('Permalink:') . "</strong>\n" . '<span id="sample-permalink">' . $permalink . "</span>\n";
       
   980 		if ( current_user_can( 'manage_options' ) )
       
   981 			$return .= '<span id="change-permalinks"><a href="options-permalink.php" class="button" target="_blank">' . __('Change Permalinks') . "</a></span>\n";
       
   982 		if ( isset($view_post) )
       
   983 			$return .= "<span id='view-post-btn'><a href='$permalink' class='button' target='_blank'>$view_post</a></span>\n";
       
   984 
       
   985 		return $return;
       
   986 	}
       
   987 
       
   988 	$title = __('Click to edit this part of the permalink');
       
   989 	if (function_exists('mb_strlen')) {
       
   990 		if (mb_strlen($post_name) > 30) {
       
   991 			$post_name_abridged = mb_substr($post_name, 0, 14). '&hellip;' . mb_substr($post_name, -14);
       
   992 		} else {
       
   993 			$post_name_abridged = $post_name;
       
   994 		}
       
   995 	} else {
       
   996 		if (strlen($post_name) > 30) {
       
   997 			$post_name_abridged = substr($post_name, 0, 14). '&hellip;' . substr($post_name, -14);
       
   998 		} else {
       
   999 			$post_name_abridged = $post_name;
       
  1000 		}
       
  1001 	}
       
  1002 
       
  1003 	$post_name_html = '<span id="editable-post-name" title="' . $title . '">' . $post_name_abridged . '</span>';
       
  1004 	$display_link = str_replace(array('%pagename%','%postname%'), $post_name_html, $permalink);
       
  1005 	$view_link = str_replace(array('%pagename%','%postname%'), $post_name, $permalink);
       
  1006 	$return = '<strong>' . __('Permalink:') . "</strong>\n" . '<span id="sample-permalink">' . $display_link . "</span>\n";
       
  1007 	$return .= '<span id="edit-slug-buttons"><a href="#post_name" class="edit-slug button hide-if-no-js" onclick="edit_permalink(' . $id . '); return false;">' . __('Edit') . "</a></span>\n";
       
  1008 	$return .= '<span id="editable-post-name-full">' . $post_name . "</span>\n";
       
  1009 	if ( isset($view_post) )
       
  1010 		$return .= "<span id='view-post-btn'><a href='$view_link' class='button' target='_blank'>$view_post</a></span>\n";
       
  1011 
       
  1012 	return $return;
       
  1013 }
       
  1014 
       
  1015 /**
       
  1016  * {@internal Missing Short Description}}
       
  1017  *
       
  1018  * @since unknown
       
  1019  *
       
  1020  * @param unknown_type $post_id
       
  1021  * @return bool|int False: not locked or locked by current user. Int: user ID of user with lock.
       
  1022  */
       
  1023 function wp_check_post_lock( $post_id ) {
       
  1024 	global $current_user;
       
  1025 
       
  1026 	if ( !$post = get_post( $post_id ) )
       
  1027 		return false;
       
  1028 
       
  1029 	$lock = get_post_meta( $post->ID, '_edit_lock', true );
       
  1030 	$last = get_post_meta( $post->ID, '_edit_last', true );
       
  1031 
       
  1032 	$time_window = apply_filters( 'wp_check_post_lock_window', AUTOSAVE_INTERVAL * 2 );
       
  1033 
       
  1034 	if ( $lock && $lock > time() - $time_window && $last != $current_user->ID )
       
  1035 		return $last;
       
  1036 	return false;
       
  1037 }
       
  1038 
       
  1039 /**
       
  1040  * {@internal Missing Short Description}}
       
  1041  *
       
  1042  * @since unknown
       
  1043  *
       
  1044  * @param unknown_type $post_id
       
  1045  * @return unknown
       
  1046  */
       
  1047 function wp_set_post_lock( $post_id ) {
       
  1048 	global $current_user;
       
  1049 	if ( !$post = get_post( $post_id ) )
       
  1050 		return false;
       
  1051 	if ( !$current_user || !$current_user->ID )
       
  1052 		return false;
       
  1053 
       
  1054 	$now = time();
       
  1055 
       
  1056 	if ( !add_post_meta( $post->ID, '_edit_lock', $now, true ) )
       
  1057 		update_post_meta( $post->ID, '_edit_lock', $now );
       
  1058 	if ( !add_post_meta( $post->ID, '_edit_last', $current_user->ID, true ) )
       
  1059 		update_post_meta( $post->ID, '_edit_last', $current_user->ID );
       
  1060 }
       
  1061 
       
  1062 /**
       
  1063  * Outputs the notice message to say that someone else is editing this post at the moment.
       
  1064  * 
       
  1065  * @since 2.8.5
       
  1066  * @return none
       
  1067  */
       
  1068 function _admin_notice_post_locked() {
       
  1069 	global $post;
       
  1070 	$last_user = get_userdata( get_post_meta( $post->ID, '_edit_last', true ) );
       
  1071 	$last_user_name = $last_user ? $last_user->display_name : __('Somebody');
       
  1072 	
       
  1073 	switch ($post->post_type) {
       
  1074 		case 'post':
       
  1075 			$message = __( 'Warning: %s is currently editing this post' );
       
  1076 			break;
       
  1077 		case 'page':
       
  1078 			$message = __( 'Warning: %s is currently editing this page' );
       
  1079 			break;
       
  1080 		default:
       
  1081 			$message = __( 'Warning: %s is currently editing this.' );
       
  1082 	}
       
  1083 	
       
  1084 	$message = sprintf( $message, esc_html( $last_user_name ) );
       
  1085 	echo "<div class='error'><p>$message</p></div>";	
       
  1086 }
       
  1087 
       
  1088 /**
       
  1089  * Creates autosave data for the specified post from $_POST data.
       
  1090  *
       
  1091  * @package WordPress
       
  1092  * @subpackage Post_Revisions
       
  1093  * @since 2.6.0
       
  1094  *
       
  1095  * @uses _wp_translate_postdata()
       
  1096  * @uses _wp_post_revision_fields()
       
  1097  */
       
  1098 function wp_create_post_autosave( $post_id ) {
       
  1099 	$translated = _wp_translate_postdata( true );
       
  1100 	if ( is_wp_error( $translated ) )
       
  1101 		return $translated;
       
  1102 
       
  1103 	// Only store one autosave.  If there is already an autosave, overwrite it.
       
  1104 	if ( $old_autosave = wp_get_post_autosave( $post_id ) ) {
       
  1105 		$new_autosave = _wp_post_revision_fields( $_POST, true );
       
  1106 		$new_autosave['ID'] = $old_autosave->ID;
       
  1107 		return wp_update_post( $new_autosave );
       
  1108 	}
       
  1109 
       
  1110 	// _wp_put_post_revision() expects unescaped.
       
  1111 	$_POST = stripslashes_deep($_POST);
       
  1112 
       
  1113 	// Otherwise create the new autosave as a special post revision
       
  1114 	return _wp_put_post_revision( $_POST, true );
       
  1115 }
       
  1116 
       
  1117 /**
       
  1118  * Save draft or manually autosave for showing preview.
       
  1119  *
       
  1120  * @package WordPress
       
  1121  * @since 2.7
       
  1122  *
       
  1123  * @uses wp_write_post()
       
  1124  * @uses edit_post()
       
  1125  * @uses get_post()
       
  1126  * @uses current_user_can()
       
  1127  * @uses wp_create_post_autosave()
       
  1128  *
       
  1129  * @return str URL to redirect to show the preview
       
  1130  */
       
  1131 function post_preview() {
       
  1132 
       
  1133 	$post_ID = (int) $_POST['post_ID'];
       
  1134 	if ( $post_ID < 1 )
       
  1135 		wp_die( __('Preview not available. Please save as a draft first.') );
       
  1136 
       
  1137 	if ( isset($_POST['catslist']) )
       
  1138 		$_POST['post_category'] = explode(",", $_POST['catslist']);
       
  1139 
       
  1140 	if ( isset($_POST['tags_input']) )
       
  1141 		$_POST['tags_input'] = explode(",", $_POST['tags_input']);
       
  1142 
       
  1143 	if ( $_POST['post_type'] == 'page' || empty($_POST['post_category']) )
       
  1144 		unset($_POST['post_category']);
       
  1145 
       
  1146 	$_POST['ID'] = $post_ID;
       
  1147 	$post = get_post($post_ID);
       
  1148 
       
  1149 	if ( 'page' == $post->post_type ) {
       
  1150 		if ( !current_user_can('edit_page', $post_ID) )
       
  1151 			wp_die(__('You are not allowed to edit this page.'));
       
  1152 	} else {
       
  1153 		if ( !current_user_can('edit_post', $post_ID) )
       
  1154 			wp_die(__('You are not allowed to edit this post.'));
       
  1155 	}
       
  1156 
       
  1157 	if ( 'draft' == $post->post_status ) {
       
  1158 		$id = edit_post();
       
  1159 	} else { // Non drafts are not overwritten.  The autosave is stored in a special post revision.
       
  1160 		$id = wp_create_post_autosave( $post->ID );
       
  1161 		if ( ! is_wp_error($id) )
       
  1162 			$id = $post->ID;
       
  1163 	}
       
  1164 
       
  1165 	if ( is_wp_error($id) )
       
  1166 		wp_die( $id->get_error_message() );
       
  1167 
       
  1168 	if ( $_POST['post_status'] == 'draft'  ) {
       
  1169 		$url = add_query_arg( 'preview', 'true', get_permalink($id) );
       
  1170 	} else {
       
  1171 		$nonce = wp_create_nonce('post_preview_' . $id);
       
  1172 		$url = add_query_arg( array( 'preview' => 'true', 'preview_id' => $id, 'preview_nonce' => $nonce ), get_permalink($id) );
       
  1173 	}
       
  1174 
       
  1175 	return $url;
       
  1176 }
       
  1177 
       
  1178 /**
       
  1179  * Adds the TinyMCE editor used on the Write and Edit screens.
       
  1180  *
       
  1181  * @package WordPress
       
  1182  * @since 2.7
       
  1183  *
       
  1184  * TinyMCE is loaded separately from other Javascript by using wp-tinymce.php. It outputs concatenated
       
  1185  * and optionaly pre-compressed version of the core and all default plugins. Additional plugins are loaded
       
  1186  * directly by TinyMCE using non-blocking method. Custom plugins can be refreshed by adding a query string
       
  1187  * to the URL when queueing them with the mce_external_plugins filter.
       
  1188  *
       
  1189  * @param bool $teeny optional Output a trimmed down version used in Press This.
       
  1190  */
       
  1191 function wp_tiny_mce( $teeny = false ) {
       
  1192 	global $concatenate_scripts, $compress_scripts, $tinymce_version;
       
  1193 
       
  1194 	if ( ! user_can_richedit() )
       
  1195 		return;
       
  1196 
       
  1197 	$baseurl = includes_url('js/tinymce');
       
  1198 
       
  1199 	$mce_locale = ( '' == get_locale() ) ? 'en' : strtolower( substr(get_locale(), 0, 2) ); // only ISO 639-1
       
  1200 
       
  1201 	/*
       
  1202 	The following filter allows localization scripts to change the languages displayed in the spellchecker's drop-down menu.
       
  1203 	By default it uses Google's spellchecker API, but can be configured to use PSpell/ASpell if installed on the server.
       
  1204 	The + sign marks the default language. More information:
       
  1205 	http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/spellchecker
       
  1206 	*/
       
  1207 	$mce_spellchecker_languages = apply_filters('mce_spellchecker_languages', '+English=en,Danish=da,Dutch=nl,Finnish=fi,French=fr,German=de,Italian=it,Polish=pl,Portuguese=pt,Spanish=es,Swedish=sv');
       
  1208 
       
  1209 	if ( $teeny ) {
       
  1210 		$plugins = apply_filters( 'teeny_mce_plugins', array('safari', 'inlinepopups', 'media', 'autosave', 'fullscreen') );
       
  1211 		$ext_plugins = '';
       
  1212 	} else {
       
  1213 		$plugins = array( 'safari', 'inlinepopups', 'spellchecker', 'paste', 'wordpress', 'media', 'fullscreen', 'wpeditimage', 'wpgallery', 'tabfocus' );
       
  1214 
       
  1215 		/*
       
  1216 		The following filter takes an associative array of external plugins for TinyMCE in the form 'plugin_name' => 'url'.
       
  1217 		It adds the plugin's name to TinyMCE's plugins init and the call to PluginManager to load the plugin.
       
  1218 		The url should be absolute and should include the js file name to be loaded. Example:
       
  1219 		array( 'myplugin' => 'http://my-site.com/wp-content/plugins/myfolder/mce_plugin.js' )
       
  1220 		If the plugin uses a button, it should be added with one of the "$mce_buttons" filters.
       
  1221 		*/
       
  1222 		$mce_external_plugins = apply_filters('mce_external_plugins', array());
       
  1223 
       
  1224 		$ext_plugins = '';
       
  1225 		if ( ! empty($mce_external_plugins) ) {
       
  1226 
       
  1227 			/*
       
  1228 			The following filter loads external language files for TinyMCE plugins.
       
  1229 			It takes an associative array 'plugin_name' => 'path', where path is the
       
  1230 			include path to the file. The language file should follow the same format as
       
  1231 			/tinymce/langs/wp-langs.php and should define a variable $strings that
       
  1232 			holds all translated strings.
       
  1233 			When this filter is not used, the function will try to load {mce_locale}.js.
       
  1234 			If that is not found, en.js will be tried next.
       
  1235 			*/
       
  1236 			$mce_external_languages = apply_filters('mce_external_languages', array());
       
  1237 
       
  1238 			$loaded_langs = array();
       
  1239 			$strings = '';
       
  1240 
       
  1241 			if ( ! empty($mce_external_languages) ) {
       
  1242 				foreach ( $mce_external_languages as $name => $path ) {
       
  1243 					if ( @is_file($path) && @is_readable($path) ) {
       
  1244 						include_once($path);
       
  1245 						$ext_plugins .= $strings . "\n";
       
  1246 						$loaded_langs[] = $name;
       
  1247 					}
       
  1248 				}
       
  1249 			}
       
  1250 
       
  1251 			foreach ( $mce_external_plugins as $name => $url ) {
       
  1252 
       
  1253 				if ( is_ssl() ) $url = str_replace('http://', 'https://', $url);
       
  1254 
       
  1255 				$plugins[] = '-' . $name;
       
  1256 
       
  1257 				$plugurl = dirname($url);
       
  1258 				$strings = $str1 = $str2 = '';
       
  1259 				if ( ! in_array($name, $loaded_langs) ) {
       
  1260 					$path = str_replace( WP_PLUGIN_URL, '', $plugurl );
       
  1261 					$path = WP_PLUGIN_DIR . $path . '/langs/';
       
  1262 
       
  1263 					if ( function_exists('realpath') )
       
  1264 						$path = trailingslashit( realpath($path) );
       
  1265 
       
  1266 					if ( @is_file($path . $mce_locale . '.js') )
       
  1267 						$strings .= @file_get_contents($path . $mce_locale . '.js') . "\n";
       
  1268 
       
  1269 					if ( @is_file($path . $mce_locale . '_dlg.js') )
       
  1270 						$strings .= @file_get_contents($path . $mce_locale . '_dlg.js') . "\n";
       
  1271 
       
  1272 					if ( 'en' != $mce_locale && empty($strings) ) {
       
  1273 						if ( @is_file($path . 'en.js') ) {
       
  1274 							$str1 = @file_get_contents($path . 'en.js');
       
  1275 							$strings .= preg_replace( '/([\'"])en\./', '$1' . $mce_locale . '.', $str1, 1 ) . "\n";
       
  1276 						}
       
  1277 
       
  1278 						if ( @is_file($path . 'en_dlg.js') ) {
       
  1279 							$str2 = @file_get_contents($path . 'en_dlg.js');
       
  1280 							$strings .= preg_replace( '/([\'"])en\./', '$1' . $mce_locale . '.', $str2, 1 ) . "\n";
       
  1281 						}
       
  1282 					}
       
  1283 
       
  1284 					if ( ! empty($strings) )
       
  1285 						$ext_plugins .= "\n" . $strings . "\n";
       
  1286 				}
       
  1287 
       
  1288 				$ext_plugins .= 'tinyMCEPreInit.load_ext("' . $plugurl . '", "' . $mce_locale . '");' . "\n";
       
  1289 				$ext_plugins .= 'tinymce.PluginManager.load("' . $name . '", "' . $url . '");' . "\n";
       
  1290 			}
       
  1291 		}
       
  1292 	}
       
  1293 
       
  1294 	$plugins = implode($plugins, ',');
       
  1295 
       
  1296 	if ( $teeny ) {
       
  1297 		$mce_buttons = apply_filters( 'teeny_mce_buttons', array('bold, italic, underline, blockquote, separator, strikethrough, bullist, numlist,justifyleft, justifycenter, justifyright, undo, redo, link, unlink, fullscreen') );
       
  1298 		$mce_buttons = implode($mce_buttons, ',');
       
  1299 		$mce_buttons_2 = $mce_buttons_3 = $mce_buttons_4 = '';
       
  1300 	} else {
       
  1301 		$mce_buttons = apply_filters('mce_buttons', array('bold', 'italic', 'strikethrough', '|', 'bullist', 'numlist', 'blockquote', '|', 'justifyleft', 'justifycenter', 'justifyright', '|', 'link', 'unlink', 'wp_more', '|', 'spellchecker', 'fullscreen', 'wp_adv' ));
       
  1302 		$mce_buttons = implode($mce_buttons, ',');
       
  1303 
       
  1304 		$mce_buttons_2 = apply_filters('mce_buttons_2', array('formatselect', 'underline', 'justifyfull', 'forecolor', '|', 'pastetext', 'pasteword', 'removeformat', '|', 'media', 'charmap', '|', 'outdent', 'indent', '|', 'undo', 'redo', 'wp_help' ));
       
  1305 		$mce_buttons_2 = implode($mce_buttons_2, ',');
       
  1306 
       
  1307 		$mce_buttons_3 = apply_filters('mce_buttons_3', array());
       
  1308 		$mce_buttons_3 = implode($mce_buttons_3, ',');
       
  1309 
       
  1310 		$mce_buttons_4 = apply_filters('mce_buttons_4', array());
       
  1311 		$mce_buttons_4 = implode($mce_buttons_4, ',');
       
  1312 	}
       
  1313 	$no_captions = ( apply_filters( 'disable_captions', '' ) ) ? true : false;
       
  1314 
       
  1315 	// TinyMCE init settings
       
  1316 	$initArray = array (
       
  1317 		'mode' => 'specific_textareas',
       
  1318 		'editor_selector' => 'theEditor',
       
  1319 		'width' => '100%',
       
  1320 		'theme' => 'advanced',
       
  1321 		'skin' => 'wp_theme',
       
  1322 		'theme_advanced_buttons1' => "$mce_buttons",
       
  1323 		'theme_advanced_buttons2' => "$mce_buttons_2",
       
  1324 		'theme_advanced_buttons3' => "$mce_buttons_3",
       
  1325 		'theme_advanced_buttons4' => "$mce_buttons_4",
       
  1326 		'language' => "$mce_locale",
       
  1327 		'spellchecker_languages' => "$mce_spellchecker_languages",
       
  1328 		'theme_advanced_toolbar_location' => 'top',
       
  1329 		'theme_advanced_toolbar_align' => 'left',
       
  1330 		'theme_advanced_statusbar_location' => 'bottom',
       
  1331 		'theme_advanced_resizing' => true,
       
  1332 		'theme_advanced_resize_horizontal' => false,
       
  1333 		'dialog_type' => 'modal',
       
  1334 		'relative_urls' => false,
       
  1335 		'remove_script_host' => false,
       
  1336 		'convert_urls' => false,
       
  1337 		'apply_source_formatting' => false,
       
  1338 		'remove_linebreaks' => true,
       
  1339 		'gecko_spellcheck' => true,
       
  1340 		'entities' => '38,amp,60,lt,62,gt',
       
  1341 		'accessibility_focus' => true,
       
  1342 		'tabfocus_elements' => 'major-publishing-actions',
       
  1343 		'media_strict' => false,
       
  1344 		'save_callback' => 'switchEditors.saveCallback',
       
  1345 		'wpeditimage_disable_captions' => $no_captions,
       
  1346 		'plugins' => "$plugins"
       
  1347 	);
       
  1348 
       
  1349 	$mce_css = trim(apply_filters('mce_css', ''), ' ,');
       
  1350 
       
  1351 	if ( ! empty($mce_css) )
       
  1352 		$initArray['content_css'] = "$mce_css";
       
  1353 
       
  1354 	// For people who really REALLY know what they're doing with TinyMCE
       
  1355 	// You can modify initArray to add, remove, change elements of the config before tinyMCE.init
       
  1356 	// Setting "valid_elements", "invalid_elements" and "extended_valid_elements" can be done through "tiny_mce_before_init".
       
  1357 	// Best is to use the default cleanup by not specifying valid_elements, as TinyMCE contains full set of XHTML 1.0.
       
  1358 	if ( $teeny ) {
       
  1359 		$initArray = apply_filters('teeny_mce_before_init', $initArray);
       
  1360 	} else {
       
  1361 		$initArray = apply_filters('tiny_mce_before_init', $initArray);
       
  1362 	}
       
  1363 
       
  1364 	if ( empty($initArray['theme_advanced_buttons3']) && !empty($initArray['theme_advanced_buttons4']) ) {
       
  1365 		$initArray['theme_advanced_buttons3'] = $initArray['theme_advanced_buttons4'];
       
  1366 		$initArray['theme_advanced_buttons4'] = '';
       
  1367 	}
       
  1368 
       
  1369 	if ( ! isset($concatenate_scripts) )
       
  1370 		script_concat_settings();
       
  1371 
       
  1372 	$language = $initArray['language'];
       
  1373 	$zip = $compress_scripts ? 1 : 0;
       
  1374 
       
  1375 	/**
       
  1376 	 * Deprecated
       
  1377 	 *
       
  1378 	 * The tiny_mce_version filter is not needed since external plugins are loaded directly by TinyMCE.
       
  1379 	 * These plugins can be refreshed by appending query string to the URL passed to mce_external_plugins filter.
       
  1380 	 * If the plugin has a popup dialog, a query string can be added to the button action that opens it (in the plugin's code).
       
  1381 	 */
       
  1382 	$version = apply_filters('tiny_mce_version', '');
       
  1383 	$version = 'ver=' . $tinymce_version . $version;
       
  1384 
       
  1385 	if ( 'en' != $language )
       
  1386 		include_once(ABSPATH . WPINC . '/js/tinymce/langs/wp-langs.php');
       
  1387 
       
  1388 	$mce_options = '';
       
  1389 	foreach ( $initArray as $k => $v )
       
  1390 	    $mce_options .= $k . ':"' . $v . '", ';
       
  1391 
       
  1392 	$mce_options = rtrim( trim($mce_options), '\n\r,' ); ?>
       
  1393 
       
  1394 <script type="text/javascript">
       
  1395 /* <![CDATA[ */
       
  1396 tinyMCEPreInit = {
       
  1397 	base : "<?php echo $baseurl; ?>",
       
  1398 	suffix : "",
       
  1399 	query : "<?php echo $version; ?>",
       
  1400 	mceInit : {<?php echo $mce_options; ?>},
       
  1401 	load_ext : function(url,lang){var sl=tinymce.ScriptLoader;sl.markDone(url+'/langs/'+lang+'.js');sl.markDone(url+'/langs/'+lang+'_dlg.js');}
       
  1402 };
       
  1403 /* ]]> */
       
  1404 </script>
       
  1405 
       
  1406 <?php
       
  1407 	if ( $concatenate_scripts )
       
  1408 		echo "<script type='text/javascript' src='$baseurl/wp-tinymce.php?c=$zip&amp;$version'></script>\n";
       
  1409 	else
       
  1410 		echo "<script type='text/javascript' src='$baseurl/tiny_mce.js?$version'></script>\n";
       
  1411 
       
  1412 	if ( 'en' != $language && isset($lang) )
       
  1413 		echo "<script type='text/javascript'>\n$lang\n</script>\n";
       
  1414 	else
       
  1415 		echo "<script type='text/javascript' src='$baseurl/langs/wp-langs-en.js?$version'></script>\n";
       
  1416 ?>
       
  1417 
       
  1418 <script type="text/javascript">
       
  1419 /* <![CDATA[ */
       
  1420 <?php if ( $ext_plugins ) echo "$ext_plugins\n"; ?>
       
  1421 <?php if ( $concatenate_scripts ) { ?>
       
  1422 tinyMCEPreInit.go();
       
  1423 <?php } else { ?>
       
  1424 (function(){var t=tinyMCEPreInit,sl=tinymce.ScriptLoader,ln=t.mceInit.language,th=t.mceInit.theme,pl=t.mceInit.plugins;sl.markDone(t.base+'/langs/'+ln+'.js');sl.markDone(t.base+'/themes/'+th+'/langs/'+ln+'.js');sl.markDone(t.base+'/themes/'+th+'/langs/'+ln+'_dlg.js');tinymce.each(pl.split(','),function(n){if(n&&n.charAt(0)!='-'){sl.markDone(t.base+'/plugins/'+n+'/langs/'+ln+'.js');sl.markDone(t.base+'/plugins/'+n+'/langs/'+ln+'_dlg.js');}});})();
       
  1425 <?php } ?>
       
  1426 tinyMCE.init(tinyMCEPreInit.mceInit);
       
  1427 /* ]]> */
       
  1428 </script>
       
  1429 <?php
       
  1430 }