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