From 86d83811fa55ffbabeb9b163bcc31b0848330aa1 Mon Sep 17 00:00:00 2001 From: Filip Ilic Date: Wed, 21 Oct 2026 09:32:57 +0200 Subject: [PATCH] Revert the sunset notice from develop Reverts #777 (merge 7c18816f). The notice and certificate were added for the final wp.org release (1.10.1), which has shipped. Development continues for our other users, who should not see an end-of-support notice. Removes the Sunset_Notice class, its dashboard and plugins-page notices, the certificate view and endpoint, its CSS and tests. The 1.10.1 changelog entry stays, since it documents what that release shipped. Co-Authored-By: Claude Opus 5.5 Signed-off-by: Filip Ilic --- assets/css/admin.css | 16 -- classes/admin/class-sunset-notice.php | 191 ------------------ classes/class-base.php | 1 - tests/phpunit/test-class-sunset-notice.php | 168 ---------------- views/sunset-certificate.php | 216 --------------------- views/sunset-notice.php | 22 --- 6 files changed, 614 deletions(-) delete mode 100644 classes/admin/class-sunset-notice.php delete mode 100644 tests/phpunit/test-class-sunset-notice.php delete mode 100644 views/sunset-certificate.php delete mode 100644 views/sunset-notice.php diff --git a/assets/css/admin.css b/assets/css/admin.css index c8862528c..58938bef6 100644 --- a/assets/css/admin.css +++ b/assets/css/admin.css @@ -324,22 +324,6 @@ button.prpl-info-icon { } } -/*------------------------------------*\ - Sunset notice. -\*------------------------------------*/ -.prpl-wrap .prpl-sunset-notice { - border-left: 4px solid var(--prpl-background-banner); - - h1 { - color: var(--prpl-color-headings); - margin-top: 0; - } - - p { - max-width: 680px; - } -} - /*------------------------------------*\ Buttons \*------------------------------------*/ diff --git a/classes/admin/class-sunset-notice.php b/classes/admin/class-sunset-notice.php deleted file mode 100644 index e7a6b4bc8..000000000 --- a/classes/admin/class-sunset-notice.php +++ /dev/null @@ -1,191 +0,0 @@ -should_show() ) { - return; - } - - \add_action( 'progress_planner_admin_page_header_before', [ $this, 'the_dashboard_notice' ] ); - \add_action( 'after_plugin_row_' . \plugin_basename( \PROGRESS_PLANNER_FILE ), [ $this, 'the_plugin_row_notice' ] ); - \add_action( 'admin_post_' . self::CERTIFICATE_ACTION, [ $this, 'render_certificate' ] ); - } - - /** - * Whether the sunset notice should be shown. - * - * The notice only applies to installs coming from wordpress.org or FAIR. - * It is hidden when the pp-hosts companion plugin is active (constants or - * class detection), when a host defines a branding ID, or when pp-hosts - * is installed but not (yet) activated. - * - * @return bool - */ - public function should_show() { - $show = ! ( - \defined( 'PP_HOSTS_FILE' ) - || \defined( 'PROGRESS_PLANNER_BRANDING_ID' ) - || \class_exists( 'PP_Hosts\Updater' ) - || \progress_planner()->get_plugin_installer()->is_plugin_installed( 'pp-hosts' ) - ); - - /** - * Filter whether the sunset notice should be shown. - * - * @param bool $show Whether the notice should be shown. - */ - return (bool) \apply_filters( 'progress_planner_show_sunset_notice', $show ); - } - - /** - * Get the notice message, shared by both surfaces. - * - * @return string - */ - public function get_message() { - return \esc_html__( 'Support and updates for the free Progress Planner plugin have ended. We are incredibly grateful for your support over the years — thank you for improving your website with us!', 'progress-planner' ); - } - - /** - * Get the certificate invitation sentence. - * - * Contains an anchor tag, so it should be escaped with `wp_kses_post` on output. - * - * @return string - */ - public function get_certificate_message() { - return \sprintf( - /* translators: %1$s: opening tag, %2$s: closing tag. */ - \esc_html__( 'As a keepsake, you can %1$sdownload a certificate%2$s with your site\'s achievements.', 'progress-planner' ), - '', - '' - ); - } - - /** - * Get the URL of the certificate page. - * - * @return string - */ - public function get_certificate_url() { - return \admin_url( 'admin-post.php?action=' . self::CERTIFICATE_ACTION ); - } - - /** - * Get all completed badges, across all badge contexts. - * - * @return \Progress_Planner\Badges\Badge[] - */ - public function get_completed_badges() { - $completed = []; - foreach ( [ 'content', 'maintenance', 'monthly_flat' ] as $context ) { - foreach ( \progress_planner()->get_badges()->get_badges( $context ) as $badge ) { - $progress = $badge->get_progress(); - if ( isset( $progress['progress'] ) && 100 === (int) $progress['progress'] ) { - $completed[] = $badge; - } - } - } - return $completed; - } - - /** - * Render the standalone certificate page and exit. - * - * Hooked to admin-post, so this renders outside the WP admin chrome. - * - * @return void - */ - public function render_certificate() { - if ( ! \current_user_can( 'edit_others_posts' ) ) { - \wp_die( \esc_html__( 'You do not have permission to view this page.', 'progress-planner' ) ); - } - $this->the_certificate(); - exit; - } - - /** - * Print the certificate page markup. - * - * @return void - */ - public function the_certificate() { - \progress_planner()->the_view( 'sunset-certificate.php' ); - } - - /** - * Print the notice banner on the Progress Planner dashboard. - * - * @return void - */ - public function the_dashboard_notice() { - \progress_planner()->the_view( 'sunset-notice.php' ); - } - - /** - * Print a notice row below the plugin's row on the plugins overview page. - * - * @param string $plugin_file Path to the plugin file relative to the plugins directory. - * - * @return void - */ - public function the_plugin_row_notice( $plugin_file ) { - if ( ! \current_user_can( 'activate_plugins' ) ) { - return; - } - - $prpl_colspan = 4; - if ( \function_exists( '_get_list_table' ) ) { - $prpl_colspan = \_get_list_table( 'WP_Plugins_List_Table', [ 'screen' => 'plugins' ] )->get_column_count(); - } - - $prpl_is_active = \function_exists( 'is_plugin_active' ) && \is_plugin_active( $plugin_file ); - ?> - - -
-

