X-Git-Url: https://scripts.mit.edu/gitweb/autoinstalls/wordpress.git/blobdiff_plain/af50974463450c98503e763a7836a50e260461a9..4feeb71a9d812a9ae371c28a3d8b442a4394ded7:/wp-admin/includes/ajax-actions.php
diff --git a/wp-admin/includes/ajax-actions.php b/wp-admin/includes/ajax-actions.php
index 9024a2c1..0f558368 100644
--- a/wp-admin/includes/ajax-actions.php
+++ b/wp-admin/includes/ajax-actions.php
@@ -1,9 +1,10 @@
cache_oembed( $_GET['post'] );
@@ -284,7 +291,7 @@ function wp_ajax_autocomplete_user() {
foreach ( $users as $user ) {
$return[] = array(
/* translators: 1: user_login, 2: user_email */
- 'label' => sprintf( __( '%1$s (%2$s)' ), $user->user_login, $user->user_email ),
+ 'label' => sprintf( _x( '%1$s (%2$s)', 'user autocomplete result' ), $user->user_login, $user->user_email ),
'value' => $user->$field,
);
}
@@ -331,10 +338,11 @@ function wp_ajax_logged_in() {
*
* Contrary to normal success AJAX response ("1"), die with time() on success.
*
+ * @access private
* @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;
@@ -343,8 +351,33 @@ function _wp_ajax_delete_comment_response( $comment_id, $delta = -1 ) {
$url = isset( $_POST['_url'] ) ? esc_url_raw( $_POST['_url'] ) : '';
// JS didn't send us everything we need to know. Just die with success message
- if ( !$total || !$per_page || !$page || !$url )
- wp_die( time() );
+ if ( ! $total || ! $per_page || ! $page || ! $url ) {
+ $time = time();
+ $comment = get_comment( $comment_id );
+
+ $counts = wp_count_comments();
+
+ $x = new WP_Ajax_Response( array(
+ 'what' => 'comment',
+ // Here for completeness - not used.
+ 'id' => $comment_id,
+ 'supplemental' => array(
+ 'status' => $comment ? $comment->comment_approved : '',
+ 'postId' => $comment ? $comment->comment_post_ID : '',
+ 'time' => $time,
+ 'in_moderation' => $counts->moderated,
+ 'i18n_comments_text' => sprintf(
+ _n( '%s Comment', '%s Comments', $counts->approved ),
+ number_format_i18n( $counts->approved )
+ ),
+ 'i18n_moderation_text' => sprintf(
+ _nx( '%s in moderation', '%s in moderation', $counts->moderated, 'comments' ),
+ number_format_i18n( $counts->moderated )
+ )
+ )
+ ) );
+ $x->send();
+ }
$total += $delta;
if ( $total < 0 )
@@ -353,7 +386,8 @@ function _wp_ajax_delete_comment_response( $comment_id, $delta = -1 ) {
// Only do the expensive stuff on a page-break, and about 1 other time per page
if ( 0 == $total % $per_page || 1 == mt_rand( 1, $per_page ) ) {
$post_id = 0;
- $status = 'total_comments'; // What type of comment count are we looking for?
+ // What type of comment count are we looking for?
+ $status = 'all';
$parsed = parse_url( $url );
if ( isset( $parsed['query'] ) ) {
parse_str( $parsed['query'], $query_vars );
@@ -373,13 +407,16 @@ function _wp_ajax_delete_comment_response( $comment_id, $delta = -1 ) {
// The time since the last comment count.
$time = time();
+ $comment = get_comment( $comment_id );
$x = new WP_Ajax_Response( array(
'what' => 'comment',
// Here for completeness - not used.
'id' => $comment_id,
'supplemental' => array(
- 'total_items_i18n' => sprintf( _n( '1 item', '%s items', $total ), number_format_i18n( $total ) ),
+ 'status' => $comment ? $comment->comment_approved : '',
+ 'postId' => $comment ? $comment->comment_post_ID : '',
+ 'total_items_i18n' => sprintf( _n( '%s item', '%s items', $total ), number_format_i18n( $total ) ),
'total_pages' => ceil( $total / $per_page ),
'total_pages_i18n' => number_format_i18n( ceil( $total / $per_page ) ),
'total' => $total,
@@ -396,6 +433,7 @@ function _wp_ajax_delete_comment_response( $comment_id, $delta = -1 ) {
/**
* Ajax handler for adding a hierarchical term.
*
+ * @access private
* @since 3.1.0
*/
function _wp_ajax_add_hierarchical_term() {
@@ -422,17 +460,21 @@ function _wp_ajax_add_hierarchical_term() {
continue;
if ( !$cat_id = term_exists( $cat_name, $taxonomy->name, $parent ) )
$cat_id = wp_insert_term( $cat_name, $taxonomy->name, array( 'parent' => $parent ) );
- if ( is_wp_error( $cat_id ) )
+ if ( is_wp_error( $cat_id ) ) {
continue;
- else if ( is_array( $cat_id ) )
+ } elseif ( is_array( $cat_id ) ) {
$cat_id = $cat_id['term_id'];
+ }
$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,
@@ -453,9 +495,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,
@@ -465,12 +509,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 );
@@ -491,31 +537,31 @@ function wp_ajax_delete_comment() {
wp_die( -1 );
check_ajax_referer( "delete-comment_$id" );
- $status = wp_get_comment_status( $comment->comment_ID );
+ $status = wp_get_comment_status( $comment );
$delta = -1;
if ( isset($_POST['trash']) && 1 == $_POST['trash'] ) {
if ( 'trash' == $status )
wp_die( time() );
- $r = wp_trash_comment( $comment->comment_ID );
+ $r = wp_trash_comment( $comment );
} elseif ( isset($_POST['untrash']) && 1 == $_POST['untrash'] ) {
if ( 'trash' != $status )
wp_die( time() );
- $r = wp_untrash_comment( $comment->comment_ID );
+ $r = wp_untrash_comment( $comment );
if ( ! isset( $_POST['comment_status'] ) || $_POST['comment_status'] != 'trash' ) // undo trash, not in trash
$delta = 1;
} elseif ( isset($_POST['spam']) && 1 == $_POST['spam'] ) {
if ( 'spam' == $status )
wp_die( time() );
- $r = wp_spam_comment( $comment->comment_ID );
+ $r = wp_spam_comment( $comment );
} elseif ( isset($_POST['unspam']) && 1 == $_POST['unspam'] ) {
if ( 'spam' != $status )
wp_die( time() );
- $r = wp_unspam_comment( $comment->comment_ID );
+ $r = wp_unspam_comment( $comment );
if ( ! isset( $_POST['comment_status'] ) || $_POST['comment_status'] != 'spam' ) // undo spam, not in spam
$delta = 1;
} elseif ( isset($_POST['delete']) && 1 == $_POST['delete'] ) {
- $r = wp_delete_comment( $comment->comment_ID );
+ $r = wp_delete_comment( $comment );
} else {
wp_die( -1 );
}
@@ -659,6 +705,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';
@@ -696,15 +747,16 @@ function wp_ajax_dim_comment() {
if ( ! current_user_can( 'edit_comment', $comment->comment_ID ) && ! current_user_can( 'moderate_comments' ) )
wp_die( -1 );
- $current = wp_get_comment_status( $comment->comment_ID );
+ $current = wp_get_comment_status( $comment );
if ( isset( $_POST['new'] ) && $_POST['new'] == $current )
wp_die( time() );
check_ajax_referer( "approve-comment_$id" );
- if ( in_array( $current, array( 'unapproved', 'spam' ) ) )
- $result = wp_set_comment_status( $comment->comment_ID, 'approve', true );
- else
- $result = wp_set_comment_status( $comment->comment_ID, 'hold', true );
+ if ( in_array( $current, array( 'unapproved', 'spam' ) ) ) {
+ $result = wp_set_comment_status( $comment, 'approve', true );
+ } else {
+ $result = wp_set_comment_status( $comment, 'hold', true );
+ }
if ( is_wp_error($result) ) {
$x = new WP_Ajax_Response( array(
@@ -741,10 +793,11 @@ function wp_ajax_add_link_category( $action ) {
continue;
if ( !$cat_id = term_exists( $cat_name, 'link_category' ) )
$cat_id = wp_insert_term( $cat_name, 'link_category' );
- if ( is_wp_error( $cat_id ) )
+ if ( is_wp_error( $cat_id ) ) {
continue;
- else if ( is_array( $cat_id ) )
+ } elseif ( is_array( $cat_id ) ) {
$cat_id = $cat_id['term_id'];
+ }
$cat_name = esc_html( $cat_name );
$x->add( array(
'what' => 'link-category',
@@ -760,6 +813,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;
@@ -804,12 +859,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();
}
@@ -828,7 +883,7 @@ function wp_ajax_get_tagcloud() {
if ( ! $tax ) {
wp_die( 0 );
}
-
+
if ( ! current_user_can( $tax->cap->assign_terms ) ) {
wp_die( -1 );
}
@@ -862,6 +917,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 ) {
@@ -898,8 +956,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',
@@ -913,6 +970,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 ) {
@@ -970,7 +1029,11 @@ function wp_ajax_replyto_comment( $action ) {
$parent = get_comment( $comment_parent );
if ( $parent && $parent->comment_approved === '0' && $parent->comment_post_ID == $comment_post_ID ) {
- if ( wp_set_comment_status( $parent->comment_ID, 'approve' ) )
+ if ( ! current_user_can( 'edit_comment', $parent->comment_ID ) ) {
+ wp_die( -1 );
+ }
+
+ if ( wp_set_comment_status( $parent, 'approve' ) )
$comment_auto_approved = true;
}
}
@@ -1002,8 +1065,23 @@ function wp_ajax_replyto_comment( $action ) {
'position' => $position
);
- if ( $comment_auto_approved )
- $response['supplemental'] = array( 'parent_approved' => $parent->comment_ID );
+ $counts = wp_count_comments();
+ $response['supplemental'] = array(
+ 'in_moderation' => $counts->moderated,
+ 'i18n_comments_text' => sprintf(
+ _n( '%s Comment', '%s Comments', $counts->approved ),
+ number_format_i18n( $counts->approved )
+ ),
+ 'i18n_moderation_text' => sprintf(
+ _nx( '%s in moderation', '%s in moderation', $counts->moderated, 'comments' ),
+ number_format_i18n( $counts->moderated )
+ )
+ );
+
+ if ( $comment_auto_approved ) {
+ $response['supplemental']['parent_approved'] = $parent->comment_ID;
+ $response['supplemental']['parent_post_id'] = $parent->comment_post_ID;
+ }
$x = new WP_Ajax_Response();
$x->add( $response );
@@ -1014,6 +1092,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;
@@ -1083,13 +1163,17 @@ function wp_ajax_add_menu_item() {
$_object = get_post( $menu_item_data['menu-item-object-id'] );
break;
+ case 'post_type_archive' :
+ $_object = get_post_type_object( $menu_item_data['menu-item-object'] );
+ break;
+
case 'taxonomy' :
$_object = get_term( $menu_item_data['menu-item-object-id'], $menu_item_data['menu-item-object'] );
break;
}
$_menu_items = array_map( 'wp_setup_nav_menu_item', array( $_object ) );
- $_menu_item = array_shift( $_menu_items );
+ $_menu_item = reset( $_menu_items );
// Restore the missing menu item properties
$menu_item_data['menu-item-description'] = $_menu_item->description;
@@ -1151,16 +1235,16 @@ function wp_ajax_add_meta() {
// If the post is an autodraft, save the post as a draft and then attempt to save the meta.
if ( $post->post_status == 'auto-draft' ) {
- $save_POST = $_POST; // Backup $_POST
- $_POST = array(); // Make it empty for edit_post()
- $_POST['action'] = 'draft'; // Warning fix
- $_POST['post_ID'] = $pid;
- $_POST['post_type'] = $post->post_type;
- $_POST['post_status'] = 'draft';
+ $post_data = array();
+ $post_data['action'] = 'draft'; // Warning fix
+ $post_data['post_ID'] = $pid;
+ $post_data['post_type'] = $post->post_type;
+ $post_data['post_status'] = 'draft';
$now = current_time('timestamp', 1);
- $_POST['post_title'] = sprintf( __( 'Draft created on %1$s at %2$s' ), date( get_option( 'date_format' ), $now ), date( get_option( 'time_format' ), $now ) );
+ $post_data['post_title'] = sprintf( __( 'Draft created on %1$s at %2$s' ), date( __( 'F j, Y' ), $now ), date( __( 'g:i a' ), $now ) );
- if ( $pid = edit_post() ) {
+ $pid = edit_post( $post_data );
+ if ( $pid ) {
if ( is_wp_error( $pid ) ) {
$x = new WP_Ajax_Response( array(
'what' => 'meta',
@@ -1168,13 +1252,13 @@ function wp_ajax_add_meta() {
) );
$x->send();
}
- $_POST = $save_POST; // Now we can restore original $_POST again
+
if ( !$mid = add_meta( $pid ) )
wp_die( __( 'Please provide a custom field value.' ) );
} else {
wp_die( 0 );
}
- } else if ( !$mid = add_meta( $pid ) ) {
+ } elseif ( ! $mid = add_meta( $pid ) ) {
wp_die( __( 'Please provide a custom field value.' ) );
}
@@ -1227,6 +1311,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 ) {
@@ -1257,7 +1343,11 @@ function wp_ajax_add_user( $action ) {
'id' => $user_id,
'data' => $wp_list_table->single_row( $user_object, '', $role ),
'supplemental' => array(
- 'show-link' => sprintf(__( 'User %s added' ), "user-$user_id", $user_object->user_login),
+ 'show-link' => sprintf(
+ /* translators: %s: the new user */
+ __( 'User %s added' ),
+ '' . $user_object->user_login . ''
+ ),
'role' => $role,
)
) );
@@ -1303,7 +1393,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 ) )
@@ -1312,8 +1401,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 );
}
@@ -1392,8 +1481,14 @@ function wp_ajax_wp_link_ajax() {
$args = array();
- if ( isset( $_POST['search'] ) )
+ if ( isset( $_POST['search'] ) ) {
$args['s'] = wp_unslash( $_POST['search'] );
+ }
+
+ if ( isset( $_POST['term'] ) ) {
+ $args['s'] = wp_unslash( $_POST['term'] );
+ }
+
$args['pagenum'] = ! empty( $_POST['page'] ) ? absint( $_POST['page'] ) : 1;
require(ABSPATH . WPINC . '/class-wp-editor.php');
@@ -1477,7 +1572,7 @@ function wp_ajax_menu_quick_search() {
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 ) ) );
+ wp_die( get_preview_post_link( $post_id ) );
}
/**
@@ -1497,9 +1592,11 @@ 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;
+ global $wp_list_table, $mode;
check_ajax_referer( 'inlineeditnonce', '_inline_edit' );
@@ -1538,16 +1635,29 @@ 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';
if ( empty($data['ping_status']) )
$data['ping_status'] = 'closed';
+ // Exclude terms from taxonomies that are not supposed to appear in Quick Edit.
+ if ( ! empty( $data['tax_input'] ) ) {
+ foreach ( $data['tax_input'] as $taxonomy => $terms ) {
+ $tax_object = get_taxonomy( $taxonomy );
+ /** This filter is documented in wp-admin/includes/class-wp-posts-list-table.php */
+ if ( ! apply_filters( 'quick_edit_show_taxonomy', $tax_object->show_in_quick_edit, $taxonomy, $post['post_type'] ) ) {
+ unset( $data['tax_input'][ $taxonomy ] );
+ }
+ }
+ }
+
// Hack: wp_unique_post_slug() doesn't work for drafts, so we will fake that our post is published.
if ( ! empty( $data['post_name'] ) && in_array( $post['post_status'], array( 'draft', 'pending' ) ) ) {
$post['post_status'] = 'publish';
@@ -1559,6 +1669,8 @@ function wp_ajax_inline_save() {
$wp_list_table = _get_list_table( 'WP_Posts_List_Table', array( 'screen' => $_POST['screen'] ) );
+ $mode = $_POST['post_view'] === 'excerpt' ? 'excerpt' : 'list';
+
$level = 0;
$request_post = array( get_post( $_POST['post_ID'] ) );
$parent = $request_post[0]->post_parent;
@@ -1578,6 +1690,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;
@@ -1730,6 +1844,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;
@@ -1776,11 +1894,15 @@ function wp_ajax_save_widget() {
$sidebar = array_diff( $sidebar, array($widget_id) );
$_POST = array('sidebar' => $sidebar_id, 'widget-' . $id_base => array(), 'the-widget-id' => $widget_id, 'delete_widget' => '1');
+
+ /** This action is documented in wp-admin/widgets.php */
+ do_action( 'delete_widget', $widget_id, $sidebar_id, $id_base );
+
} elseif ( $settings && preg_match( '/__i__|%i%/', key($settings) ) ) {
if ( !$multi_number )
wp_die( $error );
- $_POST['widget-' . $id_base] = array( $multi_number => array_shift($settings) );
+ $_POST[ 'widget-' . $id_base ] = array( $multi_number => reset( $settings ) );
$widget_id = $id_base . '-' . $multi_number;
$sidebar[] = $widget_id;
}
@@ -1819,12 +1941,49 @@ 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;
$wp_customize->widgets->wp_ajax_update_widget();
}
+/**
+ * Ajax handler for removing inactive widgets.
+ *
+ * @since 4.4.0
+ */
+function wp_ajax_delete_inactive_widgets() {
+ check_ajax_referer( 'remove-inactive-widgets', 'removeinactivewidgets' );
+
+ if ( ! current_user_can( 'edit_theme_options' ) ) {
+ wp_die( -1 );
+ }
+
+ unset( $_POST['removeinactivewidgets'], $_POST['action'] );
+
+ do_action( 'load-widgets.php' );
+ do_action( 'widgets.php' );
+ do_action( 'sidebar_admin_setup' );
+
+ $sidebars_widgets = wp_get_sidebars_widgets();
+
+ foreach ( $sidebars_widgets['wp_inactive_widgets'] as $key => $widget_id ) {
+ $pieces = explode( '-', $widget_id );
+ $multi_number = array_pop( $pieces );
+ $id_base = implode( '-', $pieces );
+ $widget = get_option( 'widget_' . $id_base );
+ unset( $widget[$multi_number] );
+ update_option( 'widget_' . $id_base, $widget );
+ unset( $sidebars_widgets['wp_inactive_widgets'][$key] );
+ }
+
+ wp_set_sidebars_widgets( $sidebars_widgets );
+
+ wp_die();
+}
+
/**
* Ajax handler for uploading attachments
*
@@ -1832,21 +1991,36 @@ function wp_ajax_update_widget() {
*/
function wp_ajax_upload_attachment() {
check_ajax_referer( 'media-form' );
+ /*
+ * This function does not use wp_send_json_success() / wp_send_json_error()
+ * as the html4 Plupload handler requires a text/html content-type for older IE.
+ * See https://core.trac.wordpress.org/ticket/31037
+ */
if ( ! current_user_can( 'upload_files' ) ) {
- wp_send_json_error( array(
- 'message' => __( "You don't have permission to upload files." ),
- 'filename' => $_FILES['async-upload']['name'],
+ echo wp_json_encode( array(
+ 'success' => false,
+ 'data' => array(
+ 'message' => __( 'You do not have permission to upload files.' ),
+ 'filename' => $_FILES['async-upload']['name'],
+ )
) );
+
+ wp_die();
}
if ( isset( $_REQUEST['post_id'] ) ) {
$post_id = $_REQUEST['post_id'];
if ( ! current_user_can( 'edit_post', $post_id ) ) {
- wp_send_json_error( array(
- 'message' => __( "You don't have permission to attach files to this post." ),
- 'filename' => $_FILES['async-upload']['name'],
+ echo wp_json_encode( array(
+ 'success' => false,
+ 'data' => array(
+ 'message' => __( "You don't have permission to attach files to this post." ),
+ 'filename' => $_FILES['async-upload']['name'],
+ )
) );
+
+ wp_die();
}
} else {
$post_id = null;
@@ -1856,22 +2030,32 @@ function wp_ajax_upload_attachment() {
// If the context is custom header or background, make sure the uploaded file is an image.
if ( isset( $post_data['context'] ) && in_array( $post_data['context'], array( 'custom-header', 'custom-background' ) ) ) {
- $wp_filetype = wp_check_filetype_and_ext( $_FILES['async-upload']['tmp_name'], $_FILES['async-upload']['name'], false );
+ $wp_filetype = wp_check_filetype_and_ext( $_FILES['async-upload']['tmp_name'], $_FILES['async-upload']['name'] );
if ( ! wp_match_mime_types( 'image', $wp_filetype['type'] ) ) {
- wp_send_json_error( array(
- 'message' => __( 'The uploaded file is not a valid image. Please try again.' ),
- 'filename' => $_FILES['async-upload']['name'],
+ echo wp_json_encode( array(
+ 'success' => false,
+ 'data' => array(
+ 'message' => __( 'The uploaded file is not a valid image. Please try again.' ),
+ 'filename' => $_FILES['async-upload']['name'],
+ )
) );
+
+ wp_die();
}
}
$attachment_id = media_handle_upload( 'async-upload', $post_id, $post_data );
if ( is_wp_error( $attachment_id ) ) {
- wp_send_json_error( array(
- 'message' => $attachment_id->get_error_message(),
- 'filename' => $_FILES['async-upload']['name'],
+ echo wp_json_encode( array(
+ 'success' => false,
+ 'data' => array(
+ 'message' => $attachment_id->get_error_message(),
+ 'filename' => $_FILES['async-upload']['name'],
+ )
) );
+
+ wp_die();
}
if ( isset( $post_data['context'] ) && isset( $post_data['theme'] ) ) {
@@ -1885,7 +2069,12 @@ function wp_ajax_upload_attachment() {
if ( ! $attachment = wp_prepare_attachment_for_js( $attachment_id ) )
wp_die();
- wp_send_json_success( $attachment );
+ echo wp_json_encode( array(
+ 'success' => true,
+ 'data' => $attachment,
+ ) );
+
+ wp_die();
}
/**
@@ -2029,6 +2218,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;
@@ -2047,11 +2237,11 @@ function wp_ajax_wp_fullscreen_save_post() {
}
if ( $post ) {
- $last_date = mysql2date( get_option('date_format'), $post->post_modified );
- $last_time = mysql2date( get_option('time_format'), $post->post_modified );
+ $last_date = mysql2date( __( 'F j, Y' ), $post->post_modified );
+ $last_time = mysql2date( __( 'g:i a' ), $post->post_modified );
} else {
- $last_date = date_i18n( get_option('date_format') );
- $last_time = date_i18n( get_option('time_format') );
+ $last_date = date_i18n( __( 'F j, Y' ) );
+ $last_time = date_i18n( __( 'g:i a' ) );
}
if ( $last_id = get_post_meta( $post_id, '_edit_last', true ) ) {
@@ -2159,11 +2349,17 @@ function wp_ajax_query_attachments() {
wp_send_json_error();
$query = isset( $_REQUEST['query'] ) ? (array) $_REQUEST['query'] : array();
- $query = array_intersect_key( $query, array_flip( array(
+ $keys = array(
's', 'order', 'orderby', 'posts_per_page', 'paged', 'post_mime_type',
'post_parent', 'post__in', 'post__not_in', 'year', 'monthnum'
- ) ) );
+ );
+ foreach ( get_taxonomies_for_attachments( 'objects' ) as $t ) {
+ if ( $t->query_var && isset( $query[ $t->query_var ] ) ) {
+ $keys[] = $t->query_var;
+ }
+ }
+ $query = array_intersect_key( $query, array_flip( $keys ) );
$query['post_type'] = 'attachment';
if ( MEDIA_TRASH
&& ! empty( $_REQUEST['query']['post_status'] )
@@ -2218,6 +2414,9 @@ function wp_ajax_save_attachment() {
if ( 'attachment' != $post['post_type'] )
wp_send_json_error();
+ if ( isset( $changes['parent'] ) )
+ $post['post_parent'] = $changes['parent'];
+
if ( isset( $changes['title'] ) )
$post['post_title'] = $changes['title'];
@@ -2238,7 +2437,7 @@ function wp_ajax_save_attachment() {
}
}
- if ( 0 === strpos( $post['post_mime_type'], 'audio/' ) ) {
+ if ( wp_attachment_is( 'audio', $post['ID'] ) ) {
$changed = false;
$id3data = wp_get_attachment_metadata( $post['ID'] );
if ( ! is_array( $id3data ) ) {
@@ -2378,14 +2577,8 @@ function wp_ajax_send_attachment_to_editor() {
}
}
- $rel = $url = '';
- $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 )
- $rel = ' rel="attachment wp-att-' . $id . '"';
- $html = '' . $html . '';
- }
+ $url = empty( $attachment['url'] ) ? '' : $attachment['url'];
+ $rel = ( strpos( $url, 'attachment_id') || get_attachment_link( $id ) == $url );
remove_filter( 'media_send_to_editor', 'image_media_send_to_editor' );
@@ -2393,11 +2586,24 @@ function wp_ajax_send_attachment_to_editor() {
$align = isset( $attachment['align'] ) ? $attachment['align'] : 'none';
$size = isset( $attachment['image-size'] ) ? $attachment['image-size'] : 'medium';
$alt = isset( $attachment['image_alt'] ) ? $attachment['image_alt'] : '';
+
+ // No whitespace-only captions.
$caption = isset( $attachment['post_excerpt'] ) ? $attachment['post_excerpt'] : '';
+ if ( '' === trim( $caption ) ) {
+ $caption = '';
+ }
+
$title = ''; // We no longer insert title tags into tags, as they are redundant.
- $html = get_image_send_to_editor( $id, $caption, $title, $align, $url, (bool) $rel, $size, $alt );
- } elseif ( 'video' === substr( $post->post_mime_type, 0, 5 ) || 'audio' === substr( $post->post_mime_type, 0, 5 ) ) {
+ $html = get_image_send_to_editor( $id, $caption, $title, $align, $url, $rel, $size, $alt );
+ } elseif ( wp_attachment_is( 'video', $post ) || wp_attachment_is( 'audio', $post ) ) {
$html = stripslashes_deep( $_POST['html'] );
+ } else {
+ $html = isset( $attachment['post_title'] ) ? $attachment['post_title'] : '';
+ $rel = $rel ? ' rel="attachment wp-att-' . $id . '"' : ''; // Hard-coded string, $id is already sanitized
+
+ if ( ! empty( $url ) ) {
+ $html = '' . $html . '';
+ }
}
/** This filter is documented in wp-admin/includes/media.php */
@@ -2417,6 +2623,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;
@@ -2432,8 +2641,8 @@ function wp_ajax_send_link_to_editor() {
if ( ! $src = esc_url_raw( $src ) )
wp_send_json_error();
- if ( ! $title = trim( wp_unslash( $_POST['title'] ) ) )
- $title = wp_basename( $src );
+ if ( ! $link_text = trim( wp_unslash( $_POST['link_text'] ) ) )
+ $link_text = wp_basename( $src );
$post = get_post( isset( $_POST['post_id'] ) ? $_POST['post_id'] : 0 );
@@ -2446,8 +2655,8 @@ function wp_ajax_send_link_to_editor() {
if ( $check_embed !== $fallback ) {
// TinyMCE view for [embed] will parse this
$html = '[embed]' . $src . '[/embed]';
- } elseif ( $title ) {
- $html = '' . $title . '';
+ } elseif ( $link_text ) {
+ $html = '' . $link_text . '';
} else {
$html = '';
}
@@ -2459,7 +2668,7 @@ function wp_ajax_send_link_to_editor() {
$type = $ext_type;
/** This filter is documented in wp-admin/includes/media.php */
- $html = apply_filters( $type . '_send_to_editor_url', $html, $src, $title );
+ $html = apply_filters( $type . '_send_to_editor_url', $html, $src, $link_text );
wp_send_json_success( $html );
}
@@ -2472,34 +2681,43 @@ 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.
*
* @since 3.6.0
*
- * @param array|object $response The Heartbeat response object or array.
- * @param array $data The $_POST data sent.
- * @param string $screen_id The screen id.
+ * @param array $response The Heartbeat response.
+ * @param array $data The $_POST data sent.
+ * @param string $screen_id The screen id.
*/
$response = apply_filters( 'heartbeat_received', $response, $data, $screen_id );
}
@@ -2509,8 +2727,8 @@ function wp_ajax_heartbeat() {
*
* @since 3.6.0
*
- * @param array|object $response The Heartbeat response object or array.
- * @param string $screen_id The screen id.
+ * @param array $response The Heartbeat response.
+ * @param string $screen_id The screen id.
*/
$response = apply_filters( 'heartbeat_send', $response, $screen_id );
@@ -2521,15 +2739,15 @@ function wp_ajax_heartbeat() {
*
* @since 3.6.0
*
- * @param array|object $response The Heartbeat response object or array.
- * @param string $screen_id The screen id.
+ * @param array $response The Heartbeat response.
+ * @param string $screen_id The screen id.
*/
do_action( 'heartbeat_tick', $response, $screen_id );
// Send the current time according to the server
$response['server_time'] = time();
- wp_send_json($response);
+ wp_send_json( $response );
}
/**
@@ -2543,7 +2761,7 @@ function wp_ajax_get_revision_diffs() {
if ( ! $post = get_post( (int) $_REQUEST['post_id'] ) )
wp_send_json_error();
- if ( ! current_user_can( 'read_post', $post->ID ) )
+ if ( ! current_user_can( 'edit_post', $post->ID ) )
wp_send_json_error();
// Really just pre-loading the cache here.
@@ -2569,6 +2787,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;
@@ -2581,14 +2801,22 @@ function wp_ajax_save_user_color_scheme() {
wp_send_json_error();
}
+ $previous_color_scheme = get_user_meta( get_current_user_id(), 'admin_color', true );
update_user_meta( get_current_user_id(), 'admin_color', $color_scheme );
- wp_send_json_success();
+
+ wp_send_json_success( array(
+ 'previousScheme' => 'admin-color-' . $previous_color_scheme,
+ 'currentScheme' => 'admin-color-' . $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;
@@ -2602,6 +2830,13 @@ function wp_ajax_query_themes() {
'fields' => $theme_field_defaults
) );
+ if ( isset( $args['browse'] ) && 'favorites' === $args['browse'] && ! isset( $args['user'] ) ) {
+ $user = get_user_option( 'wporg_favorites' );
+ if ( $user ) {
+ $args['user'] = $user;
+ }
+ }
+
$old_filter = isset( $args['browse'] ) ? $args['browse'] : 'search';
/** This filter is documented in wp-admin/includes/class-wp-theme-install-list-table.php */
@@ -2624,7 +2859,8 @@ function wp_ajax_query_themes() {
$theme->author = wp_kses( $theme->author, $themes_allowedtags );
$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->stars = wp_star_rating( array( 'rating' => $theme->rating, 'type' => 'percent', 'number' => $theme->num_ratings, 'echo' => false ) );
+ $theme->num_ratings = number_format_i18n( $theme->num_ratings );
$theme->preview_url = set_url_scheme( $theme->preview_url );
}
@@ -2636,8 +2872,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;
@@ -2651,13 +2888,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 );
@@ -2668,7 +2915,7 @@ function wp_ajax_parse_embed() {
}
}
- if ( ! $parsed ) {
+ if ( $url && ! $parsed ) {
$parsed = $wp_embed->run_shortcode( $shortcode );
}
@@ -2710,25 +2957,42 @@ 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;
- if ( ! $post = get_post( (int) $_POST['post_ID'] ) ) {
+ if ( empty( $_POST['shortcode'] ) ) {
wp_send_json_error();
}
- if ( empty( $_POST['shortcode'] ) || ! current_user_can( 'edit_post', $post->ID ) ) {
- wp_send_json_error();
+ $shortcode = wp_unslash( $_POST['shortcode'] );
+
+ if ( ! empty( $_POST['post_ID'] ) ) {
+ $post = get_post( (int) $_POST['post_ID'] );
}
- setup_postdata( $post );
- $shortcode = do_shortcode( wp_unslash( $_POST['shortcode'] ) );
+ // the embed shortcode requires a post
+ if ( ! $post || ! current_user_can( 'edit_post', $post->ID ) ) {
+ if ( 'embed' === $shortcode ) {
+ wp_send_json_error();
+ }
+ } else {
+ setup_postdata( $post );
+ }
- if ( empty( $shortcode ) ) {
+ $parsed = do_shortcode( $shortcode );
+
+ if ( empty( $parsed ) ) {
wp_send_json_error( array(
'type' => 'no-items',
'message' => __( 'No items found.' ),
@@ -2748,14 +3012,14 @@ function wp_ajax_parse_media_shortcode() {
ob_start();
- echo $shortcode;
+ echo $parsed;
if ( 'playlist' === $_REQUEST['type'] ) {
wp_underscore_playlist_templates();
wp_print_scripts( 'wp-playlist' );
} else {
- wp_print_scripts( 'wp-mediaelement' );
+ wp_print_scripts( array( 'froogaloop', 'wp-mediaelement' ) );
}
wp_send_json_success( array(
@@ -2770,7 +3034,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 ) ) {
@@ -2793,9 +3056,274 @@ function wp_ajax_destroy_sessions() {
$message = __( 'You are now logged out everywhere else.' );
} else {
$sessions->destroy_all();
- /* translators: 1: User's display name. */
+ /* translators: 1: User's display name. */
$message = sprintf( __( '%s has been logged out.' ), $user->display_name );
}
wp_send_json_success( array( 'message' => $message ) );
}
+
+
+/**
+ * AJAX handler for updating a plugin.
+ *
+ * @since 4.2.0
+ *
+ * @see Plugin_Upgrader
+ */
+function wp_ajax_update_plugin() {
+ global $wp_filesystem;
+
+ $plugin = urldecode( $_POST['plugin'] );
+
+ $status = array(
+ 'update' => 'plugin',
+ 'plugin' => $plugin,
+ 'slug' => sanitize_key( $_POST['slug'] ),
+ '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 for this site.' );
+ wp_send_json_error( $status );
+ }
+
+ check_ajax_referer( 'updates' );
+
+ include_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
+
+ wp_update_plugins();
+
+ $skin = new Automatic_Upgrader_Skin();
+ $upgrader = new Plugin_Upgrader( $skin );
+ $result = $upgrader->bulk_upgrade( array( $plugin ) );
+
+ 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 );
+
+ /*
+ * If the `update_plugins` site transient is empty (e.g. when you update
+ * two plugins in quick succession before the transient repopulates),
+ * this may be the return.
+ *
+ * Preferably something can be done to ensure `update_plugins` isn't empty.
+ * For now, surface some sort of error here.
+ */
+ if ( $plugin_update_data === true ) {
+ $status['error'] = __( 'Plugin update failed.' );
+ wp_send_json_error( $status );
+ }
+
+ $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'] );
+ }
+
+ wp_send_json_success( $status );
+ } else if ( is_wp_error( $result ) ) {
+ $status['error'] = $result->get_error_message();
+ wp_send_json_error( $status );
+
+ } 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 );
+
+ } else {
+ // An unhandled error occured
+ $status['error'] = __( 'Plugin update failed.' );
+ wp_send_json_error( $status );
+ }
+}
+
+/**
+ * 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'] ) ) {
+ include( ABSPATH . 'wp-admin/includes/class-wp-press-this.php' );
+ }
+
+ $GLOBALS['wp_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'] ) ) {
+ include( ABSPATH . 'wp-admin/includes/class-wp-press-this.php' );
+ }
+
+ $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 = wp_get_attachment_url( $attachment_id );
+ $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 ) );
+}
+
+/**
+ * Ajax handler for generating a password.
+ *
+ * @since 4.4.0
+ */
+function wp_ajax_generate_password() {
+ wp_send_json_success( wp_generate_password( 24 ) );
+}
+
+/**
+ * Ajax handler for saving the user's WordPress.org username.
+ *
+ * @since 4.4.0
+ */
+function wp_ajax_save_wporg_username() {
+ if ( ! current_user_can( 'install_themes' ) && ! current_user_can( 'install_plugins' ) ) {
+ wp_send_json_error();
+ }
+
+ check_ajax_referer( 'save_wporg_username_' . get_current_user_id() );
+
+ $username = isset( $_REQUEST['username'] ) ? wp_unslash( $_REQUEST['username'] ) : false;
+
+ if ( ! $username ) {
+ wp_send_json_error();
+ }
+
+ wp_send_json_success( update_user_meta( get_current_user_id(), 'wporg_favorites', $username ) );
+}