Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
d11dfee
Updated code to display plugin settings link in the features screen
ashwinparthasarathi May 7, 2024
c7cd3d1
Merge branch 'trunk' into add/plugin-settings-link-in-features-screen
ashwinparthasarathi May 7, 2024
3fd724e
Merge branch 'WordPress:trunk' into add/plugin-settings-link-in-featu…
ashwinparthasarathi May 8, 2024
e88f109
Updated code to fetch plugin path from plugin list
ashwinparthasarathi May 8, 2024
e7dbfa6
Merge branch 'add/plugin-settings-link-in-features-screen' of github.…
ashwinparthasarathi May 8, 2024
95642a3
Fix function stub docs
mukeshpanchal27 May 7, 2024
2da8c22
Bump PHPStan level to 5
westonruter May 6, 2024
c197b9f
Ignore phpstan errors when testing for incorrect usage
westonruter May 6, 2024
1501ebc
Fix types for arguments passed in tests
westonruter May 6, 2024
bc55f7a
Add rememberPossiblyImpureFunctionValues:false to fix it_should_use_t…
westonruter May 6, 2024
d024264
Add comments explaining why PHPStan is ignored
westonruter May 7, 2024
8067df4
Updated code to fetch plugin path from plugin list
ashwinparthasarathi May 8, 2024
b4b73ca
fix: avoid needless array allocation in rgb to hex conversion
ju1ius Apr 1, 2024
3a3d733
Ensure RGB variable is int
westonruter May 8, 2024
2473091
Add test case for when RGB values are too high
westonruter May 8, 2024
91b1f73
Merge branch 'add/plugin-settings-link-in-features-screen' of github.…
ashwinparthasarathi May 8, 2024
0fe54ec
Moved Settings to the last action link and made review changes.
ashwinparthasarathi May 13, 2024
eecfad1
Moved Settings to the last action link
ashwinparthasarathi May 13, 2024
08b83aa
Merge branch 'trunk' into add/plugin-settings-link-in-features-screen
westonruter May 13, 2024
606c4e3
Added settings link to activation admin notice.
ashwinparthasarathi May 15, 2024
18a71cc
Changed as per review shared.
ashwinparthasarathi May 16, 2024
0cf11f5
Updated the admin notice for conditions
ashwinparthasarathi May 16, 2024
b946a4d
Updated as per review changes.
ashwinparthasarathi May 16, 2024
3e6b9d4
Updated as per review changes.
ashwinparthasarathi May 16, 2024
ea00ad5
Merge branch 'trunk' into add/plugin-settings-link-in-features-screen
ashwinparthasarathi May 16, 2024
af3b5a9
Improve sanitization logic for plugin slug
westonruter May 16, 2024
c7ba02c
Prevent Settings link from overflowing plugin card
westonruter May 16, 2024
893e91b
Factor out common plugin slug sanitization logic
westonruter May 16, 2024
57e0f8e
Fix presentation of plugin cards on mobile
westonruter May 16, 2024
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
106 changes: 101 additions & 5 deletions includes/admin/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,22 @@ function perflab_enqueue_features_page_scripts(): void {
wp_enqueue_script( 'wp-a11y' );
}

/**
* Sanitizes a plugin slug.
*
* @since 3.1.0
*
* @param mixed $unsanitized_plugin_slug Unsanitized plugin slug.
* @return string|null Validated and sanitized slug or else null.
*/
function perflab_sanitize_plugin_slug( $unsanitized_plugin_slug ): ?string {
if ( in_array( $unsanitized_plugin_slug, perflab_get_standalone_plugins(), true ) ) {
return $unsanitized_plugin_slug;
} else {
return null;
}
}

/**
* Callback for handling installation/activation of plugin.
*
Expand All @@ -248,8 +264,8 @@ function perflab_install_activate_plugin_callback(): void {
wp_die( esc_html__( 'Missing required parameter.', 'performance-lab' ) );
}

$plugin_slug = sanitize_text_field( wp_unslash( $_GET['slug'] ) );
if ( ! in_array( $plugin_slug, perflab_get_standalone_plugins(), true ) ) {
$plugin_slug = perflab_sanitize_plugin_slug( wp_unslash( $_GET['slug'] ) );
if ( ! $plugin_slug ) {
wp_die( esc_html__( 'Invalid plugin.', 'performance-lab' ) );
}

Expand All @@ -262,7 +278,7 @@ function perflab_install_activate_plugin_callback(): void {
$url = add_query_arg(
array(
'page' => PERFLAB_SCREEN,
'activate' => 'true',
'activate' => $plugin_slug,
),
admin_url( 'options-general.php' )
);
Expand All @@ -287,12 +303,31 @@ function perflab_print_features_page_style(): void {
margin-left: 0;
}
.plugin-card-top {
min-height: auto;
/* This is required to ensure the Settings link does not extend below the bottom of a plugin card on a wide screen. */
min-height: 90px;
}
@media screen and (max-width: 782px) {
.plugin-card-top {
/* Same reason as above, but now the button is taller to make it easier to tap on touch screens. */
min-height: 110px;
}
}
.plugin-card .perflab-plugin-experimental {
font-size: 80%;
font-weight: normal;
}

@media screen and (max-width: 1100px) and (min-width: 782px), (max-width: 480px) {
.plugin-card .action-links {
margin-left: auto;
}
/* Make sure the settings link gets spaced out from the Learn more link. */
.plugin-card .plugin-action-buttons > li:nth-child(3) {
margin-left: 2ex;
border-left: solid 1px;
padding-left: 2ex;
}
}
</style>
<?php
}
Expand Down Expand Up @@ -329,9 +364,29 @@ static function ( $name ) {
}
}

