Source
File: wp-admin/includes/theme.php
function wp_prepare_themes_for_js( $themes = null ) {
$current_theme = get_stylesheet();
/**
* Filters theme data before it is prepared for JavaScript.
*
* Passing a non-empty array will result in wp_prepare_themes_for_js() returning
* early with that value instead.
*
* @since 4.2.0
*
* @param array $prepared_themes An associative array of theme data. Default empty array.
* @param WP_Theme[]|null $themes An array of theme objects to prepare, if any.
* @param string $current_theme The current theme slug.
*/
$prepared_themes = (array) apply_filters( 'pre_prepare_themes_for_js', array(), $themes, $current_theme );
if ( ! empty( $prepared_themes ) ) {
return $prepared_themes;
}
// Make sure the current theme is listed first.
$prepared_themes[ $current_theme ] = array();
if ( null === $themes ) {
$themes = wp_get_themes( array( 'allowed' => true ) );
if ( ! isset( $themes[ $current_theme ] ) ) {
$themes[ $current_theme ] = wp_get_theme();
}
}
$updates = array();
$no_updates = array();
if ( current_user_can( 'update_themes' ) ) {
$updates_transient = get_site_transient( 'update_themes' );
if ( isset( $updates_transient->response ) ) {
$updates = $updates_transient->response;
}
if ( isset( $updates_transient->no_update ) ) {
$no_updates = $updates_transient->no_update;
}
}
WP_Theme::sort_by_name( $themes );
$parents = array();
$auto_updates = (array) get_site_option( 'auto_update_themes', array() );
foreach ( $themes as $theme ) {
$slug = $theme->get_stylesheet();
$encoded_slug = urlencode( $slug );
$parent = false;
if ( $theme->parent() ) {
$parent = $theme->parent();
$parents[ $slug ] = $parent->get_stylesheet();
$parent = $parent->display( 'Name' );
}
$customize_action = null;
if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) {
$customize_action = esc_url(
add_query_arg(
array(
'return' => urlencode( esc_url_raw( remove_query_arg( wp_removable_query_args(), wp_unslash( $_SERVER['REQUEST_URI'] ) ) ) ),
),
wp_customize_url( $slug )
)
);
}
$update_requires_wp = isset( $updates[ $slug ]['requires'] ) ? $updates[ $slug ]['requires'] : null;
$update_requires_php = isset( $updates[ $slug ]['requires_php'] ) ? $updates[ $slug ]['requires_php'] : null;
$auto_update = in_array( $slug, $auto_updates, true );
$auto_update_action = $auto_update ? 'disable-auto-update' : 'enable-auto-update';
if ( isset( $updates[ $slug ] ) ) {
$auto_update_supported = true;
$auto_update_filter_payload = (object) $updates[ $slug ];
} elseif ( isset( $no_updates[ $slug ] ) ) {
$auto_update_supported = true;
$auto_update_filter_payload = (object) $no_updates[ $slug ];
} else {
$auto_update_supported = false;
/*
* Create the expected payload for the auto_update_theme filter, this is the same data
* as contained within $updates or $no_updates but used when the Theme is not known.
*/
$auto_update_filter_payload = (object) array(
'theme' => $slug,
'new_version' => $theme->get( 'Version' ),
'url' => '',
'package' => '',
'requires' => $theme->get( 'RequiresWP' ),
'requires_php' => $theme->get( 'RequiresPHP' ),
);
}
$type = 'theme';
/** This filter is documented in wp-admin/includes/class-wp-automatic-updater.php */
$auto_update_forced = apply_filters( "auto_update_{$type}", null, $auto_update_filter_payload );
$prepared_themes[ $slug ] = array(
'id' => $slug,
'name' => $theme->display( 'Name' ),
'screenshot' => array( $theme->get_screenshot() ), // @todo Multiple screenshots.
'description' => $theme->display( 'Description' ),
'author' => $theme->display( 'Author', false, true ),
'authorAndUri' => $theme->display( 'Author' ),
'tags' => $theme->display( 'Tags' ),
'version' => $theme->get( 'Version' ),
'compatibleWP' => is_wp_version_compatible( $theme->get( 'RequiresWP' ) ),
'compatiblePHP' => is_php_version_compatible( $theme->get( 'RequiresPHP' ) ),
'updateResponse' => array(
'compatibleWP' => is_wp_version_compatible( $update_requires_wp ),
'compatiblePHP' => is_php_version_compatible( $update_requires_php ),
),
'parent' => $parent,
'active' => $slug === $current_theme,
'hasUpdate' => isset( $updates[ $slug ] ),
'hasPackage' => isset( $updates[ $slug ] ) && ! empty( $updates[ $slug ]['package'] ),
'update' => get_theme_update_available( $theme ),
'autoupdate' => array(
'enabled' => $auto_update || $auto_update_forced,
'supported' => $auto_update_supported,
'forced' => $auto_update_forced,
),
'actions' => array(
'activate' => current_user_can( 'switch_themes' ) ? wp_nonce_url( admin_url( 'themes.php?action=activate&stylesheet=' . $encoded_slug ), 'switch-theme_' . $slug ) : null,
'customize' => $customize_action,
'delete' => current_user_can( 'delete_themes' ) ? wp_nonce_url( admin_url( 'themes.php?action=delete&stylesheet=' . $encoded_slug ), 'delete-theme_' . $slug ) : null,
'autoupdate' => wp_is_auto_update_enabled_for_type( 'theme' ) && ! is_multisite() && current_user_can( 'update_themes' )
? wp_nonce_url( admin_url( 'themes.php?action=' . $auto_update_action . '&stylesheet=' . $encoded_slug ), 'updates' )
: null,
),
);
}
// Remove 'delete' action if theme has an active child.
if ( ! empty( $parents ) && array_key_exists( $current_theme, $parents ) ) {
unset( $prepared_themes[ $parents[ $current_theme ] ]['actions']['delete'] );
}
/**
* Filters the themes prepared for JavaScript, for themes.php.
*
* Could be useful for changing the order, which is by name by default.
*
* @since 3.8.0
*
* @param array $prepared_themes Array of theme data.
*/
$prepared_themes = apply_filters( 'wp_prepare_themes_for_js', $prepared_themes );
$prepared_themes = array_values( $prepared_themes );
return array_filter( $prepared_themes );
}