get_message() . ' ' . $this->get_certificate_message() ); ?>

-
- - - - get_admin__page(); $this->get_admin__tour(); - $this->get_admin__sunset_notice(); // Dont add the widget if the privacy policy is not accepted. if ( true === $this->is_privacy_policy_accepted() ) { diff --git a/tests/phpunit/test-class-sunset-notice.php b/tests/phpunit/test-class-sunset-notice.php deleted file mode 100644 index bd561065b..000000000 --- a/tests/phpunit/test-class-sunset-notice.php +++ /dev/null @@ -1,168 +0,0 @@ -assertTrue( $notice->should_show() ); - } - - /** - * Test that hooks are registered on instantiation in a clean install. - * - * @return void - */ - public function test_hooks_registered_by_default() { - $notice = new Sunset_Notice(); - $this->assertNotFalse( \has_action( 'progress_planner_admin_page_header_before', [ $notice, 'the_dashboard_notice' ] ) ); - $this->assertNotFalse( \has_action( 'after_plugin_row_' . \plugin_basename( \PROGRESS_PLANNER_FILE ), [ $notice, 'the_plugin_row_notice' ] ) ); - } - - /** - * Test that hooks are not registered when the filter hides the notice. - * - * @return void - */ - public function test_hooks_not_registered_when_filtered_out() { - \add_filter( 'progress_planner_show_sunset_notice', '__return_false' ); - $notice = new Sunset_Notice(); - $this->assertFalse( $notice->should_show() ); - $this->assertFalse( \has_action( 'progress_planner_admin_page_header_before', [ $notice, 'the_dashboard_notice' ] ) ); - $this->assertFalse( \has_action( 'after_plugin_row_' . \plugin_basename( \PROGRESS_PLANNER_FILE ), [ $notice, 'the_plugin_row_notice' ] ) ); - } - - /** - * Test that the message is not empty and contains no links. - * - * @return void - */ - public function test_message_has_no_links() { - $notice = new Sunset_Notice(); - $this->assertNotEmpty( $notice->get_message() ); - $this->assertStringNotContainsString( 'get_message() ); - } - - /** - * Test the plugin-row notice output. - * - * @return void - */ - public function test_plugin_row_notice_output() { - $user_id = $this->factory->user->create( [ 'role' => 'administrator' ] ); - if ( \is_multisite() ) { - \grant_super_admin( $user_id ); - } - \wp_set_current_user( $user_id ); - - $notice = new Sunset_Notice(); - \ob_start(); - $notice->the_plugin_row_notice( \plugin_basename( \PROGRESS_PLANNER_FILE ), [] ); - $output = \ob_get_clean(); - - $this->assertStringContainsString( 'plugin-update-tr', $output ); - $this->assertStringContainsString( 'notice-warning', $output ); - $this->assertStringContainsString( Sunset_Notice::CERTIFICATE_ACTION, $output ); - } - - /** - * Test that the certificate endpoint is registered on instantiation. - * - * @return void - */ - public function test_certificate_endpoint_registered() { - $notice = new Sunset_Notice(); - $this->assertNotFalse( \has_action( 'admin_post_' . Sunset_Notice::CERTIFICATE_ACTION, [ $notice, 'render_certificate' ] ) ); - } - - /** - * Test that get_completed_badges only returns badges with 100% progress. - * - * @return void - */ - public function test_get_completed_badges_are_complete() { - $notice = new Sunset_Notice(); - $badges = $notice->get_completed_badges(); - $this->assertIsArray( $badges ); - foreach ( $badges as $badge ) { - $this->assertInstanceOf( \Progress_Planner\Badges\Badge::class, $badge ); - $this->assertSame( 100, (int) $badge->get_progress()['progress'] ); - } - } - - /** - * Test the certificate output contains the site URL and activation year. - * - * @return void - */ - public function test_certificate_output() { - $user_id = $this->factory->user->create( [ 'role' => 'administrator' ] ); - \wp_set_current_user( $user_id ); - - $notice = new Sunset_Notice(); - \ob_start(); - $notice->the_certificate(); - $output = \ob_get_clean(); - - $this->assertStringContainsString( \home_url(), $output ); - $this->assertStringContainsString( \progress_planner()->get_activation_date()->format( 'Y' ), $output ); - $this->assertStringContainsString( 'prpl-certificate', $output ); - } - - /** - * Test that the certificate endpoint dies for users without capabilities. - * - * @return void - */ - public function test_certificate_requires_capability() { - \wp_set_current_user( 0 ); - - $notice = new Sunset_Notice(); - $this->expectException( \WPDieException::class ); - $notice->render_certificate(); - } - - /** - * Test that the plugin-row notice outputs nothing for users without capabilities. - * - * @return void - */ - public function test_plugin_row_notice_requires_capability() { - \wp_set_current_user( 0 ); - - $notice = new Sunset_Notice(); - \ob_start(); - $notice->the_plugin_row_notice( \plugin_basename( \PROGRESS_PLANNER_FILE ), [] ); - $output = \ob_get_clean(); - - $this->assertSame( '', $output ); - } -} diff --git a/views/sunset-certificate.php b/views/sunset-certificate.php deleted file mode 100644 index 47b17c1ec..000000000 --- a/views/sunset-certificate.php +++ /dev/null @@ -1,216 +0,0 @@ -get_admin__sunset_notice(); -$prpl_completed_badges = $prpl_sunset_notice->get_completed_badges(); -$prpl_activation_date = \progress_planner()->get_activation_date(); -$prpl_badge_svg_url = \progress_planner()->get_remote_server_root_url() . '/wp-json/progress-planner-saas/v1/badge-svg/?badge_id='; - -// Scale the badges to the available space, so the certificate always fits on a single A4 page. -$prpl_badge_count = \count( $prpl_completed_badges ); -if ( $prpl_badge_count <= 8 ) { - $prpl_badge_size = 24; // mm. -} elseif ( $prpl_badge_count <= 18 ) { - $prpl_badge_size = 18; -} elseif ( $prpl_badge_count <= 32 ) { - $prpl_badge_size = 14; -} else { - $prpl_badge_size = 10; -} - -?> - -> - - - - <?php \esc_html_e( 'Progress Planner certificate', 'progress-planner' ); ?> - - - - - - - - diff --git a/views/sunset-notice.php b/views/sunset-notice.php deleted file mode 100644 index dedd4d16f..000000000 --- a/views/sunset-notice.php +++ /dev/null @@ -1,22 +0,0 @@ - -
-
-

-

get_admin__sunset_notice()->get_message() ); ?>

-

- - - -
-