X-Git-Url: https://scripts.mit.edu/gitweb/autoinstalls/wordpress.git/blobdiff_plain/0461a5f2e55c8d5f1fde96ca2e83117152573c7d..9e77185fafaf4e60e2b73821e0e4b9b1a11fb85f:/wp-admin/includes/ajax-actions.php?ds=sidebyside diff --git a/wp-admin/includes/ajax-actions.php b/wp-admin/includes/ajax-actions.php index ed78e3c0..ff2db70f 100644 --- a/wp-admin/includes/ajax-actions.php +++ b/wp-admin/includes/ajax-actions.php @@ -6,19 +6,22 @@ * @subpackage Administration */ -/* - * No-privilege Ajax handlers. - */ +// +// No-privilege Ajax handlers. +// /** - * Heartbeat API (experimental) + * Ajax handler for the Heartbeat API in + * the no-privilege context. * * Runs when the user is not logged in. + * + * @since 3.6.0 */ function wp_ajax_nopriv_heartbeat() { $response = array(); - // screen_id is the same as $current_screen->id and the JS global 'pagenow' + // 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 @@ -61,14 +64,20 @@ function wp_ajax_nopriv_heartbeat() { */ do_action( 'heartbeat_nopriv_tick', $response, $screen_id ); - // send the current time according to the server + // Send the current time according to the server. $response['server_time'] = time(); wp_send_json($response); } -/* - * GET-based Ajax handlers. +// +// GET-based Ajax handlers. +// + +/** + * Ajax handler for fetching a list table. + * + * @since 3.1.0 */ function wp_ajax_fetch_list() { global $wp_list_table; @@ -87,9 +96,13 @@ function wp_ajax_fetch_list() { wp_die( 0 ); } -function wp_ajax_ajax_tag_search() { - global $wpdb; +/** + * Ajax handler for tag search. + * + * @since 3.1.0 + */ +function wp_ajax_ajax_tag_search() { if ( isset( $_GET['tax'] ) ) { $taxonomy = sanitize_key( $_GET['tax'] ); $tax = get_taxonomy( $taxonomy ); @@ -111,8 +124,25 @@ function wp_ajax_ajax_tag_search() { $s = $s[count( $s ) - 1]; } $s = trim( $s ); - if ( strlen( $s ) < 2 ) - wp_die(); // require 2 chars for matching + + /** + * Filter the minimum number of characters required to fire a tag search via AJAX. + * + * @since 4.0.0 + * + * @param int $characters The minimum number of characters required. Default 2. + * @param object $tax The taxonomy object. + * @param string $s The search term. + */ + $term_search_min_chars = (int) apply_filters( 'term_search_min_chars', 2, $tax, $s ); + + /* + * Require $term_search_min_chars chars for matching (default: 2) + * ensure it's a non-negative, non-zero integer. + */ + if ( ( $term_search_min_chars == 0 ) || ( strlen( $s ) < $term_search_min_chars ) ){ + wp_die(); + } $results = get_terms( $taxonomy, array( 'name__like' => $s, 'fields' => 'names', 'hide_empty' => false ) ); @@ -120,6 +150,11 @@ function wp_ajax_ajax_tag_search() { wp_die(); } +/** + * Ajax handler for compression testing. + * + * @since 3.1.0 + */ function wp_ajax_wp_compression_test() { if ( !current_user_can( 'manage_options' ) ) wp_die( -1 ); @@ -165,6 +200,11 @@ function wp_ajax_wp_compression_test() { wp_die( 0 ); } +/** + * Ajax handler for image editor previews. + * + * @since 3.1.0 + */ function wp_ajax_imgedit_preview() { $post_id = intval($_GET['postid']); if ( empty($post_id) || !current_user_can('edit_post', $post_id) ) @@ -179,13 +219,21 @@ function wp_ajax_imgedit_preview() { wp_die(); } +/** + * Ajax handler for oEmbed caching. + * + * @since 3.1.0 + */ function wp_ajax_oembed_cache() { - global $wp_embed; - - $return = ( $wp_embed->cache_oembed( $_GET['post'] ) ) ? '1' : '0'; - wp_die( $return ); + $GLOBALS['wp_embed']->cache_oembed( $_GET['post'] ); + wp_die( 0 ); } +/** + * Ajax handler for user autocomplete. + * + * @since 3.4.0 + */ function wp_ajax_autocomplete_user() { if ( ! is_multisite() || ! current_user_can( 'promote_users' ) || wp_is_large_network( 'users' ) ) wp_die( -1 ); @@ -241,6 +289,11 @@ function wp_ajax_autocomplete_user() { wp_die( json_encode( $return ) ); } +/** + * Ajax handler for dashboard widgets. + * + * @since 3.4.0 + */ function wp_ajax_dashboard_widgets() { require_once ABSPATH . 'wp-admin/includes/dashboard.php'; @@ -257,13 +310,18 @@ function wp_ajax_dashboard_widgets() { wp_die(); } +/** + * Ajax handler for Customizer preview logged-in status. + * + * @since 3.4.0 + */ function wp_ajax_logged_in() { wp_die( 1 ); } -/* - * Ajax helper. - */ +// +// Ajax helpers. +// /** * Sends back current comment total and new page links if they need to be updated. @@ -304,16 +362,19 @@ function _wp_ajax_delete_comment_response( $comment_id, $delta = -1 ) { $comment_count = wp_count_comments($post_id); - if ( isset( $comment_count->$status ) ) // We're looking for a known type of comment count + // We're looking for a known type of comment count. + if ( isset( $comment_count->$status ) ) $total = $comment_count->$status; - // else use the decremented value from above + // Else use the decremented value from above. } - $time = time(); // The time since the last comment count + // The time since the last comment count. + $time = time(); $x = new WP_Ajax_Response( array( 'what' => 'comment', - 'id' => $comment_id, // here for completeness - not used + // Here for completeness - not used. + 'id' => $comment_id, 'supplemental' => array( 'total_items_i18n' => sprintf( _n( '1 item', '%s items', $total ), number_format_i18n( $total ) ), 'total_pages' => ceil( $total / $per_page ), @@ -325,10 +386,15 @@ function _wp_ajax_delete_comment_response( $comment_id, $delta = -1 ) { $x->send(); } -/* - * POST-based Ajax handlers. - */ +// +// POST-based Ajax handlers. +// +/** + * Ajax handler for adding a hierarchical term. + * + * @since 3.1.0 + */ function _wp_ajax_add_hierarchical_term() { $action = $_POST['action']; $taxonomy = get_taxonomy(substr($action, 4)); @@ -408,6 +474,11 @@ function _wp_ajax_add_hierarchical_term() { $x->send(); } +/** + * Ajax handler for deleting a comment. + * + * @since 3.1.0 + */ function wp_ajax_delete_comment() { $id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0; @@ -451,6 +522,11 @@ function wp_ajax_delete_comment() { wp_die( 0 ); } +/** + * Ajax handler for deleting a tag. + * + * @since 3.1.0 + */ function wp_ajax_delete_tag() { $tag_id = (int) $_POST['tag_ID']; check_ajax_referer( "delete-tag_$tag_id" ); @@ -471,6 +547,11 @@ function wp_ajax_delete_tag() { wp_die( 0 ); } +/** + * Ajax handler for deleting a link. + * + * @since 3.1.0 + */ function wp_ajax_delete_link() { $id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0; @@ -488,6 +569,11 @@ function wp_ajax_delete_link() { wp_die( 0 ); } +/** + * Ajax handler for deleting meta. + * + * @since 3.1.0 + */ function wp_ajax_delete_meta() { $id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0; @@ -502,6 +588,13 @@ function wp_ajax_delete_meta() { wp_die( 0 ); } +/** + * Ajax handler for deleting a post. + * + * @since 3.1.0 + * + * @param string $action Action to perform. + */ function wp_ajax_delete_post( $action ) { if ( empty( $action ) ) $action = 'delete-post'; @@ -520,6 +613,13 @@ function wp_ajax_delete_post( $action ) { wp_die( 0 ); } +/** + * Ajax handler for sending a post to the trash. + * + * @since 3.1.0 + * + * @param string $action Action to perform. + */ function wp_ajax_trash_post( $action ) { if ( empty( $action ) ) $action = 'trash-post'; @@ -543,6 +643,13 @@ function wp_ajax_trash_post( $action ) { wp_die( 0 ); } +/** + * Ajax handler to restore a post from the trash. + * + * @since 3.1.0 + * + * @param string $action Action to perform. + */ function wp_ajax_untrash_post( $action ) { if ( empty( $action ) ) $action = 'untrash-post'; @@ -567,6 +674,11 @@ function wp_ajax_delete_page( $action ) { wp_die( 0 ); } +/** + * Ajax handler to dim a comment. + * + * @since 3.1.0 + */ function wp_ajax_dim_comment() { $id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0; @@ -604,6 +716,13 @@ function wp_ajax_dim_comment() { wp_die( 0 ); } +/** + * Ajax handler for deleting a link category. + * + * @since 3.1.0 + * + * @param string $action Action to perform. + */ function wp_ajax_add_link_category( $action ) { if ( empty( $action ) ) $action = 'add-link-category'; @@ -634,11 +753,15 @@ function wp_ajax_add_link_category( $action ) { $x->send(); } +/** + * Ajax handler to add a tag. + * + * @since 3.1.0 + */ function wp_ajax_add_tag() { global $wp_list_table; check_ajax_referer( 'add-tag', '_wpnonce_add-tag' ); - $post_type = !empty($_POST['post_type']) ? $_POST['post_type'] : 'post'; $taxonomy = !empty($_POST['taxonomy']) ? $_POST['taxonomy'] : 'post_tag'; $tax = get_taxonomy($taxonomy); @@ -687,6 +810,11 @@ function wp_ajax_add_tag() { $x->send(); } +/** + * Ajax handler for getting a tagcloud. + * + * @since 3.1.0 + */ function wp_ajax_get_tagcloud() { if ( isset( $_POST['tax'] ) ) { $taxonomy = sanitize_key( $_POST['tax'] ); @@ -723,6 +851,13 @@ function wp_ajax_get_tagcloud() { wp_die(); } +/** + * Ajax handler for getting comments. + * + * @since 3.1.0 + * + * @param string $action Action to perform. + */ function wp_ajax_get_comments( $action ) { global $wp_list_table, $post_id; if ( empty( $action ) ) @@ -767,8 +902,15 @@ function wp_ajax_get_comments( $action ) { $x->send(); } +/** + * Ajax handler for replying to a comment. + * + * @since 3.1.0 + * + * @param string $action Action to perform. + */ function wp_ajax_replyto_comment( $action ) { - global $wp_list_table, $wpdb; + global $wp_list_table; if ( empty( $action ) ) $action = 'replyto-comment'; @@ -816,7 +958,7 @@ function wp_ajax_replyto_comment( $action ) { $comment_auto_approved = false; $commentdata = compact('comment_post_ID', 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content', 'comment_type', 'comment_parent', 'user_ID'); - // automatically approve parent comment + // Automatically approve parent comment. if ( !empty($_POST['approve_parent']) ) { $parent = get_comment( $comment_parent ); @@ -861,6 +1003,11 @@ function wp_ajax_replyto_comment( $action ) { $x->send(); } +/** + * Ajax handler for editing a comment. + * + * @since 3.1.0 + */ function wp_ajax_edit_comment() { global $wp_list_table; @@ -878,8 +1025,6 @@ function wp_ajax_edit_comment() { edit_comment(); $position = ( isset($_POST['position']) && (int) $_POST['position']) ? (int) $_POST['position'] : '-1'; - $comments_status = isset($_POST['comments_listing']) ? $_POST['comments_listing'] : ''; - $checkbox = ( isset($_POST['checkbox']) && true == $_POST['checkbox'] ) ? 1 : 0; $wp_list_table = _get_list_table( $checkbox ? 'WP_Comments_List_Table' : 'WP_Post_Comments_List_Table', array( 'screen' => 'edit-comments' ) ); @@ -903,6 +1048,11 @@ function wp_ajax_edit_comment() { $x->send(); } +/** + * Ajax handler for adding a menu item. + * + * @since 3.1.0 + */ function wp_ajax_add_menu_item() { check_ajax_referer( 'add-menu_item', 'menu-settings-column-nonce' ); @@ -956,14 +1106,7 @@ function wp_ajax_add_menu_item() { } } - /** - * Filter the Walker class used when adding nav menu items. - * - * @since 3.4.0 - * - * @param string $class The walker class to use. Default 'Walker_Nav_Menu_Edit'. - * @param int $menu_id The menu id, derived from $_POST['menu']. - */ + /** This filter is documented in wp-admin/includes/nav-menu.php */ $walker_class_name = apply_filters( 'wp_edit_nav_menu_walker', 'Walker_Nav_Menu_Edit', $_POST['menu'] ); if ( ! class_exists( $walker_class_name ) ) @@ -982,6 +1125,11 @@ function wp_ajax_add_menu_item() { wp_die(); } +/** + * Ajax handler for adding meta. + * + * @since 3.1.0 + */ function wp_ajax_add_meta() { check_ajax_referer( 'add-meta', '_ajax_nonce-add-meta' ); $c = 0; @@ -1065,6 +1213,13 @@ function wp_ajax_add_meta() { $x->send(); } +/** + * Ajax handler for adding a user. + * + * @since 3.1.0 + * + * @param string $action Action to perform. + */ function wp_ajax_add_user( $action ) { global $wp_list_table; if ( empty( $action ) ) @@ -1100,6 +1255,11 @@ function wp_ajax_add_user( $action ) { $x->send(); } +/** + * Ajax handler for closed post boxes. + * + * @since 3.1.0 + */ function wp_ajax_closed_postboxes() { check_ajax_referer( 'closedpostboxes', 'closedpostboxesnonce' ); $closed = isset( $_POST['closed'] ) ? explode( ',', $_POST['closed']) : array(); @@ -1127,10 +1287,14 @@ function wp_ajax_closed_postboxes() { wp_die( 1 ); } +/** + * Ajax handler for hidden columns. + * + * @since 3.1.0 + */ function wp_ajax_hidden_columns() { check_ajax_referer( 'screen-options-nonce', 'screenoptionnonce' ); - $hidden = isset( $_POST['hidden'] ) ? $_POST['hidden'] : ''; - $hidden = explode( ',', $_POST['hidden'] ); + $hidden = explode( ',', isset( $_POST['hidden'] ) ? $_POST['hidden'] : '' ); $page = isset( $_POST['page'] ) ? $_POST['page'] : ''; if ( $page != sanitize_key( $page ) ) @@ -1145,6 +1309,11 @@ function wp_ajax_hidden_columns() { wp_die( 1 ); } +/** + * Ajax handler for updating whether to display the welcome panel. + * + * @since 3.1.0 + */ function wp_ajax_update_welcome_panel() { check_ajax_referer( 'welcome-panel-nonce', 'welcomepanelnonce' ); @@ -1156,6 +1325,11 @@ function wp_ajax_update_welcome_panel() { wp_die( 1 ); } +/** + * Ajax handler for retrieving menu meta boxes. + * + * @since 3.1.0 + */ function wp_ajax_menu_get_metabox() { if ( ! current_user_can( 'edit_theme_options' ) ) wp_die( -1 ); @@ -1174,14 +1348,8 @@ function wp_ajax_menu_get_metabox() { if ( ! empty( $_POST['item-object'] ) && isset( $items[$_POST['item-object']] ) ) { $menus_meta_box_object = $items[ $_POST['item-object'] ]; - /** - * Filter a nav menu meta box object. - * - * @since 3.0.0 - * - * @param object $menus_meta_box_object A nav menu meta box object, such as Page, - * Post, Category, Tag, etc. - */ + + /** This filter is documented in wp-admin/includes/nav-menu.php */ $item = apply_filters( 'nav_menu_meta_box_object', $menus_meta_box_object ); ob_start(); call_user_func_array($callback, array( @@ -1205,6 +1373,11 @@ function wp_ajax_menu_get_metabox() { wp_die(); } +/** + * Ajax handler for internal linking. + * + * @since 3.1.0 + */ function wp_ajax_wp_link_ajax() { check_ajax_referer( 'internal-linking', '_ajax_linking_nonce' ); @@ -1226,6 +1399,11 @@ function wp_ajax_wp_link_ajax() { wp_die(); } +/** + * Ajax handler for menu locations save. + * + * @since 3.1.0 + */ function wp_ajax_menu_locations_save() { if ( ! current_user_can( 'edit_theme_options' ) ) wp_die( -1 ); @@ -1236,6 +1414,11 @@ function wp_ajax_menu_locations_save() { wp_die( 1 ); } +/** + * Ajax handler for saving the meta box order. + * + * @since 3.1.0 + */ function wp_ajax_meta_box_order() { check_ajax_referer( 'meta-box-order' ); $order = isset( $_POST['order'] ) ? (array) $_POST['order'] : false; @@ -1261,6 +1444,11 @@ function wp_ajax_meta_box_order() { wp_die( 1 ); } +/** + * Ajax handler for menu quick searching. + * + * @since 3.1.0 + */ function wp_ajax_menu_quick_search() { if ( ! current_user_can( 'edit_theme_options' ) ) wp_die( -1 ); @@ -1272,12 +1460,22 @@ function wp_ajax_menu_quick_search() { wp_die(); } +/** + * Ajax handler to retrieve a permalink. + * + * @since 3.1.0 + */ function wp_ajax_get_permalink() { check_ajax_referer( 'getpermalink', 'getpermalinknonce' ); $post_id = isset($_POST['post_id'])? intval($_POST['post_id']) : 0; wp_die( add_query_arg( array( 'preview' => 'true' ), get_permalink( $post_id ) ) ); } +/** + * Ajax handler to retrieve a sample permalink. + * + * @since 3.1.0 + */ function wp_ajax_sample_permalink() { check_ajax_referer( 'samplepermalink', 'samplepermalinknonce' ); $post_id = isset($_POST['post_id'])? intval($_POST['post_id']) : 0; @@ -1286,6 +1484,11 @@ function wp_ajax_sample_permalink() { wp_die( get_sample_permalink_html( $post_id, $title, $slug ) ); } +/** + * Ajax handler for quick edit saving for a post. + * + * @since 3.1.0 + */ function wp_ajax_inline_save() { global $wp_list_table; @@ -1312,18 +1515,20 @@ function wp_ajax_inline_save() { $data = &$_POST; $post = get_post( $post_ID, ARRAY_A ); - $post = wp_slash($post); //since it is from db + + // Since it's coming from the database. + $post = wp_slash($post); $data['content'] = $post['post_content']; $data['excerpt'] = $post['post_excerpt']; - // rename + // Rename. $data['user_ID'] = get_current_user_id(); if ( isset($data['post_parent']) ) $data['parent_id'] = $data['post_parent']; - // status + // Status. if ( isset($data['keep_private']) && 'private' == $data['keep_private'] ) $data['post_status'] = 'private'; else @@ -1340,13 +1545,11 @@ function wp_ajax_inline_save() { $data['post_name'] = wp_unique_post_slug( $data['post_name'], $post['ID'], $post['post_status'], $post['post_type'], $post['post_parent'] ); } - // update the post + // Update the post. edit_post(); $wp_list_table = _get_list_table( 'WP_Posts_List_Table', array( 'screen' => $_POST['screen'] ) ); - $mode = $_POST['post_view']; - $level = 0; $request_post = array( get_post( $_POST['post_ID'] ) ); $parent = $request_post[0]->post_parent; @@ -1362,6 +1565,11 @@ function wp_ajax_inline_save() { wp_die(); } +/** + * Ajax handler for quick edit saving for a term. + * + * @since 3.1.0 + */ function wp_ajax_inline_save_tax() { global $wp_list_table; @@ -1407,16 +1615,18 @@ function wp_ajax_inline_save_tax() { wp_die(); } +/** + * Ajax handler for finding posts. + * + * @since 3.1.0 + */ function wp_ajax_find_posts() { - global $wpdb; - check_ajax_referer( 'find-posts' ); $post_types = get_post_types( array( 'public' => true ), 'objects' ); unset( $post_types['attachment'] ); $s = wp_unslash( $_POST['ps'] ); - $searchand = $search = ''; $args = array( 'post_type' => array_keys( $post_types ), 'post_status' => 'any', @@ -1427,8 +1637,9 @@ function wp_ajax_find_posts() { $posts = get_posts( $args ); - if ( ! $posts ) - wp_die( __('No items found.') ); + if ( ! $posts ) { + wp_send_json_error( __( 'No items found.' ) ); + } $html = ''; $alt = ''; @@ -1468,6 +1679,11 @@ function wp_ajax_find_posts() { wp_send_json_success( $html ); } +/** + * Ajax handler for saving the widgets order. + * + * @since 3.1.0 + */ function wp_ajax_widgets_order() { check_ajax_referer( 'save-sidebar-widgets', 'savewidgets' ); @@ -1476,7 +1692,7 @@ function wp_ajax_widgets_order() { unset( $_POST['savewidgets'], $_POST['action'] ); - // save widgets order for all sidebars + // Save widgets order for all sidebars. if ( is_array($_POST['sidebars']) ) { $sidebars = array(); foreach ( $_POST['sidebars'] as $key => $val ) { @@ -1499,6 +1715,11 @@ function wp_ajax_widgets_order() { wp_die( -1 ); } +/** + * Ajax handler for saving a widget. + * + * @since 3.1.0 + */ function wp_ajax_save_widget() { global $wp_registered_widgets, $wp_registered_widget_controls, $wp_registered_widget_updates; @@ -1536,7 +1757,7 @@ function wp_ajax_save_widget() { $sidebars = wp_get_sidebars_widgets(); $sidebar = isset($sidebars[$sidebar_id]) ? $sidebars[$sidebar_id] : array(); - // delete + // Delete. if ( isset($_POST['delete_widget']) && $_POST['delete_widget'] ) { if ( !isset($wp_registered_widgets[$widget_id]) ) @@ -1583,11 +1804,21 @@ function wp_ajax_save_widget() { wp_die(); } +/** + * Ajax handler for saving a widget. + * + * @since 3.9.0 + */ function wp_ajax_update_widget() { global $wp_customize; $wp_customize->widgets->wp_ajax_update_widget(); } +/** + * Ajax handler for uploading attachments + * + * @since 3.3.0 + */ function wp_ajax_upload_attachment() { check_ajax_referer( 'media-form' ); @@ -1653,6 +1884,11 @@ function wp_ajax_upload_attachment() { wp_die(); } +/** + * Ajax handler for image editing. + * + * @since 3.1.0 + */ function wp_ajax_image_editor() { $attachment_id = intval($_POST['postid']); if ( empty($attachment_id) || !current_user_can('edit_post', $attachment_id) ) @@ -1680,6 +1916,11 @@ function wp_ajax_image_editor() { wp_die(); } +/** + * Ajax handler for setting the featured image. + * + * @since 3.1.0 + */ function wp_ajax_set_post_thumbnail() { $json = ! empty( $_REQUEST['json'] ); // New-style request @@ -1711,27 +1952,88 @@ function wp_ajax_set_post_thumbnail() { wp_die( 0 ); } +/** + * AJAX handler for setting the featured image for an attachment. + * + * @since 4.0.0 + * + * @see set_post_thumbnail() + */ +function wp_ajax_set_attachment_thumbnail() { + if ( empty( $_POST['urls'] ) || ! is_array( $_POST['urls'] ) ) { + wp_send_json_error(); + } + + $thumbnail_id = (int) $_POST['thumbnail_id']; + if ( empty( $thumbnail_id ) ) { + wp_send_json_error(); + } + + $post_ids = array(); + // For each URL, try to find its corresponding post ID. + foreach ( $_POST['urls'] as $url ) { + $post_id = attachment_url_to_postid( $url ); + if ( ! empty( $post_id ) ) { + $post_ids[] = $post_id; + } + } + + if ( empty( $post_ids ) ) { + wp_send_json_error(); + } + + $success = 0; + // For each found attachment, set its thumbnail. + foreach ( $post_ids as $post_id ) { + if ( ! current_user_can( 'edit_post', $post_id ) ) { + continue; + } + + if ( set_post_thumbnail( $post_id, $thumbnail_id ) ) { + $success++; + } + } + + if ( 0 === $success ) { + wp_send_json_error(); + } else { + wp_send_json_success(); + } + + wp_send_json_error(); +} + +/** + * Ajax handler for date formatting. + * + * @since 3.1.0 + */ function wp_ajax_date_format() { wp_die( date_i18n( sanitize_option( 'date_format', wp_unslash( $_POST['date'] ) ) ) ); } +/** + * Ajax handler for time formatting. + * + * @since 3.1.0 + */ function wp_ajax_time_format() { wp_die( date_i18n( sanitize_option( 'time_format', wp_unslash( $_POST['date'] ) ) ) ); } +/** + * Ajax handler for saving posts from the fullscreen editor. + * + * @since 3.1.0 + */ function wp_ajax_wp_fullscreen_save_post() { $post_id = isset( $_POST['post_ID'] ) ? (int) $_POST['post_ID'] : 0; - $post = $post_type = null; + $post = null; if ( $post_id ) $post = get_post( $post_id ); - if ( $post ) - $post_type = $post->post_type; - elseif ( isset( $_POST['post_type'] ) && post_type_exists( $_POST['post_type'] ) ) - $post_type = $_POST['post_type']; - check_ajax_referer('update-post_' . $post_id, '_wpnonce'); $post_id = edit_post(); @@ -1758,6 +2060,11 @@ function wp_ajax_wp_fullscreen_save_post() { wp_send_json_success( array( 'last_edited' => $last_edited ) ); } +/** + * Ajax handler for removing a post lock. + * + * @since 3.1.0 + */ function wp_ajax_wp_remove_post_lock() { if ( empty( $_POST['post_ID'] ) || empty( $_POST['active_post_lock'] ) ) wp_die( 0 ); @@ -1787,6 +2094,11 @@ function wp_ajax_wp_remove_post_lock() { wp_die( 1 ); } +/** + * Ajax handler for dismissing a WordPress pointer. + * + * @since 3.1.0 + */ function wp_ajax_dismiss_wp_pointer() { $pointer = $_POST['pointer']; if ( $pointer != sanitize_key( $pointer ) ) @@ -1807,7 +2119,7 @@ function wp_ajax_dismiss_wp_pointer() { } /** - * Get an attachment. + * Ajax handler for getting an attachment. * * @since 3.5.0 */ @@ -1834,7 +2146,7 @@ function wp_ajax_get_attachment() { } /** - * Query for attachments. + * Ajax handler for querying for attachments. * * @since 3.5.0 */ @@ -1845,11 +2157,18 @@ function wp_ajax_query_attachments() { $query = isset( $_REQUEST['query'] ) ? (array) $_REQUEST['query'] : array(); $query = array_intersect_key( $query, array_flip( array( 's', 'order', 'orderby', 'posts_per_page', 'paged', 'post_mime_type', - 'post_parent', 'post__in', 'post__not_in', + 'post_parent', 'post__in', 'post__not_in', 'year', 'monthnum' ) ) ); $query['post_type'] = 'attachment'; - $query['post_status'] = 'inherit'; + if ( MEDIA_TRASH + && ! empty( $_REQUEST['query']['post_status'] ) + && 'trash' === $_REQUEST['query']['post_status'] ) { + $query['post_status'] = 'trash'; + } else { + $query['post_status'] = 'inherit'; + } + if ( current_user_can( get_post_type_object( 'attachment' )->cap->read_private_posts ) ) $query['post_status'] .= ',private'; @@ -1873,7 +2192,7 @@ function wp_ajax_query_attachments() { } /** - * Save attachment attributes. + * Ajax handler for saving attachment attributes. * * @since 3.5.0 */ @@ -1904,6 +2223,9 @@ function wp_ajax_save_attachment() { if ( isset( $changes['description'] ) ) $post['post_content'] = $changes['description']; + if ( MEDIA_TRASH && isset( $changes['status'] ) ) + $post['post_status'] = $changes['status']; + if ( isset( $changes['alt'] ) ) { $alt = wp_unslash( $changes['alt'] ); if ( $alt != get_post_meta( $id, '_wp_attachment_image_alt', true ) ) { @@ -1912,12 +2234,36 @@ function wp_ajax_save_attachment() { } } - wp_update_post( $post ); + if ( 0 === strpos( $post['post_mime_type'], 'audio/' ) ) { + $changed = false; + $id3data = wp_get_attachment_metadata( $post['ID'] ); + if ( ! is_array( $id3data ) ) { + $changed = true; + $id3data = array(); + } + foreach ( wp_get_attachment_id3_keys( (object) $post, 'edit' ) as $key => $label ) { + if ( isset( $changes[ $key ] ) ) { + $changed = true; + $id3data[ $key ] = sanitize_text_field( wp_unslash( $changes[ $key ] ) ); + } + } + + if ( $changed ) { + wp_update_attachment_metadata( $id, $id3data ); + } + } + + if ( MEDIA_TRASH && isset( $changes['status'] ) && 'trash' === $changes['status'] ) { + wp_delete_post( $id ); + } else { + wp_update_post( $post ); + } + wp_send_json_success(); } /** - * Save backwards compatible attachment attributes. + * Ajax handler for saving backwards compatible attachment attributes. * * @since 3.5.0 */ @@ -1963,6 +2309,11 @@ function wp_ajax_save_attachment_compat() { wp_send_json_success( $attachment ); } +/** + * Ajax handler for saving the attachment order. + * + * @since 3.5.0 + */ function wp_ajax_save_attachment_order() { if ( ! isset( $_REQUEST['post_id'] ) ) wp_send_json_error(); @@ -1980,8 +2331,6 @@ function wp_ajax_save_attachment_order() { if ( ! current_user_can( 'edit_post', $post_id ) ) wp_send_json_error(); - $post = get_post( $post_id, ARRAY_A ); - foreach ( $attachments as $attachment_id => $menu_order ) { if ( ! current_user_can( 'edit_post', $attachment_id ) ) continue; @@ -1997,9 +2346,11 @@ function wp_ajax_save_attachment_order() { } /** + * Ajax handler for sending an attachment to the editor. + * * Generates the HTML to send an attachment to the editor. - * Backwards compatible with the media_send_to_editor filter and the chain - * of filters that follow. + * Backwards compatible with the media_send_to_editor filter + * and the chain of filters that follow. * * @since 3.5.0 */ @@ -2024,7 +2375,7 @@ function wp_ajax_send_attachment_to_editor() { } $rel = $url = ''; - $html = $title = isset( $attachment['post_title'] ) ? $attachment['post_title'] : ''; + $html = isset( $attachment['post_title'] ) ? $attachment['post_title'] : ''; if ( ! empty( $attachment['url'] ) ) { $url = $attachment['url']; if ( strpos( $url, 'attachment_id') || get_attachment_link( $id ) == $url ) @@ -2052,6 +2403,8 @@ function wp_ajax_send_attachment_to_editor() { } /** + * Ajax handler for sending a link to the editor. + * * Generates the HTML to send a non-image embed link to the editor. * * Backwards compatible with the following filters: @@ -2062,6 +2415,8 @@ function wp_ajax_send_attachment_to_editor() { * @since 3.5.0 */ function wp_ajax_send_link_to_editor() { + global $post, $wp_embed; + check_ajax_referer( 'media-send-to-editor', 'nonce' ); if ( ! $src = wp_unslash( $_POST['src'] ) ) @@ -2076,9 +2431,22 @@ function wp_ajax_send_link_to_editor() { if ( ! $title = trim( wp_unslash( $_POST['title'] ) ) ) $title = wp_basename( $src ); - $html = ''; - if ( $title ) + $post = get_post( isset( $_POST['post_id'] ) ? $_POST['post_id'] : 0 ); + + // Ping WordPress for an embed. + $check_embed = $wp_embed->run_shortcode( '[embed]'. $src .'[/embed]' ); + + // Fallback that WordPress creates when no oEmbed was found. + $fallback = $wp_embed->maybe_make_link( $src ); + + if ( $check_embed !== $fallback ) { + // TinyMCE view for [embed] will parse this + $html = '[embed]' . $src . '[/embed]'; + } elseif ( $title ) { $html = '' . $title . ''; + } else { + $html = ''; + } // Figure out what filter to run: $type = 'file'; @@ -2093,9 +2461,11 @@ function wp_ajax_send_link_to_editor() { } /** - * Heartbeat API (experimental) + * Ajax handler for the Heartbeat API. * * Runs when the user is logged in. + * + * @since 3.6.0 */ function wp_ajax_heartbeat() { if ( empty( $_POST['_nonce'] ) ) @@ -2109,7 +2479,7 @@ function wp_ajax_heartbeat() { wp_send_json($response); } - // screen_id is the same as $current_screen->id and the JS global 'pagenow' + // 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 @@ -2158,6 +2528,11 @@ function wp_ajax_heartbeat() { wp_send_json($response); } +/** + * Ajax handler for getting revision diffs. + * + * @since 3.6.0 + */ function wp_ajax_get_revision_diffs() { require ABSPATH . 'wp-admin/includes/revision.php'; @@ -2186,9 +2561,10 @@ function wp_ajax_get_revision_diffs() { } /** - * Auto-save the selected color scheme for a user's own profile. + * Ajax handler for auto-saving the selected color scheme for + * a user's own profile. * - * @since 3.8.0 + * @since 3.8.0 */ function wp_ajax_save_user_color_scheme() { global $_wp_admin_css_colors; @@ -2206,7 +2582,7 @@ function wp_ajax_save_user_color_scheme() { } /** - * Get themes from themes_api(). + * Ajax handler for getting themes from themes_api(). * * @since 3.9.0 */ @@ -2245,7 +2621,141 @@ function wp_ajax_query_themes() { $theme->version = wp_kses( $theme->version, $themes_allowedtags ); $theme->description = wp_kses( $theme->description, $themes_allowedtags ); $theme->num_ratings = sprintf( _n( '(based on %s rating)', '(based on %s ratings)', $theme->num_ratings ), number_format_i18n( $theme->num_ratings ) ); + $theme->preview_url = set_url_scheme( $theme->preview_url ); } wp_send_json_success( $api ); } + +/** + * Apply [embed] AJAX handlers to a string. + * + * @since 4.0.0 + * + * @global WP_Post $post Global $post. + * @global WP_Embed $wp_embed Embed API instance. + */ +function wp_ajax_parse_embed() { + global $post, $wp_embed; + + if ( ! $post = get_post( (int) $_POST['post_ID'] ) ) { + wp_send_json_error(); + } + + if ( empty( $_POST['shortcode'] ) || ! current_user_can( 'edit_post', $post->ID ) ) { + wp_send_json_error(); + } + + $shortcode = wp_unslash( $_POST['shortcode'] ); + $url = str_replace( '[embed]', '', str_replace( '[/embed]', '', $shortcode ) ); + $parsed = false; + setup_postdata( $post ); + + $wp_embed->return_false_on_fail = true; + + if ( is_ssl() && preg_match( '%^\\[embed[^\\]]*\\]http://%i', $shortcode ) ) { + // Admin is ssl and the user pasted non-ssl URL. + // Check if the provider supports ssl embeds and use that for the preview. + $ssl_shortcode = preg_replace( '%^(\\[embed[^\\]]*\\])http://%i', '$1https://', $shortcode ); + $parsed = $wp_embed->run_shortcode( $ssl_shortcode ); + + if ( ! $parsed ) { + $no_ssl_support = true; + } + } + + if ( ! $parsed ) { + $parsed = $wp_embed->run_shortcode( $shortcode ); + } + + if ( ! $parsed ) { + wp_send_json_error( array( + 'type' => 'not-embeddable', + 'message' => sprintf( __( '%s failed to embed.' ), '' . esc_html( $url ) . '' ), + ) ); + } + + if ( has_shortcode( $parsed, 'audio' ) || has_shortcode( $parsed, 'video' ) ) { + $styles = ''; + $mce_styles = wpview_media_sandbox_styles(); + foreach ( $mce_styles as $style ) { + $styles .= sprintf( '', $style ); + } + + $html = do_shortcode( $parsed ); + + global $wp_scripts; + if ( ! empty( $wp_scripts ) ) { + $wp_scripts->done = array(); + } + ob_start(); + wp_print_scripts( 'wp-mediaelement' ); + $scripts = ob_get_clean(); + + $parsed = $styles . $html . $scripts; + } + + + if ( ! empty( $no_ssl_support ) || ( is_ssl() && ( preg_match( '%<(iframe|script|embed) [^>]*src="http://%', $parsed ) || + preg_match( '%]*href="http://%', $parsed ) ) ) ) { + // Admin is ssl and the embed is not. Iframes, scripts, and other "active content" will be blocked. + wp_send_json_error( array( + 'type' => 'not-ssl', + 'message' => sprintf( __( 'Preview not available. %s cannot be embedded securely.' ), '' . esc_html( $url ) . '' ), + ) ); + } + + wp_send_json_success( array( + 'body' => $parsed + ) ); +} + +function wp_ajax_parse_media_shortcode() { + global $post, $wp_scripts; + + if ( ! $post = get_post( (int) $_POST['post_ID'] ) ) { + wp_send_json_error(); + } + + if ( empty( $_POST['shortcode'] ) || ! current_user_can( 'edit_post', $post->ID ) ) { + wp_send_json_error(); + } + + setup_postdata( $post ); + $shortcode = do_shortcode( wp_unslash( $_POST['shortcode'] ) ); + + if ( empty( $shortcode ) ) { + wp_send_json_error( array( + 'type' => 'no-items', + 'message' => __( 'No items found.' ), + ) ); + } + + $head = ''; + $styles = wpview_media_sandbox_styles(); + + foreach ( $styles as $style ) { + $head .= ''; + } + + if ( ! empty( $wp_scripts ) ) { + $wp_scripts->done = array(); + } + + ob_start(); + + echo $shortcode; + + if ( 'playlist' === $_REQUEST['type'] ) { + wp_underscore_playlist_templates(); + + wp_print_scripts( 'wp-playlist' ); + } else { + wp_print_scripts( 'wp-mediaelement' ); + } + + wp_send_json_success( array( + 'head' => $head, + 'body' => ob_get_clean() + ) ); +}

'.__('Title').''.__('Type').''.__('Date').''.__('Status').'