GC_Customize_Manager::handle_load_themes_request()

最后更新于:2021-11-27 01:02:01

GC_Customize_Manager::handle_load_themes_request()

Load themes into the theme browsing/installation UI.

源文件

文件: gc-includes/class-gc-customize-manager.php

	public function handle_load_themes_request() {
		check_ajax_referer( 'switch_themes', 'nonce' );

		if ( ! current_user_can( 'switch_themes' ) ) {
			gc_die( -1 );
		}

		if ( empty( $_POST['theme_action'] ) ) {
			gc_send_json_error( 'missing_theme_action' );
		}
		$theme_action = sanitize_key( $_POST['theme_action'] );
		$themes       = array();
		$args         = array();

		// Define query filters based on user input.
		if ( ! array_key_exists( 'search', $_POST ) ) {
			$args['search'] = '';
		} else {
			$args['search'] = sanitize_text_field( gc_unslash( $_POST['search'] ) );
		}

		if ( ! array_key_exists( 'tags', $_POST ) ) {
			$args['tag'] = '';
		} else {
			$args['tag'] = array_map( 'sanitize_text_field', gc_unslash( (array) $_POST['tags'] ) );
		}

		if ( ! array_key_exists( 'page', $_POST ) ) {
			$args['page'] = 1;
		} else {
			$args['page'] = absint( $_POST['page'] );
		}

		require_once ABSPATH . 'gc-admin/includes/theme.php';

		if ( 'installed' === $theme_action ) {

			// Load all installed themes from gc_prepare_themes_for_js().
			$themes = array( 'themes' => gc_prepare_themes_for_js() );
			foreach ( $themes['themes'] as &$theme ) {
				$theme['type']   = 'installed';
				$theme['active'] = ( isset( $_POST['customized_theme'] ) && $_POST['customized_theme'] === $theme['id'] );
			}
		} elseif ( 'gcorg' === $theme_action ) {

			// Load GeChiUI.org themes from the .org API and normalize data to match installed theme objects.
			if ( ! current_user_can( 'install_themes' ) ) {
				gc_die( -1 );
			}

			// Arguments for all queries.
			$gcorg_args = array(
				'per_page' => 100,
				'fields'   => array(
					'reviews_url' => true, // Explicitly request the reviews URL to be linked from the customizer.
				),
			);

			$args = array_merge( $gcorg_args, $args );

			if ( '' === $args['search'] && '' === $args['tag'] ) {
				$args['browse'] = 'new'; // Sort by latest themes by default.
			}

			// Load themes from the .org API.
			$themes = themes_api( 'query_themes', $args );
			if ( is_gc_error( $themes ) ) {
				gc_send_json_error();
			}

			// This list matches the allowed tags in gc-admin/includes/theme-install.php.
			$themes_allowedtags                     = array_fill_keys(
				array( 'a', 'abbr', 'acronym', 'code', 'pre', 'em', 'strong', 'div', 'p', 'ul', 'ol', 'li', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'img' ),
				array()
			);
			$themes_allowedtags['a']                = array_fill_keys( array( 'href', 'title', 'target' ), true );
			$themes_allowedtags['acronym']['title'] = true;
			$themes_allowedtags['abbr']['title']    = true;
			$themes_allowedtags['img']              = array_fill_keys( array( 'src', 'class', 'alt' ), true );

			// Prepare a list of installed themes to check against before the loop.
			$installed_themes = array();
			$gc_themes        = gc_get_themes();
			foreach ( $gc_themes as $theme ) {
				$installed_themes[] = $theme->get_stylesheet();
			}
			$update_php = network_admin_url( 'update.php?action=install-theme' );

			// Set up properties for themes available on GeChiUI.org.
			foreach ( $themes->themes as &$theme ) {
				$theme->install_url = add_query_arg(
					array(
						'theme'    => $theme->slug,
						'_gcnonce' => gc_create_nonce( 'install-theme_' . $theme->slug ),
					),
					$update_php
				);

				$theme->name        = gc_kses( $theme->name, $themes_allowedtags );
				$theme->version     = gc_kses( $theme->version, $themes_allowedtags );
				$theme->description = gc_kses( $theme->description, $themes_allowedtags );
				$theme->stars       = gc_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 );

				// Handle themes that are already installed as installed themes.
				if ( in_array( $theme->slug, $installed_themes, true ) ) {
					$theme->type = 'installed';
				} else {
					$theme->type = $theme_action;
				}

				// Set active based on customized theme.
				$theme->active = ( isset( $_POST['customized_theme'] ) && $_POST['customized_theme'] === $theme->slug );

				// Map available theme properties to installed theme properties.
				$theme->id            = $theme->slug;
				$theme->screenshot    = array( $theme->screenshot_url );
				$theme->authorAndUri  = gc_kses( $theme->author['display_name'], $themes_allowedtags );
				$theme->compatibleGC  = is_gc_version_compatible( $theme->requires ); // phpcs:ignore GeChiUI.NamingConventions.ValidVariableName
				$theme->compatiblePHP = is_php_version_compatible( $theme->requires_php ); // phpcs:ignore GeChiUI.NamingConventions.ValidVariableName

				if ( isset( $theme->parent ) ) {
					$theme->parent = $theme->parent['slug'];
				} else {
					$theme->parent = false;
				}
				unset( $theme->slug );
				unset( $theme->screenshot_url );
				unset( $theme->author );
			} // End foreach().
		} // End if().

		/**
		 * Filters the theme data loaded in the customizer.
		 *
		 * This allows theme data to be loading from an external source,
		 * or modification of data loaded from `gc_prepare_themes_for_js()`
		 * or GeChiUI.org via `themes_api()`.
		 *
		 * @since 4.9.0
		 *
		 * @see gc_prepare_themes_for_js()
		 * @see themes_api()
		 * @see GC_Customize_Manager::__construct()
		 *
		 * @param array                $themes  Nested array of theme data.
		 * @param array                $args    List of arguments, such as page, search term, and tags to query for.
		 * @param GC_Customize_Manager $manager Instance of Customize manager.
		 */
		$themes = apply_filters( 'customize_load_themes', $themes, $args, $this );

		gc_send_json_success( $themes );
	}