[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

/wp-admin/includes/ -> ajax-actions.php (source)

   1  <?php
   2  /**
   3   * WordPress Core Ajax Handlers.
   4   *
   5   * @package WordPress
   6   * @subpackage Administration
   7   */
   8  
   9  /*
  10   * No-privilege Ajax handlers.
  11   */
  12  function wp_ajax_nopriv_heartbeat() {
  13      $response = array();
  14  
  15      // screen_id is the same as $current_screen->id and the JS global 'pagenow'
  16      if ( ! empty($_POST['screenid']) )
  17          $screen_id = sanitize_key($_POST['screenid']);
  18      else
  19          $screen_id = 'site';
  20  
  21      if ( ! empty($_POST['data']) ) {
  22          $data = wp_unslash( (array) $_POST['data'] );
  23          $response = apply_filters( 'heartbeat_nopriv_received', $response, $data, $screen_id );
  24      }
  25  
  26      $response = apply_filters( 'heartbeat_nopriv_send', $response, $screen_id );
  27  
  28      // Allow the transport to be replaced with long-polling easily
  29      do_action( 'heartbeat_nopriv_tick', $response, $screen_id );
  30  
  31      // send the current time according to the server
  32      $response['servertime'] = time();
  33  
  34      wp_send_json($response);
  35  }
  36  
  37  /*
  38   * GET-based Ajax handlers.
  39   */
  40  function wp_ajax_fetch_list() {
  41      global $wp_list_table;
  42  
  43      $list_class = $_GET['list_args']['class'];
  44      check_ajax_referer( "fetch-list-$list_class", '_ajax_fetch_list_nonce' );
  45  
  46      $wp_list_table = _get_list_table( $list_class, array( 'screen' => $_GET['list_args']['screen']['id'] ) );
  47      if ( ! $wp_list_table )
  48          wp_die( 0 );
  49  
  50      if ( ! $wp_list_table->ajax_user_can() )
  51          wp_die( -1 );
  52  
  53      $wp_list_table->ajax_response();
  54  
  55      wp_die( 0 );
  56  }
  57  function wp_ajax_ajax_tag_search() {
  58      global $wpdb;
  59  
  60      if ( isset( $_GET['tax'] ) ) {
  61          $taxonomy = sanitize_key( $_GET['tax'] );
  62          $tax = get_taxonomy( $taxonomy );
  63          if ( ! $tax )
  64              wp_die( 0 );
  65          if ( ! current_user_can( $tax->cap->assign_terms ) )
  66              wp_die( -1 );
  67      } else {
  68          wp_die( 0 );
  69      }
  70  
  71      $s = wp_unslash( $_GET['q'] );
  72  
  73      $comma = _x( ',', 'tag delimiter' );
  74      if ( ',' !== $comma )
  75          $s = str_replace( $comma, ',', $s );
  76      if ( false !== strpos( $s, ',' ) ) {
  77          $s = explode( ',', $s );
  78          $s = $s[count( $s ) - 1];
  79      }
  80      $s = trim( $s );
  81      if ( strlen( $s ) < 2 )
  82          wp_die(); // require 2 chars for matching
  83  
  84      $results = $wpdb->get_col( $wpdb->prepare( "SELECT t.name FROM $wpdb->term_taxonomy AS tt INNER JOIN $wpdb->terms AS t ON tt.term_id = t.term_id WHERE tt.taxonomy = %s AND t.name LIKE (%s)", $taxonomy, '%' . like_escape( $s ) . '%' ) );
  85  
  86      echo join( $results, "\n" );
  87      wp_die();
  88  }
  89  
  90  function wp_ajax_wp_compression_test() {
  91      if ( !current_user_can( 'manage_options' ) )
  92          wp_die( -1 );
  93  
  94      if ( ini_get('zlib.output_compression') || 'ob_gzhandler' == ini_get('output_handler') ) {
  95          update_site_option('can_compress_scripts', 0);
  96          wp_die( 0 );
  97      }
  98  
  99      if ( isset($_GET['test']) ) {
 100          header( 'Expires: Wed, 11 Jan 1984 05:00:00 GMT' );
 101          header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s' ) . ' GMT' );
 102          header( 'Cache-Control: no-cache, must-revalidate, max-age=0' );
 103          header( 'Pragma: no-cache' );
 104          header('Content-Type: application/x-javascript; charset=UTF-8');
 105          $force_gzip = ( defined('ENFORCE_GZIP') && ENFORCE_GZIP );
 106          $test_str = '"wpCompressionTest Lorem ipsum dolor sit amet consectetuer mollis sapien urna ut a. Eu nonummy condimentum fringilla tempor pretium platea vel nibh netus Maecenas. Hac molestie amet justo quis pellentesque est ultrices interdum nibh Morbi. Cras mattis pretium Phasellus ante ipsum ipsum ut sociis Suspendisse Lorem. Ante et non molestie. Porta urna Vestibulum egestas id congue nibh eu risus gravida sit. Ac augue auctor Ut et non a elit massa id sodales. Elit eu Nulla at nibh adipiscing mattis lacus mauris at tempus. Netus nibh quis suscipit nec feugiat eget sed lorem et urna. Pellentesque lacus at ut massa consectetuer ligula ut auctor semper Pellentesque. Ut metus massa nibh quam Curabitur molestie nec mauris congue. Volutpat molestie elit justo facilisis neque ac risus Ut nascetur tristique. Vitae sit lorem tellus et quis Phasellus lacus tincidunt nunc Fusce. Pharetra wisi Suspendisse mus sagittis libero lacinia Integer consequat ac Phasellus. Et urna ac cursus tortor aliquam Aliquam amet tellus volutpat Vestibulum. Justo interdum condimentum In augue congue tellus sollicitudin Quisque quis nibh."';
 107  
 108           if ( 1 == $_GET['test'] ) {
 109               echo $test_str;
 110               wp_die();
 111           } elseif ( 2 == $_GET['test'] ) {
 112              if ( !isset($_SERVER['HTTP_ACCEPT_ENCODING']) )
 113                  wp_die( -1 );
 114              if ( false !== stripos( $_SERVER['HTTP_ACCEPT_ENCODING'], 'deflate') && function_exists('gzdeflate') && ! $force_gzip ) {
 115                  header('Content-Encoding: deflate');
 116                  $out = gzdeflate( $test_str, 1 );
 117              } elseif ( false !== stripos( $_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') && function_exists('gzencode') ) {
 118                  header('Content-Encoding: gzip');
 119                  $out = gzencode( $test_str, 1 );
 120              } else {
 121                  wp_die( -1 );
 122              }
 123              echo $out;
 124              wp_die();
 125          } elseif ( 'no' == $_GET['test'] ) {
 126              update_site_option('can_compress_scripts', 0);
 127          } elseif ( 'yes' == $_GET['test'] ) {
 128              update_site_option('can_compress_scripts', 1);
 129          }
 130      }
 131  
 132      wp_die( 0 );
 133  }
 134  
 135  function wp_ajax_imgedit_preview() {
 136      $post_id = intval($_GET['postid']);
 137      if ( empty($post_id) || !current_user_can('edit_post', $post_id) )
 138          wp_die( -1 );
 139  
 140      check_ajax_referer( "image_editor-$post_id" );
 141  
 142      include_once ( ABSPATH . 'wp-admin/includes/image-edit.php' );
 143      if ( ! stream_preview_image($post_id) )
 144          wp_die( -1 );
 145  
 146      wp_die();
 147  }
 148  
 149  function wp_ajax_oembed_cache() {
 150      global $wp_embed;
 151  
 152      $return = ( $wp_embed->cache_oembed( $_GET['post'] ) ) ? '1' : '0';
 153      wp_die( $return );
 154  }
 155  
 156  function wp_ajax_autocomplete_user() {
 157      if ( ! is_multisite() || ! current_user_can( 'promote_users' ) || wp_is_large_network( 'users' ) )
 158          wp_die( -1 );
 159  
 160      if ( ! is_super_admin() && ! apply_filters( 'autocomplete_users_for_site_admins', false ) )
 161          wp_die( -1 );
 162  
 163      $return = array();
 164  
 165      // Check the type of request
 166      if ( isset( $_REQUEST['autocomplete_type'] ) )
 167          $type = $_REQUEST['autocomplete_type'];
 168      else
 169          $type = 'add';
 170  
 171      // Exclude current users of this blog
 172      if ( isset( $_REQUEST['site_id'] ) )
 173          $id = absint( $_REQUEST['site_id'] );
 174      else
 175          $id = get_current_blog_id();
 176  
 177      $include_blog_users = ( $type == 'search' ? get_users( array( 'blog_id' => $id, 'fields' => 'ID' ) ) : array() );
 178      $exclude_blog_users = ( $type == 'add' ? get_users( array( 'blog_id' => $id, 'fields' => 'ID' ) ) : array() );
 179  
 180      $users = get_users( array(
 181          'blog_id' => false,
 182          'search'  => '*' . $_REQUEST['term'] . '*',
 183          'include' => $include_blog_users,
 184          'exclude' => $exclude_blog_users,
 185          'search_columns' => array( 'user_login', 'user_nicename', 'user_email' ),
 186      ) );
 187  
 188      foreach ( $users as $user ) {
 189          $return[] = array(
 190              /* translators: 1: user_login, 2: user_email */
 191              'label' => sprintf( __( '%1$s (%2$s)' ), $user->user_login, $user->user_email ),
 192              'value' => $user->user_login,
 193          );
 194      }
 195  
 196      wp_die( json_encode( $return ) );
 197  }
 198  
 199  function wp_ajax_dashboard_widgets() {
 200      require_once  ABSPATH . 'wp-admin/includes/dashboard.php';
 201  
 202      switch ( $_GET['widget'] ) {
 203          case 'dashboard_incoming_links' :
 204              wp_dashboard_incoming_links();
 205              break;
 206          case 'dashboard_primary' :
 207              wp_dashboard_primary();
 208              break;
 209          case 'dashboard_secondary' :
 210              wp_dashboard_secondary();
 211              break;
 212          case 'dashboard_plugins' :
 213              wp_dashboard_plugins();
 214              break;
 215      }
 216      wp_die();
 217  }
 218  
 219  function wp_ajax_logged_in() {
 220      wp_die( 1 );
 221  }
 222  
 223  /*
 224   * Ajax helper.
 225   */
 226  
 227  /**
 228   * Sends back current comment total and new page links if they need to be updated.
 229   *
 230   * Contrary to normal success AJAX response ("1"), die with time() on success.
 231   *
 232   * @since 2.7
 233   *
 234   * @param int $comment_id
 235   * @return die
 236   */
 237  function _wp_ajax_delete_comment_response( $comment_id, $delta = -1 ) {
 238      $total = (int) @$_POST['_total'];
 239      $per_page = (int) @$_POST['_per_page'];
 240      $page = (int) @$_POST['_page'];
 241      $url = esc_url_raw( @$_POST['_url'] );
 242      // JS didn't send us everything we need to know. Just die with success message
 243      if ( !$total || !$per_page || !$page || !$url )
 244          wp_die( time() );
 245  
 246      $total += $delta;
 247      if ( $total < 0 )
 248          $total = 0;
 249  
 250      // Only do the expensive stuff on a page-break, and about 1 other time per page
 251      if ( 0 == $total % $per_page || 1 == mt_rand( 1, $per_page ) ) {
 252          $post_id = 0;
 253          $status = 'total_comments'; // What type of comment count are we looking for?
 254          $parsed = parse_url( $url );
 255          if ( isset( $parsed['query'] ) ) {
 256              parse_str( $parsed['query'], $query_vars );
 257              if ( !empty( $query_vars['comment_status'] ) )
 258                  $status = $query_vars['comment_status'];
 259              if ( !empty( $query_vars['p'] ) )
 260                  $post_id = (int) $query_vars['p'];
 261          }
 262  
 263          $comment_count = wp_count_comments($post_id);
 264  
 265          if ( isset( $comment_count->$status ) ) // We're looking for a known type of comment count
 266              $total = $comment_count->$status;
 267              // else use the decremented value from above
 268      }
 269  
 270      $time = time(); // The time since the last comment count
 271  
 272      $x = new WP_Ajax_Response( array(
 273          'what' => 'comment',
 274          'id' => $comment_id, // here for completeness - not used
 275          'supplemental' => array(
 276              'total_items_i18n' => sprintf( _n( '1 item', '%s items', $total ), number_format_i18n( $total ) ),
 277              'total_pages' => ceil( $total / $per_page ),
 278              'total_pages_i18n' => number_format_i18n( ceil( $total / $per_page ) ),
 279              'total' => $total,
 280              'time' => $time
 281          )
 282      ) );
 283      $x->send();
 284  }
 285  
 286  /*
 287   * POST-based Ajax handlers.
 288   */
 289  
 290  function _wp_ajax_add_hierarchical_term() {
 291      $action = $_POST['action'];
 292      $taxonomy = get_taxonomy(substr($action, 4));
 293      check_ajax_referer( $action, '_ajax_nonce-add-' . $taxonomy->name );
 294      if ( !current_user_can( $taxonomy->cap->edit_terms ) )
 295          wp_die( -1 );
 296      $names = explode(',', $_POST['new'.$taxonomy->name]);
 297      $parent = isset($_POST['new'.$taxonomy->name.'_parent']) ? (int) $_POST['new'.$taxonomy->name.'_parent'] : 0;
 298      if ( 0 > $parent )
 299          $parent = 0;
 300      if ( $taxonomy->name == 'category' )
 301          $post_category = isset($_POST['post_category']) ? (array) $_POST['post_category'] : array();
 302      else
 303          $post_category = ( isset($_POST['tax_input']) && isset($_POST['tax_input'][$taxonomy->name]) ) ? (array) $_POST['tax_input'][$taxonomy->name] : array();
 304      $checked_categories = array_map( 'absint', (array) $post_category );
 305      $popular_ids = wp_popular_terms_checklist($taxonomy->name, 0, 10, false);
 306  
 307      foreach ( $names as $cat_name ) {
 308          $cat_name = trim($cat_name);
 309          $category_nicename = sanitize_title($cat_name);
 310          if ( '' === $category_nicename )
 311              continue;
 312          if ( !$cat_id = term_exists( $cat_name, $taxonomy->name, $parent ) )
 313              $cat_id = wp_insert_term( $cat_name, $taxonomy->name, array( 'parent' => $parent ) );
 314          if ( is_wp_error( $cat_id ) )
 315              continue;
 316          else if ( is_array( $cat_id ) )
 317              $cat_id = $cat_id['term_id'];
 318          $checked_categories[] = $cat_id;
 319          if ( $parent ) // Do these all at once in a second
 320              continue;
 321          ob_start();
 322              wp_terms_checklist( 0, array( 'taxonomy' => $taxonomy->name, 'descendants_and_self' => $cat_id, 'selected_cats' => $checked_categories, 'popular_cats' => $popular_ids ));
 323          $data = ob_get_contents();
 324          ob_end_clean();
 325          $add = array(
 326              'what' => $taxonomy->name,
 327              'id' => $cat_id,
 328              'data' => str_replace( array("\n", "\t"), '', $data),
 329              'position' => -1
 330          );
 331      }
 332  
 333      if ( $parent ) { // Foncy - replace the parent and all its children
 334          $parent = get_term( $parent, $taxonomy->name );
 335          $term_id = $parent->term_id;
 336  
 337          while ( $parent->parent ) { // get the top parent
 338              $parent = get_term( $parent->parent, $taxonomy->name );
 339              if ( is_wp_error( $parent ) )
 340                  break;
 341              $term_id = $parent->term_id;
 342          }
 343  
 344          ob_start();
 345              wp_terms_checklist( 0, array('taxonomy' => $taxonomy->name, 'descendants_and_self' => $term_id, 'selected_cats' => $checked_categories, 'popular_cats' => $popular_ids));
 346          $data = ob_get_contents();
 347          ob_end_clean();
 348          $add = array(
 349              'what' => $taxonomy->name,
 350              'id' => $term_id,
 351              'data' => str_replace( array("\n", "\t"), '', $data),
 352              'position' => -1
 353          );
 354      }
 355  
 356      ob_start();
 357          wp_dropdown_categories( array(
 358              'taxonomy' => $taxonomy->name, 'hide_empty' => 0, 'name' => 'new'.$taxonomy->name.'_parent', 'orderby' => 'name',
 359              'hierarchical' => 1, 'show_option_none' => '&mdash; '.$taxonomy->labels->parent_item.' &mdash;'
 360          ) );
 361      $sup = ob_get_contents();
 362      ob_end_clean();
 363      $add['supplemental'] = array( 'newcat_parent' => $sup );
 364  
 365      $x = new WP_Ajax_Response( $add );
 366      $x->send();
 367  }
 368  
 369  function wp_ajax_delete_comment() {
 370      $id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
 371  
 372      if ( !$comment = get_comment( $id ) )
 373          wp_die( time() );
 374      if ( ! current_user_can( 'edit_comment', $comment->comment_ID ) )
 375          wp_die( -1 );
 376  
 377      check_ajax_referer( "delete-comment_$id" );
 378      $status = wp_get_comment_status( $comment->comment_ID );
 379  
 380      $delta = -1;
 381      if ( isset($_POST['trash']) && 1 == $_POST['trash'] ) {
 382          if ( 'trash' == $status )
 383              wp_die( time() );
 384          $r = wp_trash_comment( $comment->comment_ID );
 385      } elseif ( isset($_POST['untrash']) && 1 == $_POST['untrash'] ) {
 386          if ( 'trash' != $status )
 387              wp_die( time() );
 388          $r = wp_untrash_comment( $comment->comment_ID );
 389          if ( ! isset( $_POST['comment_status'] ) || $_POST['comment_status'] != 'trash' ) // undo trash, not in trash
 390              $delta = 1;
 391      } elseif ( isset($_POST['spam']) && 1 == $_POST['spam'] ) {
 392          if ( 'spam' == $status )
 393              wp_die( time() );
 394          $r = wp_spam_comment( $comment->comment_ID );
 395      } elseif ( isset($_POST['unspam']) && 1 == $_POST['unspam'] ) {
 396          if ( 'spam' != $status )
 397              wp_die( time() );
 398          $r = wp_unspam_comment( $comment->comment_ID );
 399          if ( ! isset( $_POST['comment_status'] ) || $_POST['comment_status'] != 'spam' ) // undo spam, not in spam
 400              $delta = 1;
 401      } elseif ( isset($_POST['delete']) && 1 == $_POST['delete'] ) {
 402          $r = wp_delete_comment( $comment->comment_ID );
 403      } else {
 404          wp_die( -1 );
 405      }
 406  
 407      if ( $r ) // Decide if we need to send back '1' or a more complicated response including page links and comment counts
 408          _wp_ajax_delete_comment_response( $comment->comment_ID, $delta );
 409      wp_die( 0 );
 410  }
 411  
 412  function wp_ajax_delete_tag() {
 413      $tag_id = (int) $_POST['tag_ID'];
 414      check_ajax_referer( "delete-tag_$tag_id" );
 415  
 416      $taxonomy = !empty($_POST['taxonomy']) ? $_POST['taxonomy'] : 'post_tag';
 417      $tax = get_taxonomy($taxonomy);
 418  
 419      if ( !current_user_can( $tax->cap->delete_terms ) )
 420          wp_die( -1 );
 421  
 422      $tag = get_term( $tag_id, $taxonomy );
 423      if ( !$tag || is_wp_error( $tag ) )
 424          wp_die( 1 );
 425  
 426      if ( wp_delete_term($tag_id, $taxonomy))
 427          wp_die( 1 );
 428      else
 429          wp_die( 0 );
 430  }
 431  
 432  function wp_ajax_delete_link() {
 433      $id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
 434  
 435      check_ajax_referer( "delete-bookmark_$id" );
 436      if ( !current_user_can( 'manage_links' ) )
 437          wp_die( -1 );
 438  
 439      $link = get_bookmark( $id );
 440      if ( !$link || is_wp_error( $link ) )
 441          wp_die( 1 );
 442  
 443      if ( wp_delete_link( $id ) )
 444          wp_die( 1 );
 445      else
 446          wp_die( 0 );
 447  }
 448  
 449  function wp_ajax_delete_meta() {
 450      $id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
 451  
 452      check_ajax_referer( "delete-meta_$id" );
 453      if ( !$meta = get_metadata_by_mid( 'post', $id ) )
 454          wp_die( 1 );
 455  
 456      if ( is_protected_meta( $meta->meta_key, 'post' ) || ! current_user_can( 'delete_post_meta',  $meta->post_id, $meta->meta_key ) )
 457          wp_die( -1 );
 458      if ( delete_meta( $meta->meta_id ) )
 459          wp_die( 1 );
 460      wp_die( 0 );
 461  }
 462  
 463  function wp_ajax_delete_post( $action ) {
 464      if ( empty( $action ) )
 465          $action = 'delete-post';
 466      $id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
 467  
 468      check_ajax_referer( "{$action}_$id" );
 469      if ( !current_user_can( 'delete_post', $id ) )
 470          wp_die( -1 );
 471  
 472      if ( !get_post( $id ) )
 473          wp_die( 1 );
 474  
 475      if ( wp_delete_post( $id ) )
 476          wp_die( 1 );
 477      else
 478          wp_die( 0 );
 479  }
 480  
 481  function wp_ajax_trash_post( $action ) {
 482      if ( empty( $action ) )
 483          $action = 'trash-post';
 484      $id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
 485  
 486      check_ajax_referer( "{$action}_$id" );
 487      if ( !current_user_can( 'delete_post', $id ) )
 488          wp_die( -1 );
 489  
 490      if ( !get_post( $id ) )
 491          wp_die( 1 );
 492  
 493      if ( 'trash-post' == $action )
 494          $done = wp_trash_post( $id );
 495      else
 496          $done = wp_untrash_post( $id );
 497  
 498      if ( $done )
 499          wp_die( 1 );
 500  
 501      wp_die( 0 );
 502  }
 503  
 504  function wp_ajax_untrash_post( $action ) {
 505      if ( empty( $action ) )
 506          $action = 'untrash-post';
 507      wp_ajax_trash_post( $action );
 508  }
 509  
 510  function wp_ajax_delete_page( $action ) {
 511      if ( empty( $action ) )
 512          $action = 'delete-page';
 513      $id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
 514  
 515      check_ajax_referer( "{$action}_$id" );
 516      if ( !current_user_can( 'delete_page', $id ) )
 517          wp_die( -1 );
 518  
 519      if ( ! get_post( $id ) )
 520          wp_die( 1 );
 521  
 522      if ( wp_delete_post( $id ) )
 523          wp_die( 1 );
 524      else
 525          wp_die( 0 );
 526  }
 527  
 528  function wp_ajax_dim_comment() {
 529      $id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
 530  
 531      if ( !$comment = get_comment( $id ) ) {
 532          $x = new WP_Ajax_Response( array(
 533              'what' => 'comment',
 534              'id' => new WP_Error('invalid_comment', sprintf(__('Comment %d does not exist'), $id))
 535          ) );
 536          $x->send();
 537      }
 538  
 539      if ( ! current_user_can( 'edit_comment', $comment->comment_ID ) && ! current_user_can( 'moderate_comments' ) )
 540          wp_die( -1 );
 541  
 542      $current = wp_get_comment_status( $comment->comment_ID );
 543      if ( $_POST['new'] == $current )
 544          wp_die( time() );
 545  
 546      check_ajax_referer( "approve-comment_$id" );
 547      if ( in_array( $current, array( 'unapproved', 'spam' ) ) )
 548          $result = wp_set_comment_status( $comment->comment_ID, 'approve', true );
 549      else
 550          $result = wp_set_comment_status( $comment->comment_ID, 'hold', true );
 551  
 552      if ( is_wp_error($result) ) {
 553          $x = new WP_Ajax_Response( array(
 554              'what' => 'comment',
 555              'id' => $result
 556          ) );
 557          $x->send();
 558      }
 559  
 560      // Decide if we need to send back '1' or a more complicated response including page links and comment counts
 561      _wp_ajax_delete_comment_response( $comment->comment_ID );
 562      wp_die( 0 );
 563  }
 564  
 565  function wp_ajax_add_link_category( $action ) {
 566      if ( empty( $action ) )
 567          $action = 'add-link-category';
 568      check_ajax_referer( $action );
 569      if ( !current_user_can( 'manage_categories' ) )
 570          wp_die( -1 );
 571      $names = explode(',', wp_unslash( $_POST['newcat'] ) );
 572      $x = new WP_Ajax_Response();
 573      foreach ( $names as $cat_name ) {
 574          $cat_name = trim($cat_name);
 575          $slug = sanitize_title($cat_name);
 576          if ( '' === $slug )
 577              continue;
 578          if ( !$cat_id = term_exists( $cat_name, 'link_category' ) )
 579              $cat_id = wp_insert_term( $cat_name, 'link_category' );
 580          if ( is_wp_error( $cat_id ) )
 581              continue;
 582          else if ( is_array( $cat_id ) )
 583              $cat_id = $cat_id['term_id'];
 584          $cat_name = esc_html( $cat_name );
 585          $x->add( array(
 586              'what' => 'link-category',
 587              'id' => $cat_id,
 588              'data' => "<li id='link-category-$cat_id'><label for='in-link-category-$cat_id' class='selectit'><input value='" . esc_attr($cat_id) . "' type='checkbox' checked='checked' name='link_category[]' id='in-link-category-$cat_id'/> $cat_name</label></li>",
 589              'position' => -1
 590          ) );
 591      }
 592      $x->send();
 593  }
 594  
 595  function wp_ajax_add_tag() {
 596      global $wp_list_table;
 597  
 598      check_ajax_referer( 'add-tag', '_wpnonce_add-tag' );
 599      $post_type = !empty($_POST['post_type']) ? $_POST['post_type'] : 'post';
 600      $taxonomy = !empty($_POST['taxonomy']) ? $_POST['taxonomy'] : 'post_tag';
 601      $tax = get_taxonomy($taxonomy);
 602  
 603      if ( !current_user_can( $tax->cap->edit_terms ) )
 604          wp_die( -1 );
 605  
 606      $x = new WP_Ajax_Response();
 607  
 608      $tag = wp_insert_term($_POST['tag-name'], $taxonomy, $_POST );
 609  
 610      if ( !$tag || is_wp_error($tag) || (!$tag = get_term( $tag['term_id'], $taxonomy )) ) {
 611          $message = __('An error has occurred. Please reload the page and try again.');
 612          if ( is_wp_error($tag) && $tag->get_error_message() )
 613              $message = $tag->get_error_message();
 614  
 615          $x->add( array(
 616              'what' => 'taxonomy',
 617              'data' => new WP_Error('error', $message )
 618          ) );
 619          $x->send();
 620      }
 621  
 622      $wp_list_table = _get_list_table( 'WP_Terms_List_Table', array( 'screen' => $_POST['screen'] ) );
 623  
 624      $level = 0;
 625      if ( is_taxonomy_hierarchical($taxonomy) ) {
 626          $level = count( get_ancestors( $tag->term_id, $taxonomy ) );
 627          ob_start();
 628          $wp_list_table->single_row( $tag, $level );
 629          $noparents = ob_get_clean();
 630      }
 631  
 632      ob_start();
 633      $wp_list_table->single_row( $tag );
 634      $parents = ob_get_clean();
 635  
 636      $x->add( array(
 637          'what' => 'taxonomy',
 638          'supplemental' => compact('parents', 'noparents')
 639          ) );
 640      $x->add( array(
 641          'what' => 'term',
 642          'position' => $level,
 643          'supplemental' => (array) $tag
 644          ) );
 645      $x->send();
 646  }
 647  
 648  function wp_ajax_get_tagcloud() {
 649      if ( isset( $_POST['tax'] ) ) {
 650          $taxonomy = sanitize_key( $_POST['tax'] );
 651          $tax = get_taxonomy( $taxonomy );
 652          if ( ! $tax )
 653              wp_die( 0 );
 654          if ( ! current_user_can( $tax->cap->assign_terms ) )
 655              wp_die( -1 );
 656      } else {
 657          wp_die( 0 );
 658      }
 659  
 660      $tags = get_terms( $taxonomy, array( 'number' => 45, 'orderby' => 'count', 'order' => 'DESC' ) );
 661  
 662      if ( empty( $tags ) )
 663          wp_die( $tax->labels->not_found );
 664  
 665      if ( is_wp_error( $tags ) )
 666          wp_die( $tags->get_error_message() );
 667  
 668      foreach ( $tags as $key => $tag ) {
 669          $tags[ $key ]->link = '#';
 670          $tags[ $key ]->id = $tag->term_id;
 671      }
 672  
 673      // We need raw tag names here, so don't filter the output
 674      $return = wp_generate_tag_cloud( $tags, array('filter' => 0) );
 675  
 676      if ( empty($return) )
 677          wp_die( 0 );
 678  
 679      echo $return;
 680  
 681      wp_die();
 682  }
 683  
 684  function wp_ajax_get_comments( $action ) {
 685      global $wp_list_table, $post_id;
 686      if ( empty( $action ) )
 687          $action = 'get-comments';
 688  
 689      check_ajax_referer( $action );
 690  
 691      $wp_list_table = _get_list_table( 'WP_Post_Comments_List_Table', array( 'screen' => 'edit-comments' ) );
 692  
 693      if ( !current_user_can( 'edit_post', $post_id ) )
 694          wp_die( -1 );
 695  
 696      $wp_list_table->prepare_items();
 697  
 698      if ( !$wp_list_table->has_items() )
 699          wp_die( 1 );
 700  
 701      $x = new WP_Ajax_Response();
 702      ob_start();
 703      foreach ( $wp_list_table->items as $comment ) {
 704          if ( ! current_user_can( 'edit_comment', $comment->comment_ID ) )
 705              continue;
 706          get_comment( $comment );
 707          $wp_list_table->single_row( $comment );
 708      }
 709      $comment_list_item = ob_get_contents();
 710      ob_end_clean();
 711  
 712      $x->add( array(
 713          'what' => 'comments',
 714          'data' => $comment_list_item
 715      ) );
 716      $x->send();
 717  }
 718  
 719  function wp_ajax_replyto_comment( $action ) {
 720      global $wp_list_table, $wpdb;
 721      if ( empty( $action ) )
 722          $action = 'replyto-comment';
 723  
 724      check_ajax_referer( $action, '_ajax_nonce-replyto-comment' );
 725  
 726      $comment_post_ID = (int) $_POST['comment_post_ID'];
 727      $post = get_post( $comment_post_ID );
 728      if ( ! $post )
 729          wp_die( -1 );
 730  
 731      if ( !current_user_can( 'edit_post', $comment_post_ID ) )
 732          wp_die( -1 );
 733  
 734      if ( empty( $post->post_status ) )
 735          wp_die( 1 );
 736      elseif ( in_array($post->post_status, array('draft', 'pending', 'trash') ) )
 737          wp_die( __('ERROR: you are replying to a comment on a draft post.') );
 738  
 739      $user = wp_get_current_user();
 740      if ( $user->exists() ) {
 741          $user_ID = $user->ID;
 742          $comment_author       = $wpdb->escape($user->display_name);
 743          $comment_author_email = $wpdb->escape($user->user_email);
 744          $comment_author_url   = $wpdb->escape($user->user_url);
 745          $comment_content      = trim($_POST['content']);
 746          if ( current_user_can( 'unfiltered_html' ) ) {
 747              if ( wp_create_nonce( 'unfiltered-html-comment' ) != $_POST['_wp_unfiltered_html_comment'] ) {
 748                  kses_remove_filters(); // start with a clean slate
 749                  kses_init_filters(); // set up the filters
 750              }
 751          }
 752      } else {
 753          wp_die( __( 'Sorry, you must be logged in to reply to a comment.' ) );
 754      }
 755  
 756      if ( '' == $comment_content )
 757          wp_die( __( 'ERROR: please type a comment.' ) );
 758  
 759      $comment_parent = absint($_POST['comment_ID']);
 760      $comment_auto_approved = false;
 761      $commentdata = compact('comment_post_ID', 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content', 'comment_type', 'comment_parent', 'user_ID');
 762  
 763      // automatically approve parent comment
 764      if ( !empty($_POST['approve_parent']) ) {
 765          $parent = get_comment( $comment_parent );
 766  
 767          if ( $parent && $parent->comment_approved === '0' && $parent->comment_post_ID == $comment_post_ID ) {
 768              if ( wp_set_comment_status( $parent->comment_ID, 'approve' ) )
 769                  $comment_auto_approved = true;
 770          }
 771      }
 772  
 773      $comment_id = wp_new_comment( $commentdata );
 774      $comment = get_comment($comment_id);
 775      if ( ! $comment ) wp_die( 1 );
 776  
 777      $position = ( isset($_POST['position']) && (int) $_POST['position'] ) ? (int) $_POST['position'] : '-1';
 778  
 779      ob_start();
 780          if ( 'dashboard' == $_REQUEST['mode'] ) {
 781              require_once ( ABSPATH . 'wp-admin/includes/dashboard.php' );
 782              _wp_dashboard_recent_comments_row( $comment );
 783          } else {
 784              if ( 'single' == $_REQUEST['mode'] ) {
 785                  $wp_list_table = _get_list_table('WP_Post_Comments_List_Table', array( 'screen' => 'edit-comments' ) );
 786              } else {
 787                  $wp_list_table = _get_list_table('WP_Comments_List_Table', array( 'screen' => 'edit-comments' ) );
 788              }
 789              $wp_list_table->single_row( $comment );
 790          }
 791          $comment_list_item = ob_get_contents();
 792      ob_end_clean();
 793  
 794      $response =  array(
 795          'what' => 'comment',
 796          'id' => $comment->comment_ID,
 797          'data' => $comment_list_item,
 798          'position' => $position
 799      );
 800  
 801      if ( $comment_auto_approved )
 802          $response['supplemental'] = array( 'parent_approved' => $parent->comment_ID );
 803  
 804      $x = new WP_Ajax_Response();
 805      $x->add( $response );
 806      $x->send();
 807  }
 808  
 809  function wp_ajax_edit_comment() {
 810      global $wp_list_table;
 811  
 812      check_ajax_referer( 'replyto-comment', '_ajax_nonce-replyto-comment' );
 813  
 814      $comment_id = (int) $_POST['comment_ID'];
 815      if ( ! current_user_can( 'edit_comment', $comment_id ) )
 816          wp_die( -1 );
 817  
 818      if ( '' == $_POST['content'] )
 819          wp_die( __( 'ERROR: please type a comment.' ) );
 820  
 821      $_POST['comment_status'] = $_POST['status'];
 822      edit_comment();
 823  
 824      $position = ( isset($_POST['position']) && (int) $_POST['position']) ? (int) $_POST['position'] : '-1';
 825      $comments_status = isset($_POST['comments_listing']) ? $_POST['comments_listing'] : '';
 826  
 827      $checkbox = ( isset($_POST['checkbox']) && true == $_POST['checkbox'] ) ? 1 : 0;
 828      $wp_list_table = _get_list_table( $checkbox ? 'WP_Comments_List_Table' : 'WP_Post_Comments_List_Table', array( 'screen' => 'edit-comments' ) );
 829  
 830      $comment = get_comment( $comment_id );
 831  
 832      ob_start();
 833          $wp_list_table->single_row( $comment );
 834          $comment_list_item = ob_get_contents();
 835      ob_end_clean();
 836  
 837      $x = new WP_Ajax_Response();
 838  
 839      $x->add( array(
 840          'what' => 'edit_comment',
 841          'id' => $comment->comment_ID,
 842          'data' => $comment_list_item,
 843          'position' => $position
 844      ));
 845  
 846      $x->send();
 847  }
 848  
 849  function wp_ajax_add_menu_item() {
 850      check_ajax_referer( 'add-menu_item', 'menu-settings-column-nonce' );
 851  
 852      if ( ! current_user_can( 'edit_theme_options' ) )
 853          wp_die( -1 );
 854  
 855      require_once  ABSPATH . 'wp-admin/includes/nav-menu.php';
 856  
 857      // For performance reasons, we omit some object properties from the checklist.
 858      // The following is a hacky way to restore them when adding non-custom items.
 859  
 860      $menu_items_data = array();
 861      foreach ( (array) $_POST['menu-item'] as $menu_item_data ) {
 862          if (
 863              ! empty( $menu_item_data['menu-item-type'] ) &&
 864              'custom' != $menu_item_data['menu-item-type'] &&
 865              ! empty( $menu_item_data['menu-item-object-id'] )
 866          ) {
 867              switch( $menu_item_data['menu-item-type'] ) {
 868                  case 'post_type' :
 869                      $_object = get_post( $menu_item_data['menu-item-object-id'] );
 870                  break;
 871  
 872                  case 'taxonomy' :
 873                      $_object = get_term( $menu_item_data['menu-item-object-id'], $menu_item_data['menu-item-object'] );
 874                  break;
 875              }
 876  
 877              $_menu_items = array_map( 'wp_setup_nav_menu_item', array( $_object ) );
 878              $_menu_item = array_shift( $_menu_items );
 879  
 880              // Restore the missing menu item properties
 881              $menu_item_data['menu-item-description'] = $_menu_item->description;
 882          }
 883  
 884          $menu_items_data[] = $menu_item_data;
 885      }
 886  
 887      $item_ids = wp_save_nav_menu_items( 0, $menu_items_data );
 888      if ( is_wp_error( $item_ids ) )
 889          wp_die( 0 );
 890  
 891      $menu_items = array();
 892  
 893      foreach ( (array) $item_ids as $menu_item_id ) {
 894          $menu_obj = get_post( $menu_item_id );
 895          if ( ! empty( $menu_obj->ID ) ) {
 896              $menu_obj = wp_setup_nav_menu_item( $menu_obj );
 897              $menu_obj->label = $menu_obj->title; // don't show "(pending)" in ajax-added items
 898              $menu_items[] = $menu_obj;
 899          }
 900      }
 901  
 902      $walker_class_name = apply_filters( 'wp_edit_nav_menu_walker', 'Walker_Nav_Menu_Edit', $_POST['menu'] );
 903  
 904      if ( ! class_exists( $walker_class_name ) )
 905          wp_die( 0 );
 906  
 907      if ( ! empty( $menu_items ) ) {
 908          $args = array(
 909              'after' => '',
 910              'before' => '',
 911              'link_after' => '',
 912              'link_before' => '',
 913              'walker' => new $walker_class_name,
 914          );
 915          echo walk_nav_menu_tree( $menu_items, 0, (object) $args );
 916      }
 917      wp_die();
 918  }
 919  
 920  function wp_ajax_add_meta() {
 921      check_ajax_referer( 'add-meta', '_ajax_nonce-add-meta' );
 922      $c = 0;
 923      $pid = (int) $_POST['post_id'];
 924      $post = get_post( $pid );
 925  
 926      if ( isset($_POST['metakeyselect']) || isset($_POST['metakeyinput']) ) {
 927          if ( !current_user_can( 'edit_post', $pid ) )
 928              wp_die( -1 );
 929          if ( isset($_POST['metakeyselect']) && '#NONE#' == $_POST['metakeyselect'] && empty($_POST['metakeyinput']) )
 930              wp_die( 1 );
 931          if ( $post->post_status == 'auto-draft' ) {
 932              $save_POST = $_POST; // Backup $_POST
 933              $_POST = array(); // Make it empty for edit_post()
 934              $_POST['action'] = 'draft'; // Warning fix
 935              $_POST['post_ID'] = $pid;
 936              $_POST['post_type'] = $post->post_type;
 937              $_POST['post_status'] = 'draft';
 938              $now = current_time('timestamp', 1);
 939              $_POST['post_title'] = sprintf( __( 'Draft created on %1$s at %2$s' ), date( get_option( 'date_format' ), $now ), date( get_option( 'time_format' ), $now ) );
 940  
 941              if ( $pid = edit_post() ) {
 942                  if ( is_wp_error( $pid ) ) {
 943                      $x = new WP_Ajax_Response( array(
 944                          'what' => 'meta',
 945                          'data' => $pid
 946                      ) );
 947                      $x->send();
 948                  }
 949                  $_POST = $save_POST; // Now we can restore original $_POST again
 950                  if ( !$mid = add_meta( $pid ) )
 951                      wp_die( __( 'Please provide a custom field value.' ) );
 952              } else {
 953                  wp_die( 0 );
 954              }
 955          } else if ( !$mid = add_meta( $pid ) ) {
 956              wp_die( __( 'Please provide a custom field value.' ) );
 957          }
 958  
 959          $meta = get_metadata_by_mid( 'post', $mid );
 960          $pid = (int) $meta->post_id;
 961          $meta = get_object_vars( $meta );
 962          $x = new WP_Ajax_Response( array(
 963              'what' => 'meta',
 964              'id' => $mid,
 965              'data' => _list_meta_row( $meta, $c ),
 966              'position' => 1,
 967              'supplemental' => array('postid' => $pid)
 968          ) );
 969      } else { // Update?
 970          $mid = (int) key( $_POST['meta'] );
 971          $key = wp_unslash( $_POST['meta'][$mid]['key'] );
 972          $value = wp_unslash( $_POST['meta'][$mid]['value'] );
 973          if ( '' == trim($key) )
 974              wp_die( __( 'Please provide a custom field name.' ) );
 975          if ( '' == trim($value) )
 976              wp_die( __( 'Please provide a custom field value.' ) );
 977          if ( ! $meta = get_metadata_by_mid( 'post', $mid ) )
 978              wp_die( 0 ); // if meta doesn't exist
 979          if ( is_protected_meta( $meta->meta_key, 'post' ) || is_protected_meta( $key, 'post' ) ||
 980              ! current_user_can( 'edit_post_meta', $meta->post_id, $meta->meta_key ) ||
 981              ! current_user_can( 'edit_post_meta', $meta->post_id, $key ) )
 982              wp_die( -1 );
 983          if ( $meta->meta_value != $value || $meta->meta_key != $key ) {
 984              if ( !$u = update_metadata_by_mid( 'post', $mid, $value, $key ) )
 985                  wp_die( 0 ); // We know meta exists; we also know it's unchanged (or DB error, in which case there are bigger problems).
 986          }
 987  
 988          $x = new WP_Ajax_Response( array(
 989              'what' => 'meta',
 990              'id' => $mid, 'old_id' => $mid,
 991              'data' => _list_meta_row( array(
 992                  'meta_key' => $key,
 993                  'meta_value' => $value,
 994                  'meta_id' => $mid
 995              ), $c ),
 996              'position' => 0,
 997              'supplemental' => array('postid' => $meta->post_id)
 998          ) );
 999      }
1000      $x->send();
1001  }
1002  
1003  function wp_ajax_add_user( $action ) {
1004      global $wp_list_table;
1005      if ( empty( $action ) )
1006          $action = 'add-user';
1007  
1008      check_ajax_referer( $action );
1009      if ( ! current_user_can('create_users') )
1010          wp_die( -1 );
1011      if ( ! $user_id = edit_user() ) {
1012          wp_die( 0 );
1013      } elseif ( is_wp_error( $user_id ) ) {
1014          $x = new WP_Ajax_Response( array(
1015              'what' => 'user',
1016              'id' => $user_id
1017          ) );
1018          $x->send();
1019      }
1020      $user_object = get_userdata( $user_id );
1021  
1022      $wp_list_table = _get_list_table('WP_Users_List_Table');
1023  
1024      $role = current( $user_object->roles );
1025  
1026      $x = new WP_Ajax_Response( array(
1027          'what' => 'user',
1028          'id' => $user_id,
1029          'data' => $wp_list_table->single_row( $user_object, '', $role ),
1030          'supplemental' => array(
1031              'show-link' => sprintf(__( 'User <a href="#%s">%s</a> added' ), "user-$user_id", $user_object->user_login),
1032              'role' => $role,
1033          )
1034      ) );
1035      $x->send();
1036  }
1037  
1038  function wp_ajax_autosave() {
1039      define( 'DOING_AUTOSAVE', true );
1040  
1041      check_ajax_referer( 'autosave', 'autosavenonce' );
1042  
1043      $_POST['post_category'] = explode(",", $_POST['catslist']);
1044      if ( $_POST['post_type'] == 'page' || empty($_POST['post_category']) )
1045          unset($_POST['post_category']);
1046  
1047      $data = '';
1048      $supplemental = array();
1049      $id = $revision_id = 0;
1050  
1051      $post_id = (int) $_POST['post_id'];
1052      $_POST['ID'] = $_POST['post_ID'] = $post_id;
1053      $post = get_post($post_id);
1054      if ( 'auto-draft' == $post->post_status )
1055          $_POST['post_status'] = 'draft';
1056  
1057      if ( 'page' == $post->post_type ) {
1058          if ( !current_user_can('edit_page', $post->ID) )
1059              wp_die( __( 'You are not allowed to edit this page.' ) );
1060      } else {
1061          if ( !current_user_can('edit_post', $post->ID) )
1062              wp_die( __( 'You are not allowed to edit this post.' ) );
1063      }
1064  
1065      if ( ! empty( $_POST['autosave'] ) ) {
1066          if ( ! wp_check_post_lock( $post->ID ) && get_current_user_id() == $post->post_author && ( 'auto-draft' == $post->post_status || 'draft' == $post->post_status ) ) {
1067              // Drafts and auto-drafts are just overwritten by autosave for the same user if the post is not locked
1068              $id = edit_post();
1069          } else {
1070              // Non drafts or other users drafts are not overwritten. The autosave is stored in a special post revision for each user.
1071              $revision_id = wp_create_post_autosave( $post->ID );
1072              if ( is_wp_error($revision_id) )
1073                  $id = $revision_id;
1074              else
1075                  $id = $post->ID;
1076          }
1077  
1078          // When is_wp_error($id), $id overwrites $data in WP_Ajax_Response
1079          // todo: Needs review. The errors generated in WP_Ajax_Response and parsed with wpAjax.parseAjaxResponse() haven't been used for years.
1080          if ( ! is_wp_error($id) ) {
1081              /* translators: draft saved date format, see http://php.net/date */
1082              $draft_saved_date_format = __('g:i:s a');
1083              /* translators: %s: date and time */
1084              $data = sprintf( __('Draft saved at %s.'), date_i18n( $draft_saved_date_format ) );
1085          }
1086      } else {
1087          if ( ! empty( $_POST['auto_draft'] ) )
1088              $id = 0; // This tells us it didn't actually save
1089          else
1090              $id = $post->ID;
1091      }
1092  
1093      $x = new WP_Ajax_Response( array(
1094          'what' => 'autosave',
1095          'id' => $id,
1096          'data' => $data,
1097          'supplemental' => $supplemental
1098      ) );
1099      $x->send();
1100  }
1101  
1102  function wp_ajax_closed_postboxes() {
1103      check_ajax_referer( 'closedpostboxes', 'closedpostboxesnonce' );
1104      $closed = isset( $_POST['closed'] ) ? explode( ',', $_POST['closed']) : array();
1105      $closed = array_filter($closed);
1106  
1107      $hidden = isset( $_POST['hidden'] ) ? explode( ',', $_POST['hidden']) : array();
1108      $hidden = array_filter($hidden);
1109  
1110      $page = isset( $_POST['page'] ) ? $_POST['page'] : '';
1111  
1112      if ( $page != sanitize_key( $page ) )
1113          wp_die( 0 );
1114  
1115      if ( ! $user = wp_get_current_user() )
1116          wp_die( -1 );
1117  
1118      if ( is_array($closed) )
1119          update_user_option($user->ID, "closedpostboxes_$page", $closed, true);
1120  
1121      if ( is_array($hidden) ) {
1122          $hidden = array_diff( $hidden, array('submitdiv', 'linksubmitdiv', 'manage-menu', 'create-menu') ); // postboxes that are always shown
1123          update_user_option($user->ID, "metaboxhidden_$page", $hidden, true);
1124      }
1125  
1126      wp_die( 1 );
1127  }
1128  
1129  function wp_ajax_show_post_format_ui() {
1130      if ( empty( $_POST['post_type'] ) )
1131          wp_die( 0 );
1132  
1133      check_ajax_referer( 'show-post-format-ui_' . $_POST['post_type'], 'nonce' );
1134  
1135      if ( ! $post_type_object = get_post_type_object( $_POST['post_type'] ) )
1136          wp_die( 0 );
1137  
1138      if ( ! current_user_can( $post_type_object->cap->edit_posts ) )
1139          wp_die( -1 );
1140  
1141      update_user_option( get_current_user_id(), 'post_formats_' . $post_type_object->name, empty( $_POST['show'] ) ? 0 : 1 );
1142  
1143      wp_die( 1 );
1144  }
1145  
1146  function wp_ajax_hidden_columns() {
1147      check_ajax_referer( 'screen-options-nonce', 'screenoptionnonce' );
1148      $hidden = isset( $_POST['hidden'] ) ? $_POST['hidden'] : '';
1149      $hidden = explode( ',', $_POST['hidden'] );
1150      $page = isset( $_POST['page'] ) ? $_POST['page'] : '';
1151  
1152      if ( $page != sanitize_key( $page ) )
1153          wp_die( 0 );
1154  
1155      if ( ! $user = wp_get_current_user() )
1156          wp_die( -1 );
1157  
1158      if ( is_array($hidden) )
1159          update_user_option($user->ID, "manage{$page}columnshidden", $hidden, true);
1160  
1161      wp_die( 1 );
1162  }
1163  
1164  function wp_ajax_update_welcome_panel() {
1165      check_ajax_referer( 'welcome-panel-nonce', 'welcomepanelnonce' );
1166  
1167      if ( ! current_user_can( 'edit_theme_options' ) )
1168          wp_die( -1 );
1169  
1170      update_user_meta( get_current_user_id(), 'show_welcome_panel', empty( $_POST['visible'] ) ? 0 : 1 );
1171  
1172      wp_die( 1 );
1173  }
1174  
1175  function wp_ajax_menu_get_metabox() {
1176      if ( ! current_user_can( 'edit_theme_options' ) )
1177          wp_die( -1 );
1178  
1179      require_once  ABSPATH . 'wp-admin/includes/nav-menu.php';
1180  
1181      if ( isset( $_POST['item-type'] ) && 'post_type' == $_POST['item-type'] ) {
1182          $type = 'posttype';
1183          $callback = 'wp_nav_menu_item_post_type_meta_box';
1184          $items = (array) get_post_types( array( 'show_in_nav_menus' => true ), 'object' );
1185      } elseif ( isset( $_POST['item-type'] ) && 'taxonomy' == $_POST['item-type'] ) {
1186          $type = 'taxonomy';
1187          $callback = 'wp_nav_menu_item_taxonomy_meta_box';
1188          $items = (array) get_taxonomies( array( 'show_ui' => true ), 'object' );
1189      }
1190  
1191      if ( ! empty( $_POST['item-object'] ) && isset( $items[$_POST['item-object']] ) ) {
1192          $item = apply_filters( 'nav_menu_meta_box_object', $items[ $_POST['item-object'] ] );
1193          ob_start();
1194          call_user_func_array($callback, array(
1195              null,
1196              array(
1197                  'id' => 'add-' . $item->name,
1198                  'title' => $item->labels->name,
1199                  'callback' => $callback,
1200                  'args' => $item,
1201              )
1202          ));
1203  
1204          $markup = ob_get_clean();
1205  
1206          echo json_encode(array(
1207              'replace-id' => $type . '-' . $item->name,
1208              'markup' => $markup,
1209          ));
1210      }
1211  
1212      wp_die();
1213  }
1214  
1215  function wp_ajax_wp_link_ajax() {
1216      check_ajax_referer( 'internal-linking', '_ajax_linking_nonce' );
1217  
1218      $args = array();
1219  
1220      if ( isset( $_POST['search'] ) )
1221          $args['s'] = wp_unslash( $_POST['search'] );
1222      $args['pagenum'] = ! empty( $_POST['page'] ) ? absint( $_POST['page'] ) : 1;
1223  
1224      require(ABSPATH . WPINC . '/class-wp-editor.php');
1225      $results = _WP_Editors::wp_link_query( $args );
1226  
1227      if ( ! isset( $results ) )
1228          wp_die( 0 );
1229  
1230      echo json_encode( $results );
1231      echo "\n";
1232  
1233      wp_die();
1234  }
1235  
1236  function wp_ajax_menu_locations_save() {
1237      if ( ! current_user_can( 'edit_theme_options' ) )
1238          wp_die( -1 );
1239      check_ajax_referer( 'add-menu_item', 'menu-settings-column-nonce' );
1240      if ( ! isset( $_POST['menu-locations'] ) )
1241          wp_die( 0 );
1242      set_theme_mod( 'nav_menu_locations', array_map( 'absint', $_POST['menu-locations'] ) );
1243      wp_die( 1 );
1244  }
1245  
1246  function wp_ajax_meta_box_order() {
1247      check_ajax_referer( 'meta-box-order' );
1248      $order = isset( $_POST['order'] ) ? (array) $_POST['order'] : false;
1249      $page_columns = isset( $_POST['page_columns'] ) ? $_POST['page_columns'] : 'auto';
1250  
1251      if ( $page_columns != 'auto' )
1252          $page_columns = (int) $page_columns;
1253  
1254      $page = isset( $_POST['page'] ) ? $_POST['page'] : '';
1255  
1256      if ( $page != sanitize_key( $page ) )
1257          wp_die( 0 );
1258  
1259      if ( ! $user = wp_get_current_user() )
1260          wp_die( -1 );
1261  
1262      if ( $order )
1263          update_user_option($user->ID, "meta-box-order_$page", $order, true);
1264  
1265      if ( $page_columns )
1266          update_user_option($user->ID, "screen_layout_$page", $page_columns, true);
1267  
1268      wp_die( 1 );
1269  }
1270  
1271  function wp_ajax_menu_quick_search() {
1272      if ( ! current_user_can( 'edit_theme_options' ) )
1273          wp_die( -1 );
1274  
1275      require_once  ABSPATH . 'wp-admin/includes/nav-menu.php';
1276  
1277      _wp_ajax_menu_quick_search( $_POST );
1278  
1279      wp_die();
1280  }
1281  
1282  function wp_ajax_get_permalink() {
1283      check_ajax_referer( 'getpermalink', 'getpermalinknonce' );
1284      $post_id = isset($_POST['post_id'])? intval($_POST['post_id']) : 0;
1285      wp_die( add_query_arg( array( 'preview' => 'true' ), get_permalink( $post_id ) ) );
1286  }
1287  
1288  function wp_ajax_sample_permalink() {
1289      check_ajax_referer( 'samplepermalink', 'samplepermalinknonce' );
1290      $post_id = isset($_POST['post_id'])? intval($_POST['post_id']) : 0;
1291      $title = isset($_POST['new_title'])? $_POST['new_title'] : '';
1292      $slug = isset($_POST['new_slug'])? $_POST['new_slug'] : null;
1293      wp_die( get_sample_permalink_html( $post_id, $title, $slug ) );
1294  }
1295  
1296  function wp_ajax_inline_save() {
1297      global $wp_list_table;
1298  
1299      check_ajax_referer( 'inlineeditnonce', '_inline_edit' );
1300  
1301      if ( ! isset($_POST['post_ID']) || ! ( $post_ID = (int) $_POST['post_ID'] ) )
1302          wp_die();
1303  
1304      if ( 'page' == $_POST['post_type'] ) {
1305          if ( ! current_user_can( 'edit_page', $post_ID ) )
1306              wp_die( __( 'You are not allowed to edit this page.' ) );
1307      } else {
1308          if ( ! current_user_can( 'edit_post', $post_ID ) )
1309              wp_die( __( 'You are not allowed to edit this post.' ) );
1310      }
1311  
1312      if ( $last = wp_check_post_lock( $post_ID ) ) {
1313          $last_user = get_userdata( $last );
1314          $last_user_name = $last_user ? $last_user->display_name : __( 'Someone' );
1315          printf( $_POST['post_type'] == 'page' ? __( 'Saving is disabled: %s is currently editing this page.' ) : __( 'Saving is disabled: %s is currently editing this post.' ),    esc_html( $last_user_name ) );
1316          wp_die();
1317      }
1318  
1319      $data = &$_POST;
1320  
1321      $post = get_post( $post_ID, ARRAY_A );
1322      $post = wp_slash($post); //since it is from db
1323  
1324      $data['content'] = $post['post_content'];
1325      $data['excerpt'] = $post['post_excerpt'];
1326  
1327      // rename
1328      $data['user_ID'] = $GLOBALS['user_ID'];
1329  
1330      if ( isset($data['post_parent']) )
1331          $data['parent_id'] = $data['post_parent'];
1332  
1333      // status
1334      if ( isset($data['keep_private']) && 'private' == $data['keep_private'] )
1335          $data['post_status'] = 'private';
1336      else
1337          $data['post_status'] = $data['_status'];
1338  
1339      if ( empty($data['comment_status']) )
1340          $data['comment_status'] = 'closed';
1341      if ( empty($data['ping_status']) )
1342          $data['ping_status'] = 'closed';
1343  
1344      // Hack: wp_unique_post_slug() doesn't work for drafts, so we will fake that our post is published.
1345      if ( ! empty( $data['post_name'] ) && in_array( $post['post_status'], array( 'draft', 'pending' ) ) ) {
1346          $post['post_status'] = 'publish';
1347          $data['post_name'] = wp_unique_post_slug( $data['post_name'], $post['ID'], $post['post_status'], $post['post_type'], $post['post_parent'] );
1348      }
1349  
1350      // update the post
1351      edit_post();
1352  
1353      $wp_list_table = _get_list_table( 'WP_Posts_List_Table', array( 'screen' => $_POST['screen'] ) );
1354  
1355      $mode = $_POST['post_view'];
1356  
1357      $level = 0;
1358      $request_post = array( get_post( $_POST['post_ID'] ) );
1359      $parent = $request_post[0]->post_parent;
1360  
1361      while ( $parent > 0 ) {
1362          $parent_post = get_post( $parent );
1363          $parent = $parent_post->post_parent;
1364          $level++;
1365      }
1366  
1367      $wp_list_table->display_rows( array( get_post( $_POST['post_ID'] ) ), $level );
1368  
1369      wp_die();
1370  }
1371  
1372  function wp_ajax_inline_save_tax() {
1373      global $wp_list_table;
1374  
1375      check_ajax_referer( 'taxinlineeditnonce', '_inline_edit' );
1376  
1377      $taxonomy = sanitize_key( $_POST['taxonomy'] );
1378      $tax = get_taxonomy( $taxonomy );
1379      if ( ! $tax )
1380          wp_die( 0 );
1381  
1382      if ( ! current_user_can( $tax->cap->edit_terms ) )
1383          wp_die( -1 );
1384  
1385      $wp_list_table = _get_list_table( 'WP_Terms_List_Table', array( 'screen' => 'edit-' . $taxonomy ) );
1386  
1387      if ( ! isset($_POST['tax_ID']) || ! ( $id = (int) $_POST['tax_ID'] ) )
1388          wp_die( -1 );
1389  
1390      $tag = get_term( $id, $taxonomy );
1391      $_POST['description'] = $tag->description;
1392  
1393      $updated = wp_update_term($id, $taxonomy, $_POST);
1394      if ( $updated && !is_wp_error($updated) ) {
1395          $tag = get_term( $updated['term_id'], $taxonomy );
1396          if ( !$tag || is_wp_error( $tag ) ) {
1397              if ( is_wp_error($tag) && $tag->get_error_message() )
1398                  wp_die( $tag->get_error_message() );
1399              wp_die( __( 'Item not updated.' ) );
1400          }
1401      } else {
1402          if ( is_wp_error($updated) && $updated->get_error_message() )
1403              wp_die( $updated->get_error_message() );
1404          wp_die( __( 'Item not updated.' ) );
1405      }
1406      $level = 0;
1407      $parent = $tag->parent;
1408      while ( $parent > 0 ) {
1409          $parent_tag = get_term( $parent, $taxonomy );
1410          $parent = $parent_tag->parent;
1411          $level++;
1412      }
1413      $wp_list_table->single_row( $tag, $level );
1414      wp_die();
1415  }
1416  
1417  function wp_ajax_find_posts() {
1418      global $wpdb;
1419  
1420      check_ajax_referer( 'find-posts' );
1421  
1422      $post_types = get_post_types( array( 'public' => true ), 'objects' );
1423      unset( $post_types['attachment'] );
1424  
1425      $s = wp_unslash( $_POST['ps'] );
1426      $searchand = $search = '';
1427      $args = array(
1428          'post_type' => array_keys( $post_types ),
1429          'post_status' => 'any',
1430          'posts_per_page' => 50,
1431      );
1432      if ( '' !== $s )
1433          $args['s'] = $s;
1434  
1435      $posts = get_posts( $args );
1436  
1437      if ( ! $posts )
1438          wp_die( __('No items found.') );
1439  
1440      $html = '<table class="widefat" cellspacing="0"><thead><tr><th class="found-radio"><br /></th><th>'.__('Title').'</th><th class="no-break">'.__('Type').'</th><th class="no-break">'.__('Date').'</th><th class="no-break">'.__('Status').'</th></tr></thead><tbody>';
1441      foreach ( $posts as $post ) {
1442          $title = trim( $post->post_title ) ? $post->post_title : __( '(no title)' );
1443  
1444          switch ( $post->post_status ) {
1445              case 'publish' :
1446              case 'private' :
1447                  $stat = __('Published');
1448                  break;
1449              case 'future' :
1450                  $stat = __('Scheduled');
1451                  break;
1452              case 'pending' :
1453                  $stat = __('Pending Review');
1454                  break;
1455              case 'draft' :
1456                  $stat = __('Draft');
1457                  break;
1458          }
1459  
1460          if ( '0000-00-00 00:00:00' == $post->post_date ) {
1461              $time = '';
1462          } else {
1463              /* translators: date format in table columns, see http://php.net/date */
1464              $time = mysql2date(__('Y/m/d'), $post->post_date);
1465          }
1466  
1467          $html .= '<tr class="found-posts"><td class="found-radio"><input type="radio" id="found-'.$post->ID.'" name="found_post_id" value="' . esc_attr($post->ID) . '"></td>';
1468          $html .= '<td><label for="found-'.$post->ID.'">' . esc_html( $title ) . '</label></td><td class="no-break">' . esc_html( $post_types[$post->post_type]->labels->singular_name ) . '</td><td class="no-break">'.esc_html( $time ) . '</td><td class="no-break">' . esc_html( $stat ). ' </td></tr>' . "\n\n";
1469      }
1470  
1471      $html .= '</tbody></table>';
1472  
1473      $x = new WP_Ajax_Response();
1474      $x->add( array(
1475          'data' => $html
1476      ));
1477      $x->send();
1478  }
1479  
1480  function wp_ajax_widgets_order() {
1481      check_ajax_referer( 'save-sidebar-widgets', 'savewidgets' );
1482  
1483      if ( !current_user_can('edit_theme_options') )
1484          wp_die( -1 );
1485  
1486      unset( $_POST['savewidgets'], $_POST['action'] );
1487  
1488      // save widgets order for all sidebars
1489      if ( is_array($_POST['sidebars']) ) {
1490          $sidebars = array();
1491          foreach ( $_POST['sidebars'] as $key => $val ) {
1492              $sb = array();
1493              if ( !empty($val) ) {
1494                  $val = explode(',', $val);
1495                  foreach ( $val as $k => $v ) {
1496                      if ( strpos($v, 'widget-') === false )
1497                          continue;
1498  
1499                      $sb[$k] = substr($v, strpos($v, '_') + 1);
1500                  }
1501              }
1502              $sidebars[$key] = $sb;
1503          }
1504          wp_set_sidebars_widgets($sidebars);
1505          wp_die( 1 );
1506      }
1507  
1508      wp_die( -1 );
1509  }
1510  
1511  function wp_ajax_save_widget() {
1512      global $wp_registered_widgets, $wp_registered_widget_controls, $wp_registered_widget_updates;
1513  
1514      check_ajax_referer( 'save-sidebar-widgets', 'savewidgets' );
1515  
1516      if ( !current_user_can('edit_theme_options') || !isset($_POST['id_base']) )
1517          wp_die( -1 );
1518  
1519      unset( $_POST['savewidgets'], $_POST['action'] );
1520  
1521      do_action('load-widgets.php');
1522      do_action('widgets.php');
1523      do_action('sidebar_admin_setup');
1524  
1525      $id_base = $_POST['id_base'];
1526      $widget_id = $_POST['widget-id'];
1527      $sidebar_id = $_POST['sidebar'];
1528      $multi_number = !empty($_POST['multi_number']) ? (int) $_POST['multi_number'] : 0;
1529      $settings = isset($_POST['widget-' . $id_base]) && is_array($_POST['widget-' . $id_base]) ? $_POST['widget-' . $id_base] : false;
1530      $error = '<p>' . __('An error has occurred. Please reload the page and try again.') . '</p>';
1531  
1532      $sidebars = wp_get_sidebars_widgets();
1533      $sidebar = isset($sidebars[$sidebar_id]) ? $sidebars[$sidebar_id] : array();
1534  
1535      // delete
1536      if ( isset($_POST['delete_widget']) && $_POST['delete_widget'] ) {
1537  
1538          if ( !isset($wp_registered_widgets[$widget_id]) )
1539              wp_die( $error );
1540  
1541          $sidebar = array_diff( $sidebar, array($widget_id) );
1542          $_POST = array('sidebar' => $sidebar_id, 'widget-' . $id_base => array(), 'the-widget-id' => $widget_id, 'delete_widget' => '1');
1543      } elseif ( $settings && preg_match( '/__i__|%i%/', key($settings) ) ) {
1544          if ( !$multi_number )
1545              wp_die( $error );
1546  
1547          $_POST['widget-' . $id_base] = array( $multi_number => array_shift($settings) );
1548          $widget_id = $id_base . '-' . $multi_number;
1549          $sidebar[] = $widget_id;
1550      }
1551      $_POST['widget-id'] = $sidebar;
1552  
1553      foreach ( (array) $wp_registered_widget_updates as $name => $control ) {
1554  
1555          if ( $name == $id_base ) {
1556              if ( !is_callable( $control['callback'] ) )
1557                  continue;
1558  
1559              ob_start();
1560                  call_user_func_array( $control['callback'], $control['params'] );
1561              ob_end_clean();
1562              break;
1563          }
1564      }
1565  
1566      if ( isset($_POST['delete_widget']) && $_POST['delete_widget'] ) {
1567          $sidebars[$sidebar_id] = $sidebar;
1568          wp_set_sidebars_widgets($sidebars);
1569          echo "deleted:$widget_id";
1570          wp_die();
1571      }
1572  
1573      if ( !empty($_POST['add_new']) )
1574          wp_die();
1575  
1576      if ( $form = $wp_registered_widget_controls[$widget_id] )
1577          call_user_func_array( $form['callback'], $form['params'] );
1578  
1579      wp_die();
1580  }
1581  
1582  function wp_ajax_upload_attachment() {
1583      check_ajax_referer( 'media-form' );
1584  
1585      if ( ! current_user_can( 'upload_files' ) )
1586          wp_die();
1587  
1588      if ( isset( $_REQUEST['post_id'] ) ) {
1589          $post_id = $_REQUEST['post_id'];
1590          if ( ! current_user_can( 'edit_post', $post_id ) )
1591              wp_die();
1592      } else {
1593          $post_id = null;
1594      }
1595  
1596      $post_data = isset( $_REQUEST['post_data'] ) ? $_REQUEST['post_data'] : array();
1597  
1598      // If the context is custom header or background, make sure the uploaded file is an image.
1599      if ( isset( $post_data['context'] ) && in_array( $post_data['context'], array( 'custom-header', 'custom-background' ) ) ) {
1600          $wp_filetype = wp_check_filetype_and_ext( $_FILES['async-upload']['tmp_name'], $_FILES['async-upload']['name'], false );
1601          if ( ! wp_match_mime_types( 'image', $wp_filetype['type'] ) ) {
1602              echo json_encode( array(
1603                  'success' => false,
1604                  'data'    => array(
1605                      'message'  => __( 'The uploaded file is not a valid image. Please try again.' ),
1606                      'filename' => $_FILES['async-upload']['name'],
1607                  )
1608              ) );
1609  
1610              wp_die();
1611          }
1612      }
1613  
1614      $attachment_id = media_handle_upload( 'async-upload', $post_id, $post_data );
1615  
1616      if ( is_wp_error( $attachment_id ) ) {
1617          echo json_encode( array(
1618              'success' => false,
1619              'data'    => array(
1620                  'message'  => $attachment_id->get_error_message(),
1621                  'filename' => $_FILES['async-upload']['name'],
1622              )
1623          ) );
1624  
1625          wp_die();
1626      }
1627  
1628      if ( isset( $post_data['context'] ) && isset( $post_data['theme'] ) ) {
1629          if ( 'custom-background' === $post_data['context'] )
1630              update_post_meta( $attachment_id, '_wp_attachment_is_custom_background', $post_data['theme'] );
1631  
1632          if ( 'custom-header' === $post_data['context'] )
1633              update_post_meta( $attachment_id, '_wp_attachment_is_custom_header', $post_data['theme'] );
1634      }
1635  
1636      if ( ! $attachment = wp_prepare_attachment_for_js( $attachment_id ) )
1637          wp_die();
1638  
1639      echo json_encode( array(
1640          'success' => true,
1641          'data'    => $attachment,
1642      ) );
1643  
1644      wp_die();
1645  }
1646  
1647  function wp_ajax_image_editor() {
1648      $attachment_id = intval($_POST['postid']);
1649      if ( empty($attachment_id) || !current_user_can('edit_post', $attachment_id) )
1650          wp_die( -1 );
1651  
1652      check_ajax_referer( "image_editor-$attachment_id" );
1653      include_once ( ABSPATH . 'wp-admin/includes/image-edit.php' );
1654  
1655      $msg = false;
1656      switch ( $_POST['do'] ) {
1657          case 'save' :
1658              $msg = wp_save_image($attachment_id);
1659              $msg = json_encode($msg);
1660              wp_die( $msg );
1661              break;
1662          case 'scale' :
1663              $msg = wp_save_image($attachment_id);
1664              break;
1665          case 'restore' :
1666              $msg = wp_restore_image($attachment_id);
1667              break;
1668      }
1669  
1670      wp_image_editor($attachment_id, $msg);
1671      wp_die();
1672  }
1673  
1674  function wp_ajax_set_post_thumbnail() {
1675      $json = ! empty( $_REQUEST['json'] ); // New-style request
1676  
1677      $post_ID = intval( $_POST['post_id'] );
1678      if ( ! current_user_can( 'edit_post', $post_ID ) )
1679          wp_die( -1 );
1680  
1681      $thumbnail_id = intval( $_POST['thumbnail_id'] );
1682  
1683      if ( $json )
1684          check_ajax_referer( "update-post_$post_ID" );
1685      else
1686          check_ajax_referer( "set_post_thumbnail-$post_ID" );
1687  
1688      if ( $thumbnail_id == '-1' ) {
1689          if ( delete_post_thumbnail( $post_ID ) ) {
1690              $return = _wp_post_thumbnail_html( null, $post_ID );
1691              $json ? wp_send_json_success( $return ) : wp_die( $return );
1692          } else {
1693              wp_die( 0 );
1694          }
1695      }
1696  
1697      if ( set_post_thumbnail( $post_ID, $thumbnail_id ) ) {
1698          $return = _wp_post_thumbnail_html( $thumbnail_id, $post_ID );
1699          $json ? wp_send_json_success( $return ) : wp_die( $return );
1700      }
1701  
1702      wp_die( 0 );
1703  }
1704  
1705  function wp_ajax_date_format() {
1706      wp_die( date_i18n( sanitize_option( 'date_format', $_POST['date'] ) ) );
1707  }
1708  
1709  function wp_ajax_time_format() {
1710      wp_die( date_i18n( sanitize_option( 'time_format', $_POST['date'] ) ) );
1711  }
1712  
1713  function wp_ajax_wp_fullscreen_save_post() {
1714      $post_id = isset( $_POST['post_ID'] ) ? (int) $_POST['post_ID'] : 0;
1715  
1716      $post = $post_type = null;
1717  
1718      if ( $post_id )
1719          $post = get_post( $post_id );
1720  
1721      if ( $post )
1722          $post_type = $post->post_type;
1723      elseif ( isset( $_POST['post_type'] ) && post_type_exists( $_POST['post_type'] ) )
1724          $post_type = $_POST['post_type'];
1725  
1726      check_ajax_referer('update-post_' . $post_id, '_wpnonce');
1727  
1728      $post_id = edit_post();
1729  
1730      if ( is_wp_error($post_id) ) {
1731          if ( $post_id->get_error_message() )
1732              $message = $post_id->get_error_message();
1733          else
1734              $message = __('Save failed');
1735  
1736          echo json_encode( array( 'message' => $message, 'last_edited' => '' ) );
1737          wp_die();
1738      } else {
1739          $message = __('Saved.');
1740      }
1741  
1742      if ( $post ) {
1743          $last_date = mysql2date( get_option('date_format'), $post->post_modified );
1744          $last_time = mysql2date( get_option('time_format'), $post->post_modified );
1745      } else {
1746          $last_date = date_i18n( get_option('date_format') );
1747          $last_time = date_i18n( get_option('time_format') );
1748      }
1749  
1750      if ( $last_id = get_post_meta($post_id, '_edit_last', true) ) {
1751          $last_user = get_userdata($last_id);
1752          $last_edited = sprintf( __('Last edited by %1$s on %2$s at %3$s'), esc_html( $last_user->display_name ), $last_date, $last_time );
1753      } else {
1754          $last_edited = sprintf( __('Last edited on %1$s at %2$s'), $last_date, $last_time );
1755      }
1756  
1757      echo json_encode( array( 'message' => $message, 'last_edited' => $last_edited ) );
1758      wp_die();
1759  }
1760  
1761  function wp_ajax_wp_remove_post_lock() {
1762      if ( empty( $_POST['post_ID'] ) || empty( $_POST['active_post_lock'] ) )
1763          wp_die( 0 );
1764      $post_id = (int) $_POST['post_ID'];
1765      if ( ! $post = get_post( $post_id ) )
1766          wp_die( 0 );
1767  
1768      check_ajax_referer( 'update-post_' . $post_id );
1769  
1770      if ( ! current_user_can( 'edit_post', $post_id ) )
1771          wp_die( -1 );
1772  
1773      $active_lock = array_map( 'absint', explode( ':', $_POST['active_post_lock'] ) );
1774      if ( $active_lock[1] != get_current_user_id() )
1775          wp_die( 0 );
1776  
1777      $new_lock = ( time() - apply_filters( 'wp_check_post_lock_window', 120 ) + 5 ) . ':' . $active_lock[1];
1778      update_post_meta( $post_id, '_edit_lock', $new_lock, implode( ':', $active_lock ) );
1779      wp_die( 1 );
1780  }
1781  
1782  function wp_ajax_dismiss_wp_pointer() {
1783      $pointer = $_POST['pointer'];
1784      if ( $pointer != sanitize_key( $pointer ) )
1785          wp_die( 0 );
1786  
1787  //    check_ajax_referer( 'dismiss-pointer_' . $pointer );
1788  
1789      $dismissed = array_filter( explode( ',', (string) get_user_meta( get_current_user_id(), 'dismissed_wp_pointers', true ) ) );
1790  
1791      if ( in_array( $pointer, $dismissed ) )
1792          wp_die( 0 );
1793  
1794      $dismissed[] = $pointer;
1795      $dismissed = implode( ',', $dismissed );
1796  
1797      update_user_meta( get_current_user_id(), 'dismissed_wp_pointers', $dismissed );
1798      wp_die( 1 );
1799  }
1800  
1801  /**
1802   * Get an attachment.
1803   *
1804   * @since 3.5.0
1805   */
1806  function wp_ajax_get_attachment() {
1807      if ( ! isset( $_REQUEST['id'] ) )
1808          wp_send_json_error();
1809  
1810      if ( ! $id = absint( $_REQUEST['id'] ) )
1811          wp_send_json_error();
1812  
1813      if ( ! $post = get_post( $id ) )
1814          wp_send_json_error();
1815  
1816      if ( 'attachment' != $post->post_type )
1817          wp_send_json_error();
1818  
1819      if ( ! current_user_can( 'upload_files' ) )
1820          wp_send_json_error();
1821  
1822      if ( ! $attachment = wp_prepare_attachment_for_js( $id ) )
1823          wp_send_json_error();
1824  
1825      wp_send_json_success( $attachment );
1826  }
1827  
1828  /**
1829   * Query for attachments.
1830   *
1831   * @since 3.5.0
1832   */
1833  function wp_ajax_query_attachments() {
1834      if ( ! current_user_can( 'upload_files' ) )
1835          wp_send_json_error();
1836  
1837      $query = isset( $_REQUEST['query'] ) ? (array) $_REQUEST['query'] : array();
1838      $query = array_intersect_key( $query, array_flip( array(
1839          's', 'order', 'orderby', 'posts_per_page', 'paged', 'post_mime_type',
1840          'post_parent', 'post__in', 'post__not_in',
1841      ) ) );
1842  
1843      $query['post_type'] = 'attachment';
1844      $query['post_status'] = 'inherit';
1845      if ( current_user_can( get_post_type_object( 'attachment' )->cap->read_private_posts ) )
1846          $query['post_status'] .= ',private';
1847  
1848      $query = new WP_Query( $query );
1849  
1850      $posts = array_map( 'wp_prepare_attachment_for_js', $query->posts );
1851      $posts = array_filter( $posts );
1852  
1853      wp_send_json_success( $posts );
1854  }
1855  
1856  /**
1857   * Save attachment attributes.
1858   *
1859   * @since 3.5.0
1860   */
1861  function wp_ajax_save_attachment() {
1862      if ( ! isset( $_REQUEST['id'] ) || ! isset( $_REQUEST['changes'] ) )
1863          wp_send_json_error();
1864  
1865      if ( ! $id = absint( $_REQUEST['id'] ) )
1866          wp_send_json_error();
1867  
1868      check_ajax_referer( 'update-post_' . $id, 'nonce' );
1869  
1870      if ( ! current_user_can( 'edit_post', $id ) )
1871          wp_send_json_error();
1872  
1873      $changes = $_REQUEST['changes'];
1874      $post    = get_post( $id, ARRAY_A );
1875  
1876      if ( 'attachment' != $post['post_type'] )
1877          wp_send_json_error();
1878  
1879      if ( isset( $changes['title'] ) )
1880          $post['post_title'] = $changes['title'];
1881  
1882      if ( isset( $changes['caption'] ) )
1883          $post['post_excerpt'] = $changes['caption'];
1884  
1885      if ( isset( $changes['description'] ) )
1886          $post['post_content'] = $changes['description'];
1887  
1888      if ( isset( $changes['alt'] ) ) {
1889          $alt = wp_unslash( $changes['alt'] );
1890          if ( $alt != get_post_meta( $id, '_wp_attachment_image_alt', true ) ) {
1891              $alt = wp_strip_all_tags( $alt, true );
1892              update_post_meta( $id, '_wp_attachment_image_alt', wp_slash( $alt ) );
1893          }
1894      }
1895  
1896      wp_update_post( $post );
1897      wp_send_json_success();
1898  }
1899  
1900  /**
1901   * Save backwards compatible attachment attributes.
1902   *
1903   * @since 3.5.0
1904   */
1905  function wp_ajax_save_attachment_compat() {
1906      if ( ! isset( $_REQUEST['id'] ) )
1907          wp_send_json_error();
1908  
1909      if ( ! $id = absint( $_REQUEST['id'] ) )
1910          wp_send_json_error();
1911  
1912      if ( empty( $_REQUEST['attachments'] ) || empty( $_REQUEST['attachments'][ $id ] ) )
1913          wp_send_json_error();
1914      $attachment_data = $_REQUEST['attachments'][ $id ];
1915  
1916      check_ajax_referer( 'update-post_' . $id, 'nonce' );
1917  
1918      if ( ! current_user_can( 'edit_post', $id ) )
1919          wp_send_json_error();
1920  
1921      $post = get_post( $id, ARRAY_A );
1922  
1923      if ( 'attachment' != $post['post_type'] )
1924          wp_send_json_error();
1925  
1926      $post = apply_filters( 'attachment_fields_to_save', $post, $attachment_data );
1927  
1928      if ( isset( $post['errors'] ) ) {
1929          $errors = $post['errors']; // @todo return me and display me!
1930          unset( $post['errors'] );
1931      }
1932  
1933      wp_update_post( $post );
1934  
1935      foreach ( get_attachment_taxonomies( $post ) as $taxonomy ) {
1936          if ( isset( $attachment_data[ $taxonomy ] ) )
1937              wp_set_object_terms( $id, array_map( 'trim', preg_split( '/,+/', $attachment_data[ $taxonomy ] ) ), $taxonomy, false );
1938      }
1939  
1940      if ( ! $attachment = wp_prepare_attachment_for_js( $id ) )
1941          wp_send_json_error();
1942  
1943      wp_send_json_success( $attachment );
1944  }
1945  
1946  function wp_ajax_save_attachment_order() {
1947      if ( ! isset( $_REQUEST['post_id'] ) )
1948          wp_send_json_error();
1949  
1950      if ( ! $post_id = absint( $_REQUEST['post_id'] ) )
1951          wp_send_json_error();
1952  
1953      if ( empty( $_REQUEST['attachments'] ) )
1954          wp_send_json_error();
1955  
1956      check_ajax_referer( 'update-post_' . $post_id, 'nonce' );
1957  
1958      $attachments = $_REQUEST['attachments'];
1959  
1960      if ( ! current_user_can( 'edit_post', $post_id ) )
1961          wp_send_json_error();
1962  
1963      $post = get_post( $post_id, ARRAY_A );
1964  
1965      foreach ( $attachments as $attachment_id => $menu_order ) {
1966          if ( ! current_user_can( 'edit_post', $attachment_id ) )
1967              continue;
1968          if ( ! $attachment = get_post( $attachment_id ) )
1969              continue;
1970          if ( 'attachment' != $attachment->post_type )
1971              continue;
1972  
1973          wp_update_post( array( 'ID' => $attachment_id, 'menu_order' => $menu_order ) );
1974      }
1975  
1976      wp_send_json_success();
1977  }
1978  
1979  /**
1980   * Generates the HTML to send an attachment to the editor.
1981   * Backwards compatible with the media_send_to_editor filter and the chain
1982   * of filters that follow.
1983   *
1984   * @since 3.5.0
1985   */
1986  function wp_ajax_send_attachment_to_editor() {
1987      check_ajax_referer( 'media-send-to-editor', 'nonce' );
1988  
1989      $attachment = wp_unslash( $_POST['attachment'] );
1990  
1991      $id = intval( $attachment['id'] );
1992  
1993      if ( ! $post = get_post( $id ) )
1994          wp_send_json_error();
1995  
1996      if ( 'attachment' != $post->post_type )
1997          wp_send_json_error();
1998  
1999      if ( current_user_can( 'edit_post', $id ) ) {
2000          // If this attachment is unattached, attach it. Primarily a back compat thing.
2001          if ( 0 == $post->post_parent && $insert_into_post_id = intval( $_POST['post_id'] ) ) {
2002              wp_update_post( array( 'ID' => $id, 'post_parent' => $insert_into_post_id ) );
2003          }
2004      }
2005  
2006      $rel = $url = '';
2007      $html = $title = isset( $attachment['post_title'] ) ? $attachment['post_title'] : '';
2008      if ( ! empty( $attachment['url'] ) ) {
2009          $url = $attachment['url'];
2010          if ( strpos( $url, 'attachment_id') || get_attachment_link( $id ) == $url )
2011              $rel = ' rel="attachment wp-att-' . $id . '"';
2012          $html = '<a href="' . esc_url( $url ) . '"' . $rel . '>' . $html . '</a>';
2013      }
2014  
2015      remove_filter( 'media_send_to_editor', 'image_media_send_to_editor' );
2016  
2017      if ( 'image' === substr( $post->post_mime_type, 0, 5 ) ) {
2018          $align = isset( $attachment['align'] ) ? $attachment['align'] : 'none';
2019          $size = isset( $attachment['image-size'] ) ? $attachment['image-size'] : 'medium';
2020          $alt = isset( $attachment['image_alt'] ) ? $attachment['image_alt'] : '';
2021          $caption = isset( $attachment['post_excerpt'] ) ? $attachment['post_excerpt'] : '';
2022          $title = ''; // We no longer insert title tags into <img> tags, as they are redundant.
2023          $html = get_image_send_to_editor( $id, $caption, $title, $align, $url, (bool) $rel, $size, $alt );
2024      } elseif ( 'video' === substr( $post->post_mime_type, 0, 5 ) || 'audio' === substr( $post->post_mime_type, 0, 5 )  ) {
2025          $html = stripslashes_deep( $_POST['html'] );
2026      }
2027  
2028      $html = apply_filters( 'media_send_to_editor', $html, $id, $attachment );
2029  
2030      wp_send_json_success( $html );
2031  }
2032  
2033  /**
2034   * Generates the HTML to send a non-image embed link to the editor.
2035   *
2036   * Backwards compatible with the following filters:
2037   * - file_send_to_editor_url
2038   * - audio_send_to_editor_url
2039   * - video_send_to_editor_url
2040   *
2041   * @since 3.5.0
2042   */
2043  function wp_ajax_send_link_to_editor() {
2044      check_ajax_referer( 'media-send-to-editor', 'nonce' );
2045  
2046      if ( ! $src = wp_unslash( $_POST['src'] ) )
2047          wp_send_json_error();
2048  
2049      if ( ! strpos( $src, '://' ) )
2050          $src = 'http://' . $src;
2051  
2052      if ( ! $src = esc_url_raw( $src ) )
2053          wp_send_json_error();
2054  
2055      if ( ! $title = trim( wp_unslash( $_POST['title'] ) ) )
2056          $title = wp_basename( $src );
2057  
2058      $html = '';
2059      if ( $title )
2060          $html = '<a href="' . esc_url( $src ) . '">' . $title . '</a>';
2061  
2062      // Figure out what filter to run:
2063      $type = 'file';
2064      if ( ( $ext = preg_replace( '/^.+?\.([^.]+)$/', '$1', $src ) ) && ( $ext_type = wp_ext2type( $ext ) )
2065          && ( 'audio' == $ext_type || 'video' == $ext_type ) )
2066              $type = $ext_type;
2067  
2068      $html = apply_filters( $type . '_send_to_editor_url', $html, $src, $title );
2069  
2070      wp_send_json_success( $html );
2071  }
2072  
2073  function wp_ajax_heartbeat() {
2074      check_ajax_referer( 'heartbeat-nonce', '_nonce' );
2075      $response = array();
2076  
2077      // screen_id is the same as $current_screen->id and the JS global 'pagenow'
2078      if ( ! empty($_POST['screenid']) )
2079          $screen_id = sanitize_key($_POST['screenid']);
2080      else
2081          $screen_id = 'site';
2082  
2083      if ( ! empty($_POST['data']) ) {
2084          $data = (array) $_POST['data'];
2085          // todo: how much to sanitize and preset and what to leave to be accessed from $data or $_POST..?
2086          $user = wp_get_current_user();
2087          $data['user_id'] = $user->exists() ? $user->ID : 0;
2088  
2089          // todo: separate filters: 'heartbeat_[action]' so we call different callbacks only when there is data for them,
2090          // or all callbacks listen to one filter and run when there is something for them in $data?
2091          $response = apply_filters( 'heartbeat_received', $response, $data, $screen_id );
2092      }
2093  
2094      $response = apply_filters( 'heartbeat_send', $response, $screen_id );
2095  
2096      // Allow the transport to be replaced with long-polling easily
2097      do_action( 'heartbeat_tick', $response, $screen_id );
2098  
2099      // send the current time acording to the server
2100      $response['servertime'] = time();
2101  
2102      wp_send_json($response);
2103  }
2104  
2105  function wp_ajax_revisions_data() {
2106      check_ajax_referer( 'revisions-ajax-nonce', 'nonce' );
2107  
2108      $compare_to = ! empty( $_GET['compare_to'] ) ? absint( $_GET['compare_to'] ) : 0;
2109      $show_autosaves = ! empty( $_GET['show_autosaves'] );
2110      $show_split_view = ! empty( $_GET['show_split_view'] );
2111      $post_id = ! empty( $_GET['post_id'] ) ? absint( $_GET['post_id'] ) : 0;
2112      $right_handle_at = ! empty( $_GET['right_handle_at'] ) ? (int) $_GET['right_handle_at'] : 0;
2113      $left_handle_at = ! empty( $_GET['left_handle_at'] ) ? (int) $_GET['left_handle_at'] : 0;
2114      $single_revision_id = ! empty( $_GET['single_revision_id'] ) ? absint( $_GET['single_revision_id'] ) : 0;
2115      $compare_two_mode = (bool) $post_id;
2116  
2117      $all_the_revisions = array();
2118      if ( ! $post_id )
2119          $post_id = $compare_to;
2120  
2121      if ( ! current_user_can( 'read_post', $post_id ) )
2122          continue;
2123  
2124      if ( ! $revisions = wp_get_post_revisions( $post_id ) )
2125          return;
2126  
2127      $left_revision = get_post( $compare_to );
2128  
2129      // single model fetch mode
2130      // return the diff of a single revision comparison
2131      if ( $single_revision_id ) {
2132          $right_revision = get_post( $single_revision_id );
2133  
2134          if ( ! $compare_to )
2135              $left_revision = get_post( $post_id );
2136  
2137          // make sure the right revision is the most recent, except on oldest revision
2138          if ( $compare_to && $right_revision->post_date < $left_revision->post_date ) {
2139              $temp = $left_revision;
2140              $left_revision = $right_revision;
2141              $right_revision = $temp;
2142          }
2143  
2144          $lines_added = $lines_deleted = 0;
2145          $content = '';
2146          // compare from left to right, passed from application
2147          foreach ( _wp_post_revision_fields() as $field => $field_value ) {
2148              $left_content = apply_filters( "_wp_post_revision_field_$field", $left_revision->$field, $field, $left_revision, 'left' );
2149              $right_content = apply_filters( "_wp_post_revision_field_$field", $right_revision->$field, $field, $right_revision, 'right' );
2150  
2151              add_filter( "_wp_post_revision_field_$field", 'htmlspecialchars' );
2152  
2153              $args = array();
2154  
2155              if ( $show_split_view )
2156                   $args = array( 'show_split_view' => true );
2157  
2158              // compare_to == 0 means first revision, so compare to a blank field to show whats changed
2159              $diff = wp_text_diff_with_count( ( 0 == $compare_to ) ? '' : $left_content, $right_content, $args );
2160  
2161              if ( isset( $diff[ 'html' ] ) ) {
2162                  $content .= sprintf( '<div class="diff-label">%s</div>', $field_value );
2163                  $content .= $diff[ 'html' ];
2164              }
2165  
2166              if ( isset( $diff[ 'lines_added' ] ) )
2167                  $lines_added = $lines_added + $diff[ 'lines_added' ];
2168  
2169              if ( isset( $diff[ 'lines_deleted' ] ) )
2170                  $lines_deleted = $lines_deleted + $diff[ 'lines_deleted' ];
2171          }
2172          $content = '' == $content ? __( 'No difference' ) : $content;
2173  
2174          $all_the_revisions = array (
2175              'diff'         => $content,
2176              'linesDeleted' => $lines_deleted,
2177              'linesAdded'   => $lines_added
2178          );
2179  
2180          echo json_encode( $all_the_revisions );
2181          exit();
2182      } // end single model fetch
2183  
2184      $count = -1;
2185  
2186      // reverse the list to start with oldest revision
2187      $revisions = array_reverse( $revisions );
2188  
2189      $previous_revision_id = 0;
2190  
2191      /* translators: revision date format, see http://php.net/date */
2192      $datef = _x( 'j F, Y @ G:i:s', 'revision date format');
2193  
2194      foreach ( $revisions as $revision ) :
2195          if ( ! $show_autosaves && wp_is_post_autosave( $revision ) )
2196              continue;
2197  
2198          $revision_from_date_author = '';
2199          $is_current_revision = false;
2200          $count++;
2201  
2202          /**
2203          * return blank data for diffs to the left of the left handle (for right handel model)
2204          * or to the right of the right handle (for left handel model)
2205          * and visa versa in RTL mode
2206          */
2207          if( ! is_rtl() ) {
2208              if ( ( ( 0 != $left_handle_at && $count < $left_handle_at ) ||
2209                   ( 0 != $right_handle_at && $count > ( $right_handle_at - 2 ) ) ) ) {
2210                  $all_the_revisions[] = array (
2211                      'ID' => $revision->ID,
2212                  );
2213                  continue;
2214              }
2215          } else { // is_rtl
2216              if ( ( 0 != $left_handle_at && $count > ( $left_handle_at - 1 ) ||
2217                   ( 0 != $left_handle_at && $count < $right_handle_at ) ) ) {
2218                  $all_the_revisions[] = array (
2219                      'ID' => $revision->ID,
2220                  );
2221                  continue;
2222              }
2223          }
2224  
2225          if ( $compare_two_mode ) {
2226              $compare_to_gravatar = get_avatar( $left_revision->post_author, 24 );
2227              $compare_to_author = get_the_author_meta( 'display_name', $left_revision->post_author );
2228              $compare_to_date = date_i18n( $datef, strtotime( $left_revision->post_modified ) );
2229  
2230              $revision_from_date_author = sprintf(
2231                  /* translators: post revision title: 1: author avatar, 2: author name, 3: time ago, 4: date */
2232                  _x( '%1$s %2$s, %3$s ago (%4$s)', 'post revision title' ),
2233                  $compare_to_gravatar,
2234                  $compare_to_author,
2235                  human_time_diff( strtotime( $left_revision->post_modified ), current_time( 'timestamp' ) ),
2236                  $compare_to_date
2237              );
2238          }
2239  
2240          $gravatar = get_avatar( $revision->post_author, 24 );
2241          $author = get_the_author_meta( 'display_name', $revision->post_author );
2242          $date = date_i18n( $datef, strtotime( $revision->post_modified ) );
2243          $revision_date_author = sprintf(
2244              /* translators: post revision title: 1: author avatar, 2: author name, 3: time ago, 4: date */
2245              _x( '%1$s %2$s, %3$s ago (%4$s)', 'post revision title' ),
2246              $gravatar,
2247              $author,
2248              human_time_diff( strtotime( $revision->post_modified ), current_time( 'timestamp' ) ),
2249              $date
2250          );
2251  
2252          /* translators: 1: date */
2253          $autosavef = _x( '%1$s [Autosave]', 'post revision title extra' );
2254          /* translators: 1: date */
2255          $currentf  = _x( '%1$s [Current Revision]', 'post revision title extra' );
2256  
2257          if ( ! $post = get_post( $post_id ) )
2258              continue;
2259  
2260          if ( $left_revision->post_modified === $post->post_modified )
2261              $revision_from_date_author = sprintf( $currentf, $revision_from_date_author );
2262          elseif ( wp_is_post_autosave( $left_revision ) )
2263              $revision_from_date_author = sprintf( $autosavef, $revision_from_date_author );
2264  
2265          if ( $revision->post_modified === $post->post_modified ) {
2266              $revision_date_author = sprintf( $currentf, $revision_date_author );
2267              $is_current_revision = true;
2268          } elseif ( wp_is_post_autosave( $revision ) ) {
2269              $revision_date_author = sprintf( $autosavef, $revision_date_author );
2270          }
2271  
2272          /* translators: revision date short format, see http://php.net/date */
2273          $date_short_format = _x( 'j M @ G:i', 'revision date short format');
2274          $date_short = date_i18n( $date_short_format, strtotime( $revision->post_modified ) );
2275  
2276          $revision_date_author_short = sprintf(
2277              '%s <strong>%s</strong><br />%s',
2278              $gravatar,
2279              $author,
2280              $date_short
2281          );
2282  
2283          $restore_link = wp_nonce_url(
2284              add_query_arg(
2285                  array( 'revision' => $revision->ID,
2286                      'action' => 'restore' ),
2287                      admin_url( 'revision.php' )
2288              ),
2289              "restore-post_{$revision->ID}"
2290          );
2291  
2292          // if this is a left handled calculation swap data
2293          if ( 0 != $right_handle_at ) {
2294              $tmp = $revision_from_date_author;
2295              $revision_from_date_author = $revision_date_author;
2296              $revision_date_author = $tmp;
2297          }
2298  
2299          if ( ( $compare_two_mode || -1 !== $previous_revision_id ) ) {
2300              $all_the_revisions[] = array (
2301                  'ID'           => $revision->ID,
2302                  'titleTo'      => $revision_date_author,
2303                  'titleFrom'    => $revision_from_date_author,
2304                  'titleTooltip' => $revision_date_author_short,
2305                  'restoreLink'  => urldecode( $restore_link ),
2306                  'previousID'   => $previous_revision_id,
2307                  'isCurrent'    => $is_current_revision,
2308              );
2309          }
2310          $previous_revision_id = $revision->ID;
2311  
2312      endforeach;
2313  
2314      // in RTL + single handle mode, reverse the revision direction
2315      if ( is_rtl() && $compare_two_mode )
2316          $all_the_revisions = array_reverse( $all_the_revisions );
2317  
2318      echo json_encode( $all_the_revisions );
2319      exit();
2320  }


Generated: Tue May 21 03:56:26 2013 Hosted by follow the white rabbit.