$activated_plugin_slug = null;
if ( isset( $_GET['activate'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
$activated_plugin_slug = perflab_sanitize_plugin_slug( wp_unslash( $_GET['activate'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
}

if ( $activated_plugin_slug ) {
$message = __( 'Feature activated.', 'performance-lab' );

$plugin_settings_url = perflab_get_plugin_settings_url( $activated_plugin_slug );
if ( $plugin_settings_url ) {
/* translators: %s is the settings URL */
$message .= ' ' . sprintf( __( 'Review <a href="%s">settings</a>.', 'performance-lab' ), esc_url( $plugin_settings_url ) );
}

wp_admin_notice(
esc_html__( 'Feature activated.', 'performance-lab' ),
wp_kses(
$message,
array(
'a' => array(
'href' => array(),
),
)
),
array(
'type' => 'success',
'dismissible' => true,
Expand Down Expand Up @@ -375,3 +430,44 @@ function addPluginProgressIndicator( message ) {
array( 'type' => 'module' )
);
}

/**
* Gets the URL to the plugin settings screen if one exists.
*
* @since n.e.x.t
*
* @param string $plugin_slug Plugin slug passed to generate the settings link.
* @return string|null Either the plugin settings URL or null if not available.
*/
function perflab_get_plugin_settings_url( string $plugin_slug ): ?string {
$plugin_file = null;

foreach ( array_keys( get_plugins() ) as $file ) {
if ( strtok( $file, '/' ) === $plugin_slug ) {
$plugin_file = $file;
break;
}
}

if ( null === $plugin_file ) {
return null;
}

/** This filter is documented in wp-admin/includes/class-wp-plugins-list-table.php */
$plugin_links = apply_filters( "plugin_action_links_{$plugin_file}", array() );

if ( ! is_array( $plugin_links ) || ! array_key_exists( 'settings', $plugin_links ) ) {
return null;
}

$p = new WP_HTML_Tag_Processor( $plugin_links['settings'] );
if ( ! $p->next_tag( array( 'tag_name' => 'A' ) ) ) {
return null;
}
$href = $p->get_attribute( 'href' );
if ( $href && is_string( $href ) ) {
return $href;
}

return null;
}
11 changes: 9 additions & 2 deletions includes/admin/plugins.php
Original file line number Diff line number Diff line change
Expand Up @@ -318,8 +318,7 @@ function perflab_render_plugin_card( array $plugin_data ): void {
/** This filter is documented in wp-admin/includes/class-wp-plugin-install-list-table.php */
$description = apply_filters( 'plugin_install_description', $description, $plugin_data );

$availability = perflab_get_plugin_availability( $plugin_data );

$availability = perflab_get_plugin_availability( $plugin_data );
$compatible_php = $availability['compatible_php'];
$compatible_wp = $availability['compatible_wp'];

Expand Down Expand Up @@ -398,6 +397,14 @@ function perflab_render_plugin_card( array $plugin_data ): void {
esc_html__( 'Visit plugin site', 'default' )
);
}

if ( $availability['activated'] ) {
$settings_url = perflab_get_plugin_settings_url( $plugin_data['slug'] );
if ( $settings_url ) {
/* translators: %s is the settings URL */
$action_links[] = sprintf( '<a href="%s">%s</a>', esc_url( $settings_url ), esc_html__( 'Settings', 'performance-lab' ) );
}
}
?>
<div class="plugin-card plugin-card-<?php echo sanitize_html_class( $plugin_data['slug'] ); ?>">
<?php
Expand Down
42 changes: 42 additions & 0 deletions tests/includes/admin/load-tests.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ public function test_perflab_add_features_page(): void {
remove_all_filters( 'plugin_action_links_' . plugin_basename( PERFLAB_MAIN_FILE ) );
}

/**
* @covers ::perflab_render_settings_page
*/
public function test_perflab_render_settings_page(): void {
ob_start();
perflab_render_settings_page();
Expand All @@ -59,6 +62,9 @@ public function test_perflab_render_settings_page(): void {
$this->assertStringNotContainsString( "<input type='hidden' name='option_page' value='" . PERFLAB_SCREEN . "' />", $output );
}

/**
* @covers ::perflab_plugin_action_links_add_settings
*/
public function test_perflab_plugin_action_links_add_settings(): void {
$original_links = array(
'deactivate' => '<a href="#">Deactivate</a>',
Expand All @@ -73,4 +79,40 @@ public function test_perflab_plugin_action_links_add_settings(): void {
$actual_links = perflab_plugin_action_links_add_settings( $original_links );
$this->assertSame( $expected_links, $actual_links );
}

/**
* @return array<int, mixed>
*/
public function data_provider_to_test_perflab_sanitize_plugin_slug(): array {
return array(
array(
'webp-uploads',
'webp-uploads',
),
array(
'akismet',
null,
),
array(
1,
null,
),
array(
array( 'speculative-loading' ),
null,
),
);
}

/**
* @covers ::perflab_sanitize_plugin_slug
*
* @dataProvider data_provider_to_test_perflab_sanitize_plugin_slug
*
* @param mixed $slug Slug.
* @param string|null $expected Expected.
*/
public function test_perflab_sanitize_plugin_slug( $slug, ?string $expected ): void {
$this->assertSame( $expected, perflab_sanitize_plugin_slug( $slug ) );
}
}