Theme Installer: Revert to proxying through PHP for WordPress.org API requests.
This is to ensure we have valid installation nonces, though we've run into this as a problem previously (see #27639, #27581, #27055). A tad slower, but we gained speed in 3.9 by simplifying the request made to the API. props ocean90. fixes #27798. Built from https://develop.svn.wordpress.org/trunk@28126 git-svn-id: http://core.svn.wordpress.org/trunk@27957 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
parent
d1e72b8e20
commit
9f81d0526e
|
@ -58,7 +58,7 @@ $core_actions_post = array(
|
|||
'wp-remove-post-lock', 'dismiss-wp-pointer', 'upload-attachment', 'get-attachment',
|
||||
'query-attachments', 'save-attachment', 'save-attachment-compat', 'send-link-to-editor',
|
||||
'send-attachment-to-editor', 'save-attachment-order', 'heartbeat', 'get-revision-diffs',
|
||||
'save-user-color-scheme', 'update-widget',
|
||||
'save-user-color-scheme', 'update-widget', 'query-themes',
|
||||
);
|
||||
|
||||
// Register core Ajax calls.
|
||||
|
|
|
@ -2204,3 +2204,48 @@ function wp_ajax_save_user_color_scheme() {
|
|||
update_user_meta( get_current_user_id(), 'admin_color', $color_scheme );
|
||||
wp_send_json_success();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get themes from themes_api().
|
||||
*
|
||||
* @since 3.9.0
|
||||
*/
|
||||
function wp_ajax_query_themes() {
|
||||
global $themes_allowedtags, $theme_field_defaults;
|
||||
|
||||
if ( ! current_user_can( 'install_themes' ) ) {
|
||||
wp_send_json_error();
|
||||
}
|
||||
|
||||
$args = wp_parse_args( wp_unslash( $_REQUEST['request'] ), array(
|
||||
'per_page' => 20,
|
||||
'fields' => $theme_field_defaults
|
||||
) );
|
||||
|
||||
$old_filter = isset( $args['browse'] ) ? $args['browse'] : 'search';
|
||||
|
||||
/** This filter is documented in wp-admin/includes/class-wp-theme-install-list-table.php */
|
||||
$args = apply_filters( 'install_themes_table_api_args_' . $old_filter, $args );
|
||||
|
||||
$api = themes_api( 'query_themes', $args );
|
||||
|
||||
if ( is_wp_error( $api ) ) {
|
||||
wp_send_json_error();
|
||||
}
|
||||
|
||||
$update_php = self_admin_url( 'update.php?action=install-theme' );
|
||||
foreach ( $api->themes as &$theme ) {
|
||||
$theme->install_url = add_query_arg( array(
|
||||
'theme' => $theme->slug,
|
||||
'_wpnonce' => wp_create_nonce( 'install-theme_' . $theme->slug )
|
||||
), $update_php );
|
||||
|
||||
$theme->name = wp_kses( $theme->name, $themes_allowedtags );
|
||||
$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 ) );
|
||||
}
|
||||
|
||||
wp_send_json_success( $api );
|
||||
}
|
||||
|
|
|
@ -346,7 +346,9 @@ function themes_api( $action, $args = null ) {
|
|||
$request = wp_remote_post( $url, $args );
|
||||
|
||||
if ( $ssl && is_wp_error( $request ) ) {
|
||||
trigger_error( __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the <a href="https://wordpress.org/support/">support forums</a>.' ) . ' ' . '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)', headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE );
|
||||
if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX ) {
|
||||
trigger_error( __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the <a href="https://wordpress.org/support/">support forums</a>.' ) . ' ' . '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)', headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE );
|
||||
}
|
||||
$request = wp_remote_post( $http_url, $args );
|
||||
}
|
||||
|
||||
|
|
|
@ -22,18 +22,7 @@ themes.Model = Backbone.Model.extend({
|
|||
// Adds attributes to the default data coming through the .org themes api
|
||||
// Map `id` to `slug` for shared code
|
||||
initialize: function() {
|
||||
var install, description;
|
||||
|
||||
// Install url for the theme
|
||||
// using the install nonce
|
||||
install = {
|
||||
action: 'install-theme',
|
||||
theme: this.get( 'slug' ),
|
||||
_wpnonce: themes.data.settings._nonceInstall
|
||||
};
|
||||
|
||||
// Build the url query
|
||||
install = themes.data.settings.updateURI + '?' + $.param( install );
|
||||
var description;
|
||||
|
||||
// If theme is already installed, set an attribute.
|
||||
if ( _.indexOf( themes.data.installedThemes, this.get( 'slug' ) ) !== -1 ) {
|
||||
|
@ -42,7 +31,6 @@ themes.Model = Backbone.Model.extend({
|
|||
|
||||
// Set the attributes
|
||||
this.set({
|
||||
installURI: ( this.get( 'slug' ) ) ? install : false,
|
||||
// slug is for installation, id is for existing.
|
||||
id: this.get( 'slug' ) || this.get( 'id' )
|
||||
});
|
||||
|
@ -225,7 +213,7 @@ themes.Collection = Backbone.Collection.extend({
|
|||
//
|
||||
// When we are missing a cache object we fire an apiCall()
|
||||
// which triggers events of `query:success` or `query:fail`
|
||||
query: function( request, action ) {
|
||||
query: function( request ) {
|
||||
/**
|
||||
* @static
|
||||
* @type Array
|
||||
|
@ -254,7 +242,7 @@ themes.Collection = Backbone.Collection.extend({
|
|||
|
||||
// Otherwise, send a new API call and add it to the cache.
|
||||
if ( ! query && ! isPaginated ) {
|
||||
query = this.apiCall( request, action ).done( function( data ) {
|
||||
query = this.apiCall( request ).done( function( data ) {
|
||||
|
||||
// Update the collection with the queried data.
|
||||
if ( data.themes ) {
|
||||
|
@ -262,11 +250,6 @@ themes.Collection = Backbone.Collection.extend({
|
|||
count = data.info.results;
|
||||
// Store the results and the query request
|
||||
queries.push( { themes: data.themes, request: request, total: count } );
|
||||
|
||||
} else if ( action ) {
|
||||
self.reset( data );
|
||||
count = 1;
|
||||
self.trigger( 'query:theme' );
|
||||
}
|
||||
|
||||
// Trigger a collection refresh event
|
||||
|
@ -284,7 +267,7 @@ themes.Collection = Backbone.Collection.extend({
|
|||
} else {
|
||||
// If it's a paginated request we need to fetch more themes...
|
||||
if ( isPaginated ) {
|
||||
return this.apiCall( request, action, isPaginated ).done( function( data ) {
|
||||
return this.apiCall( request, isPaginated ).done( function( data ) {
|
||||
// Add the new themes to the current collection
|
||||
// @todo update counter
|
||||
self.add( data.themes );
|
||||
|
@ -310,12 +293,13 @@ themes.Collection = Backbone.Collection.extend({
|
|||
this.count = query.total;
|
||||
}
|
||||
|
||||
this.reset( query.themes );
|
||||
if ( ! query.total ) {
|
||||
this.count = this.length;
|
||||
}
|
||||
|
||||
this.reset( query.themes );
|
||||
this.trigger( 'update' );
|
||||
this.trigger( 'query:success', this.count );
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -329,30 +313,23 @@ themes.Collection = Backbone.Collection.extend({
|
|||
},
|
||||
|
||||
// Send request to api.wordpress.org/themes
|
||||
apiCall: function( request, action, paginated ) {
|
||||
|
||||
// Send tags (and fields) as comma-separated to keep the JSONP query string short.
|
||||
if ( request.tag && _.isArray( request.tag ) ) {
|
||||
request.tag = request.tag.join( ',' );
|
||||
}
|
||||
|
||||
// Set request action
|
||||
if ( ! action ) {
|
||||
action = 'query_themes'
|
||||
}
|
||||
|
||||
// JSONP request to .org API
|
||||
return $.ajax({
|
||||
url: 'https://api.wordpress.org/themes/info/1.1/?callback=?',
|
||||
dataType: 'jsonp',
|
||||
timeout: 15000, // 15 seconds
|
||||
|
||||
// Request data
|
||||
apiCall: function( request, paginated ) {
|
||||
return wp.ajax.send( 'query-themes', {
|
||||
data: {
|
||||
action: action,
|
||||
// Request data
|
||||
request: _.extend({
|
||||
per_page: 72,
|
||||
fields: 'description,tested,requires,rating,downloaded,downloadLink,last_updated,homepage,num_ratings'
|
||||
per_page: 100,
|
||||
fields: {
|
||||
description: true,
|
||||
tested: true,
|
||||
requires: true,
|
||||
rating: true,
|
||||
downloaded: true,
|
||||
downloadLink: true,
|
||||
last_updated: true,
|
||||
homepage: true,
|
||||
num_ratings: true
|
||||
}
|
||||
}, request)
|
||||
},
|
||||
|
||||
|
@ -1567,7 +1544,11 @@ themes.view.Installer = themes.view.Appearance.extend({
|
|||
});
|
||||
},
|
||||
|
||||
backToFilters: function() {
|
||||
backToFilters: function( event ) {
|
||||
if ( event ) {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
$( 'body' ).removeClass( 'filters-applied' );
|
||||
},
|
||||
|
||||
|
@ -1634,8 +1615,8 @@ themes.RunInstaller = {
|
|||
// Handles `theme` route event
|
||||
// Queries the API for the passed theme slug
|
||||
themes.router.on( 'route:preview', function( slug ) {
|
||||
request.slug = slug;
|
||||
self.view.collection.query( request, 'theme_information' );
|
||||
request.theme = slug;
|
||||
self.view.collection.query( request );
|
||||
});
|
||||
|
||||
// Handles sorting / browsing routes
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -46,9 +46,7 @@ wp_localize_script( 'theme', '_wpThemeSettings', array(
|
|||
'isInstall' => true,
|
||||
'canInstall' => current_user_can( 'install_themes' ),
|
||||
'installURI' => current_user_can( 'install_themes' ) ? self_admin_url( 'theme-install.php' ) : null,
|
||||
'adminUrl' => parse_url( self_admin_url(), PHP_URL_PATH ),
|
||||
'updateURI' => self_admin_url( 'update.php' ),
|
||||
'_nonceInstall' => wp_create_nonce( 'install-theme' )
|
||||
'adminUrl' => parse_url( self_admin_url(), PHP_URL_PATH )
|
||||
),
|
||||
'l10n' => array(
|
||||
'addNew' => __( 'Add New Theme' ),
|
||||
|
@ -56,7 +54,7 @@ wp_localize_script( 'theme', '_wpThemeSettings', array(
|
|||
'searchPlaceholder' => __( 'Search themes...' ), // placeholder (no ellipsis)
|
||||
'upload' => __( 'Upload Theme' ),
|
||||
'back' => __( 'Back' ),
|
||||
'error' => sprintf( __( 'An unexpected error occurred and we can᾿t reach WordPress.org. If you continue to have problems, please try the <a href="%s">support forums</a>.' ), __( 'https://wordpress.org/support/' ) )
|
||||
'error' => __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the <a href="https://wordpress.org/support/">support forums</a>.' )
|
||||
),
|
||||
'installedThemes' => array_keys( $installed_themes ),
|
||||
'browse' => array(
|
||||
|
@ -199,7 +197,7 @@ if ( $tab ) {
|
|||
<h3 class="theme-name">{{ data.name }}</h3>
|
||||
|
||||
<div class="theme-actions">
|
||||
<a class="button button-primary" href="{{ data.installURI }}"><?php esc_html_e( 'Install' ); ?></a>
|
||||
<a class="button button-primary" href="{{ data.install_url }}"><?php esc_html_e( 'Install' ); ?></a>
|
||||
<a class="button button-secondary preview install-theme-preview" href="#"><?php esc_html_e( 'Preview' ); ?></a>
|
||||
</div>
|
||||
|
||||
|
@ -215,7 +213,7 @@ if ( $tab ) {
|
|||
<# if ( data.installed ) { #>
|
||||
<a href="#" class="button button-primary theme-install disabled"><?php _e( 'Installed' ); ?></a>
|
||||
<# } else { #>
|
||||
<a href="{{ data.installURI }}" class="button button-primary theme-install"><?php _e( 'Install' ); ?></a>
|
||||
<a href="{{ data.install_url }}" class="button button-primary theme-install"><?php _e( 'Install' ); ?></a>
|
||||
<# } #>
|
||||
</div>
|
||||
<div class="wp-full-overlay-sidebar-content">
|
||||
|
@ -233,7 +231,7 @@ if ( $tab ) {
|
|||
<span class="four"></span>
|
||||
<span class="five"></span>
|
||||
<# if ( data.num_ratings ) { #>
|
||||
<p class="ratings">({{ data.num_ratings }})</p>
|
||||
<p class="ratings">{{ data.num_ratings }}</p>
|
||||
<# } else { #>
|
||||
<p class="ratings"><?php _e( 'No ratings.' ); ?></p>
|
||||
<# } #>
|
||||
|
|
|
@ -202,7 +202,7 @@ if ( isset($_GET['action']) ) {
|
|||
|
||||
include_once ABSPATH . 'wp-admin/includes/theme-install.php'; //for themes_api..
|
||||
|
||||
check_admin_referer( 'install-theme' );
|
||||
check_admin_referer( 'install-theme_' . $theme );
|
||||
$api = themes_api('theme_information', array('slug' => $theme, 'fields' => array('sections' => false, 'tags' => false) ) ); //Save on a bit of bandwidth.
|
||||
|
||||
if ( is_wp_error($api) )
|
||||
|
|
Loading…
Reference in New Issue