+
+/**
+ * Heartbeat API (experimental)
+ *
+ * Runs when the user is logged in.
+ */
+function wp_ajax_heartbeat() {
+ if ( empty( $_POST['_nonce'] ) )
+ wp_send_json_error();
+
+ $response = array();
+
+ if ( false === wp_verify_nonce( $_POST['_nonce'], 'heartbeat-nonce' ) ) {
+ // User is logged in but nonces have expired.
+ $response['nonces_expired'] = true;
+ wp_send_json($response);
+ }
+
+ // screen_id is the same as $current_screen->id and the JS global 'pagenow'
+ if ( ! empty($_POST['screen_id']) )
+ $screen_id = sanitize_key($_POST['screen_id']);
+ else
+ $screen_id = 'front';
+
+ if ( ! empty($_POST['data']) ) {
+ $data = (array) $_POST['data'];
+ $response = apply_filters( 'heartbeat_received', $response, $data, $screen_id );
+ }
+
+ $response = apply_filters( 'heartbeat_send', $response, $screen_id );
+
+ // Allow the transport to be replaced with long-polling easily
+ do_action( 'heartbeat_tick', $response, $screen_id );
+
+ // Send the current time according to the server
+ $response['server_time'] = time();
+
+ wp_send_json($response);
+}
+
+function wp_ajax_get_revision_diffs() {
+ require ABSPATH . 'wp-admin/includes/revision.php';
+
+ if ( ! $post = get_post( (int) $_REQUEST['post_id'] ) )
+ wp_send_json_error();
+
+ if ( ! current_user_can( 'read_post', $post->ID ) )
+ wp_send_json_error();
+
+ // Really just pre-loading the cache here.
+ if ( ! $revisions = wp_get_post_revisions( $post->ID, array( 'check_enabled' => false ) ) )
+ wp_send_json_error();
+
+ $return = array();
+ @set_time_limit( 0 );
+
+ foreach ( $_REQUEST['compare'] as $compare_key ) {
+ list( $compare_from, $compare_to ) = explode( ':', $compare_key ); // from:to
+
+ $return[] = array(
+ 'id' => $compare_key,
+ 'fields' => wp_get_revision_ui_diff( $post, $compare_from, $compare_to ),
+ );
+ }
+ wp_send_json_success( $return );
+}