Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Untangle theme screens #41374

Draft
wants to merge 34 commits into
base: trunk
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
aec7d11
Add Theme Install page
scruffian Jan 28, 2025
3415864
changelog
scruffian Jan 28, 2025
259aae7
add theme-install.php
scruffian Jan 28, 2025
1d7d077
add theme-install.php
scruffian Jan 28, 2025
ffec564
Make theme-install load
ryelle Jan 28, 2025
3edc01a
add js file
scruffian Jan 28, 2025
971a845
don't send simple site users to calypso for installed or activated th…
draganescu Jan 29, 2025
0c67014
changelog
draganescu Jan 29, 2025
6a10604
Use the page load hook to enqueue script
ryelle Jan 29, 2025
8342b7e
Ensure the custom JS is loaded after the core theme JS
ryelle Jan 29, 2025
6b1d85e
Update the router to use the custom page URL
ryelle Jan 29, 2025
ebbbef4
remove the theme showcase banner and link
draganescu Jan 29, 2025
1be87f1
Copy over atomic theme api customization
ryelle Jan 29, 2025
89d9ba1
Fork the core admin-ajax response to return regardless of install per…
ryelle Jan 29, 2025
2331013
Fix the URLs passed to the router
ryelle Jan 29, 2025
e16a87d
Replace the ajax request for the favorites username with patched version
ryelle Jan 31, 2025
0013535
Update comments to explicitly call out patched sections of ajax funct…
ryelle Jan 31, 2025
cf77993
Add filter to update the theme object before returning in ajax response
ryelle Jan 31, 2025
81d3c17
Use the correct theme slug for each environment
ryelle Jan 31, 2025
405cbb0
Add patched notes and remove hardcoded changes
ryelle Jan 31, 2025
8884b04
Add filters to the theme templates
ryelle Jan 31, 2025
9a83d3d
Add (unstyled) theme tier label
ryelle Jan 31, 2025
db48ebf
Remove the tier check at the API level
ryelle Jan 31, 2025
b76f129
Conditional theme activate button text depending of the user plan
matiasbenedetto Jan 31, 2025
39c2f50
Update "Activate" and "Install" URLs to use checkout if necessary
ryelle Feb 4, 2025
47e5bca
Update "Install" button text to "Upgrade to install", ensure only but…
ryelle Feb 4, 2025
f5f6f49
Fix duplicate ampersand in URL
ryelle Feb 4, 2025
2ccf4b2
Fix CSS on custom page by injected theme-install-php class
ryelle Feb 7, 2025
189c9a9
Switch installTheme handler to a noop, to prevent AJAX install request
ryelle Feb 7, 2025
a25b393
Apply the install button fix on preview too
ryelle Feb 7, 2025
3494763
Display a text saying if the theme is available on the plan or the us…
matiasbenedetto Feb 12, 2025
dc0a8e2
copying badge styles from Gutenberg's Badge component
matiasbenedetto Feb 12, 2025
08e7e23
add an upload button
scruffian Feb 11, 2025
26b7e86
fix a couple of PHP warnings
scruffian Feb 12, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: added

Add theme install page
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Copied from Gutenberg's Badge component. See:
* https://github.com/WordPress/gutenberg/blob/trunk/packages/components/src/badge/styles.scss

* The scss code was translated to plain css to make it work in wp-admin
*/

.components-badge {
background-color: color-mix(in srgb, #fff 90%, var(--base-color));
color: color-mix(in srgb, #000 50%, var(--base-color));
padding: 0 8px;
min-height: 24px;
max-width: 100%;
border-radius: 4px;
font-size: 12px;
font-weight: 400;
line-height: 1.4;
display: inline-flex;
align-items: center;
gap: 2px;
}

.components-badge.is-default {
background-color: #f0f0f0;
color: #2c3338;
}

.components-badge.has-icon {
padding-inline-start: 4px;
}

/* Color variants */
.components-badge.is-info {
--base-color: #3858e9;
}

.components-badge.is-warning {
--base-color: #f0b849;
}

.components-badge.is-error {
--base-color: #d63638;
}

.components-badge.is-success {
--base-color: #00a32a;
}

.components-badge__icon {
flex-shrink: 0;
}

.components-badge__content {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
<?php
/**
* Class WPCom_Themes_Api.
* Retrieves themes from the WordPress.com themes API.
*
* @package wpcom-themes
*/

/**
* Fetches themes from the WordPress.com themes API.
*/
class WPCom_Themes_Api {

/**
* The URL of the WordPress.com themes API.
*/
const WP_COM_THEMES_API_URL = 'https://public-api.wordpress.com/rest/v1.2/themes?http_envelope=1&page=1&number=1000';

/**
* The URL of the WordPress.com theme API.
*/
const WP_COM_THEME_API_URL = 'https://public-api.wordpress.com/rest/v1.2/themes/%s?http_envelope=1';

/**
* Cache handler.
*
* @var WPCom_Themes_Cache $cache
*/
private WPCom_Themes_Cache $cache;

Check failure on line 29 in projects/packages/jetpack-mu-wpcom/src/features/wpcom-themes/includes/class-wpcom-themes-api.php

View workflow job for this annotation

GitHub Actions / PHP lint (7.2)

Parse error: syntax error, unexpected 'WPCom_Themes_Cache' (T_STRING), expecting function (T_FUNCTION) or const (T_CONST)

Check failure on line 29 in projects/packages/jetpack-mu-wpcom/src/features/wpcom-themes/includes/class-wpcom-themes-api.php

View workflow job for this annotation

GitHub Actions / PHP Compatibility

Typed properties are not supported in PHP 7.3 or earlier (PHPCompatibility.Classes.NewTypedProperties.Found)

Check failure on line 29 in projects/packages/jetpack-mu-wpcom/src/features/wpcom-themes/includes/class-wpcom-themes-api.php

View workflow job for this annotation

GitHub Actions / dev branch for PHP 8.0

Typed properties are not supported in PHP 7.3 or earlier. Found: WPCom_Themes_Cache (PHPCompatibility.Classes.NewTypedProperties.Found)

Check failure on line 29 in projects/packages/jetpack-mu-wpcom/src/features/wpcom-themes/includes/class-wpcom-themes-api.php

View workflow job for this annotation

GitHub Actions / Static analysis

CompatError PhanCompatibleTypedProperty Cannot use typed properties before php 7.4. This property group has type \WPCom_Themes_Cache FAQ on Phan issues: pdWQjU-Jb-p2

Check failure on line 29 in projects/packages/jetpack-mu-wpcom/src/features/wpcom-themes/includes/class-wpcom-themes-api.php

View workflow job for this annotation

GitHub Actions / PHP lint (7.2)

Parse error: syntax error, unexpected 'WPCom_Themes_Cache' (T_STRING), expecting function (T_FUNCTION) or const (T_CONST)

Check failure on line 29 in projects/packages/jetpack-mu-wpcom/src/features/wpcom-themes/includes/class-wpcom-themes-api.php

View workflow job for this annotation

GitHub Actions / PHP Compatibility

Typed properties are not supported in PHP 7.3 or earlier (PHPCompatibility.Classes.NewTypedProperties.Found)

Check failure on line 29 in projects/packages/jetpack-mu-wpcom/src/features/wpcom-themes/includes/class-wpcom-themes-api.php

View workflow job for this annotation

GitHub Actions / dev branch for PHP 8.0

Typed properties are not supported in PHP 7.3 or earlier. Found: WPCom_Themes_Cache (PHPCompatibility.Classes.NewTypedProperties.Found)

Check failure on line 29 in projects/packages/jetpack-mu-wpcom/src/features/wpcom-themes/includes/class-wpcom-themes-api.php

View workflow job for this annotation

GitHub Actions / Static analysis

CompatError PhanCompatibleTypedProperty Cannot use typed properties before php 7.4. This property group has type \WPCom_Themes_Cache FAQ on Phan issues: pdWQjU-Jb-p2

/**
* Class constructor.
*
* @param WPCom_Themes_Cache $cache Cache handler.
*/
public function __construct( WPCom_Themes_Cache $cache ) {
$this->cache = $cache;
}

/**
* Returns an array of themes fetched from the WordPress.com themes API.
* Caching is used to avoid fetching the themes on every request.
*
* @param string $cache_key Key of the cache where the API response will be cached.
* @param array $params Query params to pass to the API URL.
*
* @return array<stdClass> An array with all the WPCom themes.
*/
protected function fetch_themes( string $cache_key, array $params = array() ): array {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function calls the API through HTTP. On Simple sites we can call the code directly, which means that we don't need to wait for an HTTP request. I think we can do this using Client::wpcom_json_api_request_as_blog

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 458df77 - we should now be able to modify the API and see the results when testing.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reverted this because it was broken, but it should give you an idea how to do it!

$url = add_query_arg( $params, self::WP_COM_THEMES_API_URL );

return $this->cache->run_cached(
$cache_key,
fn() => $this->handle_request( $url )->themes ?? array()

Check failure on line 54 in projects/packages/jetpack-mu-wpcom/src/features/wpcom-themes/includes/class-wpcom-themes-api.php

View workflow job for this annotation

GitHub Actions / dev branch for PHP 8.0

The "fn" keyword for arrow functions is not present in PHP version 7.3 or earlier (PHPCompatibility.Keywords.NewKeywords.t_fnFound)

Check failure on line 54 in projects/packages/jetpack-mu-wpcom/src/features/wpcom-themes/includes/class-wpcom-themes-api.php

View workflow job for this annotation

GitHub Actions / Static analysis

CompatError PhanCompatibleArrowFunction Cannot use arrow functions before php 7.4 in (fn) FAQ on Phan issues: pdWQjU-Jb-p2

Check failure on line 54 in projects/packages/jetpack-mu-wpcom/src/features/wpcom-themes/includes/class-wpcom-themes-api.php

View workflow job for this annotation

GitHub Actions / dev branch for PHP 8.0

The "fn" keyword for arrow functions is not present in PHP version 7.3 or earlier (PHPCompatibility.Keywords.NewKeywords.t_fnFound)

Check failure on line 54 in projects/packages/jetpack-mu-wpcom/src/features/wpcom-themes/includes/class-wpcom-themes-api.php

View workflow job for this annotation

GitHub Actions / Static analysis

CompatError PhanCompatibleArrowFunction Cannot use arrow functions before php 7.4 in (fn) FAQ on Phan issues: pdWQjU-Jb-p2
);
}

/**
* Fetches the response from the given URL.
*
* @param string $url URL to fetch.
*
* @return ?stdClass Response body.
*/
protected function handle_request( string $url ): ?stdClass {
$response = wp_remote_get( esc_url_raw( $url ) );
if ( 200 === wp_remote_retrieve_response_code( $response ) ) {
$body_json = json_decode( wp_remote_retrieve_body( $response ) );

if ( isset( $body_json->body ) ) {
return $body_json->body;
}
}

return null;
}

/**
* Returns all the WP.com themes.
*
* @return array<stdClass> An array with all the WPCom themes.
*/
public function fetch_all_non_delisted_themes(): array {
return $this->fetch_themes( 'wpcom-themes-all' );
}

/**
* Returns the WP.com theme with the given slug.
*
* @param string $slug Theme slug.
*
* @return stdClass|null A WPCom theme object or null if not found.
*/
public function fetch_theme( string $slug ): ?stdClass {
$url = sprintf( self::WP_COM_THEME_API_URL, $slug );

$theme = $this->cache->run_cached(
'wpcom-themes-' . $slug,
fn() => $this->handle_request( $url )

Check failure on line 99 in projects/packages/jetpack-mu-wpcom/src/features/wpcom-themes/includes/class-wpcom-themes-api.php

View workflow job for this annotation

GitHub Actions / dev branch for PHP 8.0

The "fn" keyword for arrow functions is not present in PHP version 7.3 or earlier (PHPCompatibility.Keywords.NewKeywords.t_fnFound)

Check failure on line 99 in projects/packages/jetpack-mu-wpcom/src/features/wpcom-themes/includes/class-wpcom-themes-api.php

View workflow job for this annotation

GitHub Actions / Static analysis

CompatError PhanCompatibleArrowFunction Cannot use arrow functions before php 7.4 in (fn) FAQ on Phan issues: pdWQjU-Jb-p2

Check failure on line 99 in projects/packages/jetpack-mu-wpcom/src/features/wpcom-themes/includes/class-wpcom-themes-api.php

View workflow job for this annotation

GitHub Actions / dev branch for PHP 8.0

The "fn" keyword for arrow functions is not present in PHP version 7.3 or earlier (PHPCompatibility.Keywords.NewKeywords.t_fnFound)

Check failure on line 99 in projects/packages/jetpack-mu-wpcom/src/features/wpcom-themes/includes/class-wpcom-themes-api.php

View workflow job for this annotation

GitHub Actions / Static analysis

CompatError PhanCompatibleArrowFunction Cannot use arrow functions before php 7.4 in (fn) FAQ on Phan issues: pdWQjU-Jb-p2
);

if ( ! $theme || isset( $theme->error ) ) {
return null;
}

return $theme;
}

/**
* Returns the collection of the recommended WP.com themes.
*
* @return array<stdClass> An array with all the recommended WPCom themes.
*/
public function fetch_recommended_themes(): array {
return $this->fetch_themes(
'wpcom-themes-recommended',
array( 'collection' => 'recommended' )
);
}

/**
* Returns the WP.com themes that match the given search term.
*
* @param string $search Search term.
*
* @return array<stdClass> An array with all the matching WPCom themes.
*/
public function search_themes( string $search ): array {
return $this->fetch_themes(
'wpcom-themes-search-' . md5( $search ),
array(
'search' => $search,
'sort' => 'date',
)
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php
/**
* Class WPCom_Themes_Cache.
* Caches WPCom themes.
*
* @package wpcom-themes
*/

/**
* Basic cache implementation for themes.
*/
class WPCom_Themes_Cache {
/**
* The cache group.
*
* @var string
*/
const CACHE_GROUP = 'wpcom-themes-cache';

/**
* Executes the supplied callable and caches the result.
*
* @param string $cache_key The cache key.
* @param callable $lambda Callable that returns theme data.
* @param int $ttl Time to live in seconds.
*
* @return mixed Cached data.
*/
public function run_cached( string $cache_key, callable $lambda, int $ttl = DAY_IN_SECONDS ) {
$data = wp_cache_get( $cache_key, self::CACHE_GROUP );

if ( false === $data || defined( 'IGNORE_CACHED_WPCOM_THEMES' ) ) {
$data = $lambda();
wp_cache_set( $cache_key, $data, self::CACHE_GROUP, $ttl );
}

return $data;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
<?php
/**
* Class WPCom_Themes_Mapper.
* Responsible for mapping theme objects between WPCom and WPOrg formats.
*
* @package wpcom-themes
*/

/**
* Maps theme objects between WPCom and WPOrg formats.
*/
class WPCom_Themes_Mapper {

/**
* Maps a WPCom theme subject to .org theme subjects.
*/
private const SUBJECT_MAP = array(
'business' => 'e-commerce',
'store' => 'e-commerce',
'real-estate' => 'e-commerce',
'health-wellness' => 'e-commerce',
'restaurant' => 'food-and-drink',
'travel-lifestyle' => 'holiday',
'art-design' => 'photography',
'about' => 'blog',
'authors-writers' => 'blog',
'newsletter' => 'news',
'magazine' => 'news',
'music' => 'portfolio',
'fashion-beauty' => 'e-commerce',
'community-non-profit' => 'blog',
'podcast' => 'portfolio',
);

/**
* Maps a WPCom theme object to a WPOrg theme object.
*
* @param stdClass $wpcom_theme WPCom theme object.
*
* @return stdClass WPOrg theme object.
*/
public function map_wpcom_to_wporg( stdClass $wpcom_theme ): stdClass {
$slug = $wpcom_theme->stylesheet;
if ( defined( 'IS_ATOMIC' ) && IS_ATOMIC ) {
$slug = $wpcom_theme->id;
}

$wp_theme = wp_get_theme( $slug );
$current_theme = wp_get_theme();

$theme = new stdClass();
$theme->name = $wpcom_theme->name;
$theme->slug = $slug;
$theme->preview_url = $wpcom_theme->demo_uri . '?demo=true&iframe=true&theme_preview=true';
$theme->author = array( 'display_name' => $wpcom_theme->author );
$theme->screenshot_url = $wpcom_theme->screenshot;
$theme->homepage = "https://wordpress.com/theme/$wpcom_theme->id";
$theme->description = $wpcom_theme->description;

// Some themes returned by the API do not have a download URI, but they are installable since they're managed by WP.com.
// In those cases we generate a fake download url so that we can find the theme by download url even though it's not a real download link.
$theme->download_link = $wpcom_theme->id;
$theme->is_commercial = false;
$theme->external_support_url = false;
$theme->is_community = false;
$theme->compatible_wp = true;
$theme->compatible_php = true;
$theme->num_ratings = 0;
$theme->rating = 0;
$theme->requires = '5.8';
$theme->requires_php = '7.4';
$theme->active = $slug === $current_theme->get_stylesheet();
$theme->installed = $wp_theme->exists();
$theme->block_theme = $wpcom_theme->block_theme;
$theme->version = $wpcom_theme->version;
$theme->creation_time = $wpcom_theme->date_added;
$theme->is_wpcom_theme = true;
$theme->tags = $this->build_theme_tags( $wpcom_theme );
$theme->tier = $wpcom_theme->theme_tier->slug;
$theme->theme_type = $wpcom_theme->theme_type;
$theme->product_details = property_exists( $wpcom_theme, 'product_details' ) ? $wpcom_theme->product_details : '';

return $theme;
}

/**
* Creates an array of theme tags from a WPCom theme object.
*
* @param stdClass $theme WPCom theme object.
*
* @return array Theme tags.
*/
private function build_theme_tags( $theme ) {
$tags = array();

foreach ( $theme->taxonomies->theme_subject ?? array() as $subject ) {
$tags[] = $this::SUBJECT_MAP[ $subject->slug ] ?? $subject->slug;
}

foreach ( (array) $theme->taxonomies as $taxonomy ) {
foreach ( $taxonomy as $item ) {
if ( isset( $item->slug ) ) {
$tags[] = $item->slug;
}
}
}

return $tags;
}
}
Loading
Loading