X-Git-Url: https://scripts.mit.edu/gitweb/autoinstalls/wordpress.git/blobdiff_plain/7f1521bf193b382565eb753043c161f4cb3fcda7..refs/tags/wordpress-4.3:/wp-admin/includes/ajax-actions.php diff --git a/wp-admin/includes/ajax-actions.php b/wp-admin/includes/ajax-actions.php index 40f8f5d1..77c32b05 100644 --- a/wp-admin/includes/ajax-actions.php +++ b/wp-admin/includes/ajax-actions.php @@ -78,6 +78,8 @@ function wp_ajax_nopriv_heartbeat() { * Ajax handler for fetching a list table. * * @since 3.1.0 + * + * @global WP_List_Table $wp_list_table */ function wp_ajax_fetch_list() { global $wp_list_table; @@ -226,6 +228,8 @@ function wp_ajax_imgedit_preview() { * Ajax handler for oEmbed caching. * * @since 3.1.0 + * + * @global WP_Embed $wp_embed */ function wp_ajax_oembed_cache() { $GLOBALS['wp_embed']->cache_oembed( $_GET['post'] ); @@ -334,7 +338,7 @@ function wp_ajax_logged_in() { * @since 2.7.0 * * @param int $comment_id - * @return die + * @param int $delta */ function _wp_ajax_delete_comment_response( $comment_id, $delta = -1 ) { $total = isset( $_POST['_total'] ) ? (int) $_POST['_total'] : 0; @@ -430,10 +434,13 @@ function _wp_ajax_add_hierarchical_term() { $checked_categories[] = $cat_id; if ( $parent ) // Do these all at once in a second continue; + ob_start(); - wp_terms_checklist( 0, array( 'taxonomy' => $taxonomy->name, 'descendants_and_self' => $cat_id, 'selected_cats' => $checked_categories, 'popular_cats' => $popular_ids )); - $data = ob_get_contents(); - ob_end_clean(); + + wp_terms_checklist( 0, array( 'taxonomy' => $taxonomy->name, 'descendants_and_self' => $cat_id, 'selected_cats' => $checked_categories, 'popular_cats' => $popular_ids )); + + $data = ob_get_clean(); + $add = array( 'what' => $taxonomy->name, 'id' => $cat_id, @@ -454,9 +461,11 @@ function _wp_ajax_add_hierarchical_term() { } ob_start(); - wp_terms_checklist( 0, array('taxonomy' => $taxonomy->name, 'descendants_and_self' => $term_id, 'selected_cats' => $checked_categories, 'popular_cats' => $popular_ids)); - $data = ob_get_contents(); - ob_end_clean(); + + wp_terms_checklist( 0, array('taxonomy' => $taxonomy->name, 'descendants_and_self' => $term_id, 'selected_cats' => $checked_categories, 'popular_cats' => $popular_ids)); + + $data = ob_get_clean(); + $add = array( 'what' => $taxonomy->name, 'id' => $term_id, @@ -466,12 +475,14 @@ function _wp_ajax_add_hierarchical_term() { } ob_start(); - wp_dropdown_categories( array( - 'taxonomy' => $taxonomy->name, 'hide_empty' => 0, 'name' => 'new'.$taxonomy->name.'_parent', 'orderby' => 'name', - 'hierarchical' => 1, 'show_option_none' => '— '.$taxonomy->labels->parent_item.' —' - ) ); - $sup = ob_get_contents(); - ob_end_clean(); + + wp_dropdown_categories( array( + 'taxonomy' => $taxonomy->name, 'hide_empty' => 0, 'name' => 'new'.$taxonomy->name.'_parent', 'orderby' => 'name', + 'hierarchical' => 1, 'show_option_none' => '— '.$taxonomy->labels->parent_item.' —' + ) ); + + $sup = ob_get_clean(); + $add['supplemental'] = array( 'newcat_parent' => $sup ); $x = new WP_Ajax_Response( $add ); @@ -660,6 +671,11 @@ function wp_ajax_untrash_post( $action ) { wp_ajax_trash_post( $action ); } +/** + * @since 3.1.0 + * + * @param string $action + */ function wp_ajax_delete_page( $action ) { if ( empty( $action ) ) $action = 'delete-page'; @@ -762,6 +778,8 @@ function wp_ajax_add_link_category( $action ) { * Ajax handler to add a tag. * * @since 3.1.0 + * + * @global WP_List_Table $wp_list_table */ function wp_ajax_add_tag() { global $wp_list_table; @@ -806,12 +824,12 @@ function wp_ajax_add_tag() { $x->add( array( 'what' => 'taxonomy', 'supplemental' => compact('parents', 'noparents') - ) ); + ) ); $x->add( array( 'what' => 'term', 'position' => $level, 'supplemental' => (array) $tag - ) ); + ) ); $x->send(); } @@ -864,6 +882,9 @@ function wp_ajax_get_tagcloud() { * * @since 3.1.0 * + * @global WP_List_Table $wp_list_table + * @global int $post_id + * * @param string $action Action to perform. */ function wp_ajax_get_comments( $action ) { @@ -900,8 +921,7 @@ function wp_ajax_get_comments( $action ) { get_comment( $comment ); $wp_list_table->single_row( $comment ); } - $comment_list_item = ob_get_contents(); - ob_end_clean(); + $comment_list_item = ob_get_clean(); $x->add( array( 'what' => 'comments', @@ -915,6 +935,8 @@ function wp_ajax_get_comments( $action ) { * * @since 3.1.0 * + * @global WP_List_Table $wp_list_table + * * @param string $action Action to perform. */ function wp_ajax_replyto_comment( $action ) { @@ -1016,6 +1038,8 @@ function wp_ajax_replyto_comment( $action ) { * Ajax handler for editing a comment. * * @since 3.1.0 + * + * @global WP_List_Table $wp_list_table */ function wp_ajax_edit_comment() { global $wp_list_table; @@ -1229,6 +1253,8 @@ function wp_ajax_add_meta() { * * @since 3.1.0 * + * @global WP_List_Table $wp_list_table + * * @param string $action Action to perform. */ function wp_ajax_add_user( $action ) { @@ -1305,7 +1331,6 @@ function wp_ajax_closed_postboxes() { */ function wp_ajax_hidden_columns() { check_ajax_referer( 'screen-options-nonce', 'screenoptionnonce' ); - $hidden = explode( ',', isset( $_POST['hidden'] ) ? $_POST['hidden'] : '' ); $page = isset( $_POST['page'] ) ? $_POST['page'] : ''; if ( $page != sanitize_key( $page ) ) @@ -1314,8 +1339,8 @@ function wp_ajax_hidden_columns() { if ( ! $user = wp_get_current_user() ) wp_die( -1 ); - if ( is_array($hidden) ) - update_user_option($user->ID, "manage{$page}columnshidden", $hidden, true); + $hidden = ! empty( $_POST['hidden'] ) ? explode( ',', $_POST['hidden'] ) : array(); + update_user_option( $user->ID, "manage{$page}columnshidden", $hidden, true ); wp_die( 1 ); } @@ -1499,6 +1524,8 @@ function wp_ajax_sample_permalink() { * Ajax handler for Quick Edit saving a post from a list table. * * @since 3.1.0 + * + * @global WP_List_Table $wp_list_table */ function wp_ajax_inline_save() { global $wp_list_table; @@ -1540,10 +1567,12 @@ function wp_ajax_inline_save() { $data['parent_id'] = $data['post_parent']; // Status. - if ( isset($data['keep_private']) && 'private' == $data['keep_private'] ) + if ( isset( $data['keep_private'] ) && 'private' == $data['keep_private'] ) { + $data['visibility'] = 'private'; $data['post_status'] = 'private'; - else + } else { $data['post_status'] = $data['_status']; + } if ( empty($data['comment_status']) ) $data['comment_status'] = 'closed'; @@ -1591,6 +1620,8 @@ function wp_ajax_inline_save() { * Ajax handler for quick edit saving for a term. * * @since 3.1.0 + * + * @global WP_List_Table $wp_list_table */ function wp_ajax_inline_save_tax() { global $wp_list_table; @@ -1743,6 +1774,10 @@ function wp_ajax_widgets_order() { * Ajax handler for saving a widget. * * @since 3.1.0 + * + * @global array $wp_registered_widgets + * @global array $wp_registered_widget_controls + * @global array $wp_registered_widget_updates */ function wp_ajax_save_widget() { global $wp_registered_widgets, $wp_registered_widget_controls, $wp_registered_widget_updates; @@ -1832,6 +1867,8 @@ function wp_ajax_save_widget() { * Ajax handler for saving a widget. * * @since 3.9.0 + * + * @global WP_Customize_Manager $wp_customize */ function wp_ajax_update_widget() { global $wp_customize; @@ -2072,6 +2109,7 @@ function wp_ajax_time_format() { * Ajax handler for saving posts from the fullscreen editor. * * @since 3.1.0 + * @deprecated 4.3.0 */ function wp_ajax_wp_fullscreen_save_post() { $post_id = isset( $_POST['post_ID'] ) ? (int) $_POST['post_ID'] : 0; @@ -2475,6 +2513,9 @@ function wp_ajax_send_attachment_to_editor() { * - video_send_to_editor_url * * @since 3.5.0 + * + * @global WP_Post $post + * @global WP_Embed $wp_embed */ function wp_ajax_send_link_to_editor() { global $post, $wp_embed; @@ -2530,26 +2571,35 @@ function wp_ajax_send_link_to_editor() { * @since 3.6.0 */ function wp_ajax_heartbeat() { - if ( empty( $_POST['_nonce'] ) ) + 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); } + $response = $data = array(); + $nonce_state = wp_verify_nonce( $_POST['_nonce'], 'heartbeat-nonce' ); + // screen_id is the same as $current_screen->id and the JS global 'pagenow'. - if ( ! empty($_POST['screen_id']) ) + if ( ! empty( $_POST['screen_id'] ) ) { $screen_id = sanitize_key($_POST['screen_id']); - else + } else { $screen_id = 'front'; + } - if ( ! empty($_POST['data']) ) { + if ( ! empty( $_POST['data'] ) ) { $data = wp_unslash( (array) $_POST['data'] ); + } + if ( 1 !== $nonce_state ) { + $response = apply_filters( 'wp_refresh_nonces', $response, $data, $screen_id ); + + if ( false === $nonce_state ) { + // User is logged in but nonces have expired. + $response['nonces_expired'] = true; + wp_send_json( $response ); + } + } + + if ( ! empty( $data ) ) { /** * Filter the Heartbeat response received. * @@ -2587,7 +2637,7 @@ function wp_ajax_heartbeat() { // Send the current time according to the server $response['server_time'] = time(); - wp_send_json($response); + wp_send_json( $response ); } /** @@ -2627,6 +2677,8 @@ function wp_ajax_get_revision_diffs() { * a user's own profile. * * @since 3.8.0 + * + * @global array $_wp_admin_css_colors */ function wp_ajax_save_user_color_scheme() { global $_wp_admin_css_colors; @@ -2652,6 +2704,9 @@ function wp_ajax_save_user_color_scheme() { * Ajax handler for getting themes from themes_api(). * * @since 3.9.0 + * + * @global array $themes_allowedtags + * @global array $theme_field_defaults */ function wp_ajax_query_themes() { global $themes_allowedtags, $theme_field_defaults; @@ -2699,8 +2754,9 @@ function wp_ajax_query_themes() { * * @since 4.0.0 * - * @global WP_Post $post Global $post. - * @global WP_Embed $wp_embed Embed API instance. + * @global WP_Post $post Global $post. + * @global WP_Embed $wp_embed Embed API instance. + * @global WP_Scripts $wp_scripts */ function wp_ajax_parse_embed() { global $post, $wp_embed; @@ -2714,14 +2770,23 @@ function wp_ajax_parse_embed() { } $shortcode = wp_unslash( $_POST['shortcode'] ); - $url = str_replace( '[embed]', '', str_replace( '[/embed]', '', $shortcode ) ); + + preg_match( '/' . get_shortcode_regex() . '/s', $shortcode, $matches ); + $atts = shortcode_parse_atts( $matches[3] ); + if ( ! empty( $matches[5] ) ) { + $url = $matches[5]; + } elseif ( ! empty( $atts['src'] ) ) { + $url = $atts['src']; + } else { + $url = ''; + } $parsed = false; setup_postdata( $post ); $wp_embed->return_false_on_fail = true; - if ( is_ssl() && preg_match( '%^\\[embed[^\\]]*\\]http://%i', $shortcode ) ) { + if ( is_ssl() && 0 === strpos( $url, 'http://' ) ) { // 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 ); @@ -2732,7 +2797,7 @@ function wp_ajax_parse_embed() { } } - if ( ! $parsed ) { + if ( $url && ! $parsed ) { $parsed = $wp_embed->run_shortcode( $shortcode ); } @@ -2774,10 +2839,17 @@ function wp_ajax_parse_embed() { } wp_send_json_success( array( - 'body' => $parsed + 'body' => $parsed, + 'attr' => $wp_embed->last_attr ) ); } +/** + * @since 4.0.0 + * + * @global WP_Post $post + * @global WP_Scripts $wp_scripts + */ function wp_ajax_parse_media_shortcode() { global $post, $wp_scripts; @@ -2844,7 +2916,6 @@ function wp_ajax_parse_media_shortcode() { * @since 4.1.0 */ function wp_ajax_destroy_sessions() { - $user = get_userdata( (int) $_POST['user_id'] ); if ( $user ) { if ( ! current_user_can( 'edit_user', $user->ID ) ) { @@ -2883,6 +2954,8 @@ function wp_ajax_destroy_sessions() { * @see Plugin_Upgrader */ function wp_ajax_update_plugin() { + global $wp_filesystem; + $plugin = urldecode( $_POST['plugin'] ); $status = array( @@ -2892,13 +2965,14 @@ function wp_ajax_update_plugin() { 'oldVersion' => '', 'newVersion' => '', ); + $plugin_data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin ); if ( $plugin_data['Version'] ) { $status['oldVersion'] = sprintf( __( 'Version %s' ), $plugin_data['Version'] ); } if ( ! current_user_can( 'update_plugins' ) ) { - $status['error'] = __( 'You do not have sufficient permissions to update plugins on this site.' ); + $status['error'] = __( 'You do not have sufficient permissions to update plugins for this site.' ); wp_send_json_error( $status ); } @@ -2906,15 +2980,17 @@ function wp_ajax_update_plugin() { include_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' ); - $current = get_site_transient( 'update_plugins' ); - if ( empty( $current ) ) { - wp_update_plugins(); - } + wp_update_plugins(); - $upgrader = new Plugin_Upgrader( new Automatic_Upgrader_Skin() ); + $skin = new Automatic_Upgrader_Skin(); + $upgrader = new Plugin_Upgrader( $skin ); $result = $upgrader->bulk_upgrade( array( $plugin ) ); - if ( is_array( $result ) ) { + if ( is_array( $result ) && empty( $result[$plugin] ) && is_wp_error( $skin->result ) ) { + $result = $skin->result; + } + + if ( is_array( $result ) && !empty( $result[ $plugin ] ) ) { $plugin_update_data = current( $result ); /* @@ -2929,7 +3005,8 @@ function wp_ajax_update_plugin() { wp_send_json_error( $status ); } - $plugin_data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin ); + $plugin_data = get_plugins( '/' . $result[ $plugin ]['destination_name'] ); + $plugin_data = reset( $plugin_data ); if ( $plugin_data['Version'] ) { $status['newVersion'] = sprintf( __( 'Version %s' ), $plugin_data['Version'] ); @@ -2939,10 +3016,18 @@ function wp_ajax_update_plugin() { } else if ( is_wp_error( $result ) ) { $status['error'] = $result->get_error_message(); wp_send_json_error( $status ); - } else if ( is_bool( $result ) && ! $result ) { + + } else if ( is_bool( $result ) && ! $result ) { $status['errorCode'] = 'unable_to_connect_to_filesystem'; $status['error'] = __( 'Unable to connect to the filesystem. Please confirm your credentials.' ); + + // Pass through the error from WP_Filesystem if one was raised + if ( is_wp_error( $wp_filesystem->errors ) && $wp_filesystem->errors->get_error_code() ) { + $status['error'] = $wp_filesystem->errors->get_error_message(); + } + wp_send_json_error( $status ); + } } @@ -2950,6 +3035,8 @@ function wp_ajax_update_plugin() { * AJAX handler for saving a post from Press This. * * @since 4.2.0 + * + * @global WP_Press_This $wp_press_this */ function wp_ajax_press_this_save_post() { if ( empty( $GLOBALS['wp_press_this'] ) ) { @@ -2963,6 +3050,8 @@ function wp_ajax_press_this_save_post() { * AJAX handler for creating new category from Press This. * * @since 4.2.0 + * + * @global WP_Press_This $wp_press_this */ function wp_ajax_press_this_add_category() { if ( empty( $GLOBALS['wp_press_this'] ) ) { @@ -2971,3 +3060,117 @@ function wp_ajax_press_this_add_category() { $GLOBALS['wp_press_this']->add_category(); } + +/** + * AJAX handler for cropping an image. + * + * @since 4.3.0 + * + * @global WP_Site_Icon $wp_site_icon + */ +function wp_ajax_crop_image() { + $attachment_id = absint( $_POST['id'] ); + + check_ajax_referer( 'image_editor-' . $attachment_id, 'nonce' ); + if ( ! current_user_can( 'customize' ) ) { + wp_send_json_error(); + } + + $context = str_replace( '_', '-', $_POST['context'] ); + $data = array_map( 'absint', $_POST['cropDetails'] ); + $cropped = wp_crop_image( $attachment_id, $data['x1'], $data['y1'], $data['width'], $data['height'], $data['dst_width'], $data['dst_height'] ); + + if ( ! $cropped || is_wp_error( $cropped ) ) { + wp_send_json_error( array( 'message' => __( 'Image could not be processed.' ) ) ); + } + + switch ( $context ) { + case 'site-icon': + require_once ABSPATH . '/wp-admin/includes/class-wp-site-icon.php'; + global $wp_site_icon; + + // Skip creating a new attachment if the attachment is a Site Icon. + if ( get_post_meta( $attachment_id, '_wp_attachment_context', true ) == $context ) { + + // Delete the temporary cropped file, we don't need it. + wp_delete_file( $cropped ); + + // Additional sizes in wp_prepare_attachment_for_js(). + add_filter( 'image_size_names_choose', array( $wp_site_icon, 'additional_sizes' ) ); + break; + } + + /** This filter is documented in wp-admin/custom-header.php */ + $cropped = apply_filters( 'wp_create_file_in_uploads', $cropped, $attachment_id ); // For replication. + $object = $wp_site_icon->create_attachment_object( $cropped, $attachment_id ); + unset( $object['ID'] ); + + // Update the attachment. + add_filter( 'intermediate_image_sizes_advanced', array( $wp_site_icon, 'additional_sizes' ) ); + $attachment_id = $wp_site_icon->insert_attachment( $object, $cropped ); + remove_filter( 'intermediate_image_sizes_advanced', array( $wp_site_icon, 'additional_sizes' ) ); + + // Additional sizes in wp_prepare_attachment_for_js(). + add_filter( 'image_size_names_choose', array( $wp_site_icon, 'additional_sizes' ) ); + break; + + default: + + /** + * Fires before a cropped image is saved. + * + * Allows to add filters to modify the way a cropped image is saved. + * + * @since 4.3.0 + * + * @param string $context The Customizer control requesting the cropped image. + * @param int $attachment_id The attachment ID of the original image. + * @param string $cropped Path to the cropped image file. + */ + do_action( 'wp_ajax_crop_image_pre_save', $context, $attachment_id, $cropped ); + + /** This filter is documented in wp-admin/custom-header.php */ + $cropped = apply_filters( 'wp_create_file_in_uploads', $cropped, $attachment_id ); // For replication. + + $parent_url = get_post( $attachment_id )->guid; + $url = str_replace( basename( $parent_url ), basename( $cropped ), $parent_url ); + + $size = @getimagesize( $cropped ); + $image_type = ( $size ) ? $size['mime'] : 'image/jpeg'; + + $object = array( + 'post_title' => basename( $cropped ), + 'post_content' => $url, + 'post_mime_type' => $image_type, + 'guid' => $url, + 'context' => $context, + ); + + $attachment_id = wp_insert_attachment( $object, $cropped ); + $metadata = wp_generate_attachment_metadata( $attachment_id, $cropped ); + + /** + * Filter the cropped image attachment metadata. + * + * @since 4.3.0 + * + * @see wp_generate_attachment_metadata() + * + * @param array $metadata Attachment metadata. + */ + $metadata = apply_filters( 'wp_ajax_cropped_attachment_metadata', $metadata ); + wp_update_attachment_metadata( $attachment_id, $metadata ); + + /** + * Filter the attachment ID for a cropped image. + * + * @since 4.3.0 + * + * @param int $attachment_id The attachment ID of the cropped image. + * @param string $context The Customizer control requesting the cropped image. + */ + $attachment_id = apply_filters( 'wp_ajax_cropped_attachment_id', $attachment_id, $context ); + } + + wp_send_json_success( wp_prepare_attachment_for_js( $attachment_id ) ); +}