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