Skip to content

Add sunset notice with downloadable certificate - #777

Draft
tacoverdo wants to merge 1 commit into
developfrom
taco/sunset-notice
Draft

Add sunset notice with downloadable certificate#777
tacoverdo wants to merge 1 commit into
developfrom
taco/sunset-notice

Conversation

@tacoverdo

Copy link
Copy Markdown
Contributor

What

Shows a notice that support for the free plugin is ending, in two places:

  • Progress Planner dashboard: a banner above the header (via the progress_planner_admin_page_header_before slot), thanking users, linking to more information, and offering a certificate download.
  • Plugins overview page: a warning row under the Progress Planner row, using WP core's own update-row markup (plugin-update-tr / notice notice-warning inline notice-alt) so it inherits core styling.

Certificate

The "Get your certificate" button opens a standalone print-optimized page (served via admin-post.php, outside the admin chrome) showing the site name/URL, the date the user started using Progress Planner (get_activation_date()), and all completed badges across the content, maintenance, and monthly groups. A "Save as PDF" button triggers the browser print dialog. The layout is hard-sized to a single A4 landscape page; badge artwork scales with the badge count (24mm → 10mm tiers) so even 60+ badges fit on one sheet.

Suppression for hosted users

The notice and certificate endpoint are not registered when:

  • PP_HOSTS_FILE or PROGRESS_PLANNER_BRANDING_ID is defined, or the PP_Hosts\Updater class exists (pp-hosts active / host-defined branding), or
  • the pp-hosts plugin is installed but inactive (Plugin_Installer::is_plugin_installed()).

A progress_planner_show_sunset_notice filter is available as an escape hatch (and as the test seam).

Open items

  • Final copy and the real "learn more" URL — placeholder is https://prpl.fyi/sunset, kept as a class constant.
  • Badge artwork loads from the SaaS badge-svg endpoint at render time (with placeholder fallback); if that endpoint sunsets too, we may want to cache SVGs locally.

Testing

  • 6 new PHPUnit tests (hook registration, filter suppression, row-notice output, capability guards, completed-badge filtering, certificate output).
  • PHPStan level 10, WPCS, and the full suite (414 tests) pass.
  • Verified live in WP Playground: both notices render on a clean install; both disappear with PROGRESS_PLANNER_BRANDING_ID defined.

🤖 Generated with Claude Code

Show a notice that support for the plugin is ending, on the Progress
Planner dashboard and on the plugins overview page. The notice thanks
users and links to more information, and lets them download a printable
single-page A4 certificate showing their site, how long they have used
Progress Planner, and all completed badges.

The notice is hidden when the pp-hosts companion plugin is installed or
active, or when a branding ID is defined, since support continues for
hosted users. A progress_planner_show_sunset_notice filter is available
as an escape hatch.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Test on Playground
Test this pull request on the Playground
or download the zip

@github-actions

Copy link
Copy Markdown
Contributor

🔍 WordPress Plugin Check Report

⚠️ Status: Passed with warnings

📊 Report

🎯 Total Issues ❌ Errors ⚠️ Warnings
10 0 10

⚠️ Warnings (10)

📁 classes/suggested-tasks/providers/class-content-review.php (4 warnings)
📍 Line 🔖 Check 💬 Message
232 WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_post__not_in Using exclusionary parameters, like post__not_in, in calls to get_posts() should be done with caution, see https://docs.wpvip.com/databases/optimize-queries/using-post__not_in/ for more information.
377 WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_post__not_in Using exclusionary parameters, like post__not_in, in calls to get_posts() should be done with caution, see https://docs.wpvip.com/databases/optimize-queries/using-post__not_in/ for more information.
381 WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_post__not_in Using exclusionary parameters, like post__not_in, in calls to get_posts() should be done with caution, see https://docs.wpvip.com/databases/optimize-queries/using-post__not_in/ for more information.
388 WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_post__not_in Using exclusionary parameters, like post__not_in, in calls to get_posts() should be done with caution, see https://docs.wpvip.com/databases/optimize-queries/using-post__not_in/ for more information.
📁 classes/suggested-tasks/data-collector/class-unpublished-content.php (1 warning)
📍 Line 🔖 Check 💬 Message
103 WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_post__not_in Using exclusionary parameters, like post__not_in, in calls to get_posts() should be done with caution, see https://docs.wpvip.com/databases/optimize-queries/using-post__not_in/ for more information.
📁 classes/suggested-tasks/data-collector/class-yoast-orphaned-content.php (1 warning)
📍 Line 🔖 Check 💬 Message
111 PluginCheck.Security.DirectDB.UnescapedDBParameter Unescaped parameter $query used in $wpdb->get_row()\n$query assigned unsafely at line 98.
📁 classes/suggested-tasks/data-collector/class-terms-without-description.php (1 warning)
📍 Line 🔖 Check 💬 Message
108 PluginCheck.Security.DirectDB.UnescapedDBParameter Unescaped parameter $query used in $wpdb->get_results()\n$query assigned unsafely at line 106.
📁 classes/suggested-tasks/data-collector/class-terms-without-posts.php (1 warning)
📍 Line 🔖 Check 💬 Message
120 PluginCheck.Security.DirectDB.UnescapedDBParameter Unescaped parameter $query used in $wpdb->get_results()\n$query assigned unsafely at line 118.
📁 classes/activities/class-query.php (2 warnings)
📍 Line 🔖 Check 💬 Message
71 PluginCheck.Security.DirectDB.UnescapedDBParameter Unescaped parameter $table_name used in $wpdb->query()\n$table_name assigned unsafely at line 58.
163 PluginCheck.Security.DirectDB.UnescapedDBParameter Unescaped parameter $where_args used in $wpdb->get_results()\n$where_args assigned unsafely at line 153.

🤖 Generated by WordPress Plugin Check Action • Learn more about Plugin Check

@github-actions

Copy link
Copy Markdown
Contributor

✅ Code Coverage Report

Metric Value
Total Coverage 32.68% 📉
Base Coverage 32.27%
Difference 📈 0.41%

⚠️ Coverage below recommended 40% threshold

🎉 Great job maintaining/improving code coverage!

📊 File-level Coverage Changes (2 files)

🆕 New Files

Class Coverage Lines
🟢 Progress_Planner\Admin\Sunset_Notice 93.33% 42/45

📈 Coverage Improved

Class Before After Change
Progress_Planner\Base 45.40% 48.78% +3.38%
ℹ️ About this report
  • All tests run in a single job with Xdebug coverage
  • Security tests excluded from coverage to prevent output issues
  • Coverage calculated from line coverage percentages

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant