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 27 commits into
base: trunk
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
5a7b94e
Add Theme Install page
scruffian Jan 28, 2025
c465561
changelog
scruffian Jan 28, 2025
f56c185
add theme-install.php
scruffian Jan 28, 2025
e5ea4e3
add theme-install.php
scruffian Jan 28, 2025
97807c0
Make theme-install load
ryelle Jan 28, 2025
cd17551
add js file
scruffian Jan 28, 2025
4e87cba
don't send simple site users to calypso for installed or activated th…
draganescu Jan 29, 2025
4f19353
changelog
draganescu Jan 29, 2025
569763f
Use the page load hook to enqueue script
ryelle Jan 29, 2025
09f978f
Ensure the custom JS is loaded after the core theme JS
ryelle Jan 29, 2025
c2ecd53
Update the router to use the custom page URL
ryelle Jan 29, 2025
20313cc
remove the theme showcase banner and link
draganescu Jan 29, 2025
b1f95ae
Copy over atomic theme api customization
ryelle Jan 29, 2025
44fc77b
Fork the core admin-ajax response to return regardless of install per…
ryelle Jan 29, 2025
7bad581
Fix the URLs passed to the router
ryelle Jan 29, 2025
b01b0f7
Replace the ajax request for the favorites username with patched version
ryelle Jan 31, 2025
6bb1d24
Update comments to explicitly call out patched sections of ajax funct…
ryelle Jan 31, 2025
34610e3
Add filter to update the theme object before returning in ajax response
ryelle Jan 31, 2025
7ce283c
Use the correct theme slug for each environment
ryelle Jan 31, 2025
a26c390
Add patched notes and remove hardcoded changes
ryelle Jan 31, 2025
f10d9f0
Add filters to the theme templates
ryelle Jan 31, 2025
07acb1c
Add (unstyled) theme tier label
ryelle Jan 31, 2025
1ecc29f
Remove the tier check at the API level
ryelle Jan 31, 2025
563949c
Conditional theme activate button text depending of the user plan
matiasbenedetto Jan 31, 2025
4fb5586
Update "Activate" and "Install" URLs to use checkout if necessary
ryelle Feb 4, 2025
563f07a
Update "Install" button text to "Upgrade to install", ensure only but…
ryelle Feb 4, 2025
30611da
Fix duplicate ampersand in URL
ryelle Feb 4, 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,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 / 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 / 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 / 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 {
$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
);
}

/**
* 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 / 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 = $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;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<?php
/**
* Class WPCom_Themes_Merger.
* Responsible for the different merging strategies between WPCom and WPOrg themes.
*
* @package wpcom-themes
*/

/**
* Merges theme objects between WPCom and WPOrg repositories.
*/
class WPCom_Themes_Merger {
/**
* Merges themes prioritizing WPCom themes.
*
* @param stdClass $wporg_themes_object The WP.org themes API result.
* @param array $wpcom_themes The WP.com themes to include.
*
* @return stdClass The themes API result including wpcom themes.
*/
public function merge_by_wpcom_first( stdClass $wporg_themes_object, array $wpcom_themes ): stdClass {
$wporg_themes_excluding_wpcom = array();

// Create an associative array with theme slugs as keys for quick lookup
$wpcom_theme_slugs = array_flip(
array_map(
fn ( $theme ) => $theme->slug,

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

View workflow job for this annotation

GitHub Actions / PHP lint (7.2)

Parse error: syntax error, unexpected '=&gt;' (T_DOUBLE_ARROW), expecting ',' or ')'

Check failure on line 27 in projects/packages/jetpack-mu-wpcom/src/features/wpcom-themes/includes/class-wpcom-themes-merger.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 27 in projects/packages/jetpack-mu-wpcom/src/features/wpcom-themes/includes/class-wpcom-themes-merger.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
$wpcom_themes
)
);

// Filter themes from $wporg_themes_object that are not in $wpcom_themes
foreach ( $wporg_themes_object->themes as $wporg_theme ) {
if ( ! isset( $wpcom_theme_slugs[ $wporg_theme->slug ] ) ) {
$wporg_themes_excluding_wpcom[] = $wporg_theme;
}
}

// Remove the count of wporg themes.
$wporg_themes_object->info['results'] -= count( $wporg_themes_object->themes );

// Merge $wpcom_themes and $wporg_themes_excluding_wpcom if it's the first page
if ( $wporg_themes_object->info['page'] === 1 ) {
$wporg_themes_object->themes = array_merge( $wpcom_themes, $wporg_themes_excluding_wpcom );
}

// Add the count of themes without duplicates.
$wporg_themes_object->info['results'] += count( $wporg_themes_object->themes );

return $wporg_themes_object;
}

/**
* Merge themes by release date with no particular bias.
*
* @param stdClass $wporg_themes_object The WP.org themes API result.
* @param array $wpcom_themes The WP.com themes to include.
*
* @return stdClass The themes API result including wpcom themes.
*/
public function merge_by_release_date( stdClass $wporg_themes_object, array $wpcom_themes ): stdClass {
$last_theme_date = strtotime( end( $wporg_themes_object->themes )->creation_time );
$first_theme_date = strtotime( reset( $wporg_themes_object->themes )->creation_time );

$themes = array();
foreach ( $wporg_themes_object->themes as $wporg_theme ) {
$themes[ $wporg_theme->slug ] = $wporg_theme;
}

// We override WP.org themes with WP.com themes if they have the same slug. We might have fewer results
// than expected if there are themes with the same slug in both repositories and the release dates differ.
// As a general rule, users will see themes once they're available on the WPCom theme repo which is before they're
// available on the WPOrg theme repo.
foreach ( $wpcom_themes as $theme ) {
$themes[ $theme->slug ] = $theme;
}

$themes = array_filter(
$themes,
fn( $theme ) => strtotime( $theme->creation_time ) >= $last_theme_date && strtotime( $theme->creation_time ) <= $first_theme_date

Check failure on line 80 in projects/packages/jetpack-mu-wpcom/src/features/wpcom-themes/includes/class-wpcom-themes-merger.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 80 in projects/packages/jetpack-mu-wpcom/src/features/wpcom-themes/includes/class-wpcom-themes-merger.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
);

usort(
$themes,
fn( $a, $b ) => strtotime( $b->creation_time ) - strtotime( $a->creation_time )

Check failure on line 85 in projects/packages/jetpack-mu-wpcom/src/features/wpcom-themes/includes/class-wpcom-themes-merger.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 85 in projects/packages/jetpack-mu-wpcom/src/features/wpcom-themes/includes/class-wpcom-themes-merger.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
);

// Remove the wporg themes count.
$wporg_themes_object->info['results'] -= count( $wporg_themes_object->themes );
// Add the filtered unique themes count.
$wporg_themes_object->info['results'] += count( $themes );

$wporg_themes_object->themes = $themes;

return $wporg_themes_object;
}
}
Loading
Loading