WordPress Version: 6.3
/**
* Prepares themes for JavaScript.
*
* @since 3.8.0
*
* @param WP_Theme[] $themes Optional. Array of theme objects to prepare.
* Defaults to all allowed themes.
*
* @return array An associative array of theme data, sorted by name.
*/
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 active 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 active 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 (!is_multisite() && 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;
$can_edit_theme_options = current_user_can('edit_theme_options');
$can_customize = current_user_can('customize');
$is_block_theme = $theme->is_block_theme();
if ($is_block_theme && $can_edit_theme_options) {
$customize_action = admin_url('site-editor.php');
if ($current_theme !== $slug) {
$customize_action = add_query_arg('wp_theme_preview', $slug, $customize_action);
}
} elseif (!$is_block_theme && $can_customize && $can_edit_theme_options) {
$customize_action = wp_customize_url($slug);
}
if (null !== $customize_action) {
$customize_action = add_query_arg(array('return' => urlencode(sanitize_url(remove_query_arg(wp_removable_query_args(), wp_unslash($_SERVER['REQUEST_URI']))))), $customize_action);
$customize_action = esc_url($customize_action);
}
$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'));
}
$auto_update_forced = wp_is_auto_update_forced_for_item('theme', 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' => (!is_multisite() && 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),
'blockTheme' => $theme->is_block_theme(),
);
}
// 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);
}