Skip to content

Conversation

@ilicfilip
Copy link
Collaborator

@ilicfilip ilicfilip commented Dec 24, 2025

This PR integrates with WordPress 6.9's new Notes feature to make "Review post X" tasks more actionable. Instead of just sending users to the edit page, we now create block-level notes that guide them through reviewing specific elements.

Implements: https://github.com/ProgressPlanner/progress-planner-pro/issues/192

Changes

  • Added "Review with Notes" action button on review tasks (WP 6.9+ only)
  • When clicked, automatically injects notes for:
    • Images: Each core/image block gets a note asking to verify relevance and display
    • Linked images: Special message noting both image and link should be checked
    • Paragraphs with links: One note per paragraph containing links, with link count
  • Notes are linked to blocks via metadata.noteId attribute
  • Task completion now checks if all PRPL notes are resolved (when notes exist)
  • Falls back to original "post modified" check when no notes present
  • Duplicate prevention: won't create notes if block already has a valid note

How It Works

  1. User clicks "Review with Notes" on a review task
  2. Opens editor with ?prpl_inject_notes=1 parameter
  3. Notes are created and linked to relevant blocks
  4. User sees notes in the Notes panel, can click to highlight blocks
  5. User resolves notes as they review each element
  6. When all notes resolved → task auto-completes

Testing

  1. Create a post with images and paragraphs containing links
  2. Backdate post_modified to >12 months ago
  3. View the review task and click "Review with Notes"
  4. Verify notes appear in the Notes panel
  5. Resolve all notes and verify task completion

@github-actions
Copy link
Contributor

github-actions bot commented Dec 24, 2025

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

@github-actions
Copy link
Contributor

github-actions bot commented Dec 24, 2025

✅ Code Coverage Report

Metric Value
Total Coverage 32.80% 📉
Base Coverage 31.63%
Difference 📈 1.17%

⚠️ Coverage below recommended 40% threshold

🎉 Great job maintaining/improving code coverage!

📊 File-level Coverage Changes (1 files)

📈 Coverage Improved

Class Before After Change
Progress_Planner\Suggested_Tasks\Providers\Content_Review 0.00% 39.40% +39.40%
ℹ️ 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

@github-actions
Copy link
Contributor

github-actions bot commented Jan 28, 2026

🔍 WordPress Plugin Check Report

⚠️ Status: Passed with warnings

📊 Report

🎯 Total Issues ❌ Errors ⚠️ Warnings
10 0 10

⚠️ Warnings (10)

📁 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://wpvip.com/documentation/performance-improvements-by-removing-usage-of-post__not_in/ for more information.
📁 classes/suggested-tasks/providers/class-content-review.php (4 warnings)
📍 Line 🔖 Check 💬 Message
268 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://wpvip.com/documentation/performance-improvements-by-removing-usage-of-post__not_in/ for more information.
413 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://wpvip.com/documentation/performance-improvements-by-removing-usage-of-post__not_in/ for more information.
417 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://wpvip.com/documentation/performance-improvements-by-removing-usage-of-post__not_in/ for more information.
424 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://wpvip.com/documentation/performance-improvements-by-removing-usage-of-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($query)\n$query assigned unsafely at line 98:\n $query = "SELECT p.ID AS post_id, p.post_title AS post_title\n\t\t\tFROM {$wpdb->posts} p\n\t\t\tLEFT JOIN (\n\t\t\t\tSELECT DISTINCT l.target_post_id\n\t\t\t\tFROM {$wpdb->prefix}yoast_seo_links l\n\t\t\t\tWHERE l.type = 'internal'\n\t\t\t\tAND l.target_post_id IS NOT NULL\n\t\t\t) l ON p.ID = l.target_post_id\n\t\t\tWHERE {$where_clause}\n\t\t\tAND l.target_post_id IS NULL\n\t\t\tORDER BY p.post_date DESC\n\t\t\tLIMIT 1"\n$where_clause assigned unsafely at line 95:\n $where_clause .= ' AND p.ID NOT IN (' . \implode( ',', $exclude_post_ids ) . ')'\n$exclude_post_ids assigned unsafely at line 91:\n $exclude_post_ids = \apply_filters( 'progress_planner_yoast_orphaned_content_exclude_post_ids', $exclude_post_ids )\n$exclude_post_ids assigned unsafely at line 79:\n $exclude_post_ids = \array_filter(\n\t\t\t[\n\t\t\t\t( new Hello_World() )->collect(),\n\t\t\t\t( new Sample_Page() )->collect(),\n\t\t\t]\n\t\t)
📁 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($wpdb->prepare( $query, $taxonomy, self::MIN_POSTS ))\n$query assigned unsafely at line 106:\n $query .= ' ORDER BY tt.count DESC LIMIT 1'\n$query assigned unsafely at line 104:\n $query .= ' AND t.term_id NOT IN (' . \implode( ',', \array_map( 'intval', $exclude_term_ids ) ) . ')'\n$terms assigned unsafely at line 108:\n $terms = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching\n\t\t\t\t$wpdb->prepare( $query, $taxonomy, self::MIN_POSTS ) // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- We are using array_map to ensure the values are integers.\n\t\t\t)\n$taxonomy used without escaping.
📁 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($wpdb->prepare( $query, $taxonomy, self::MIN_POSTS, $query_limit ))\n$query assigned unsafely at line 118:\n $query .= ' LIMIT %d'\n$query assigned unsafely at line 115:\n $query .= ' AND t.term_id NOT IN (' . \implode( ',', \array_map( 'intval', $exclude_term_ids ) ) . ')'\n$terms assigned unsafely at line 120:\n $terms = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching\n\t\t\t\t$wpdb->prepare( $query, $taxonomy, self::MIN_POSTS, $query_limit ) // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- We are using array_map to ensure the values are integers.\n\t\t\t)\n$taxonomy used without escaping.
📁 classes/activities/class-query.php (2 warnings)
📍 Line 🔖 Check 💬 Message
71 PluginCheck.Security.DirectDB.UnescapedDBParameter Unescaped parameter $table_name used in $wpdb->query("CREATE TABLE IF NOT EXISTS $table_name (\n\t\t\t\tid BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,\n\t\t\t\tdate DATE NOT NULL,\n\t\t\t\tcategory VARCHAR(255) NOT NULL,\n\t\t\t\ttype VARCHAR(255) NOT NULL,\n\t\t\t\tdata_id VARCHAR(255),\n\t\t\t\tuser_id BIGINT(20) UNSIGNED NOT NULL,\n\t\t\t\tPRIMARY KEY (id)\n\t\t\t) $charset_collate;")\n$table_name assigned unsafely at line 58:\n $table_name = $wpdb->prefix . static::TABLE_NAME
163 PluginCheck.Security.DirectDB.UnescapedDBParameter Unescaped parameter $where_args used in $wpdb->get_results($wpdb->prepare(\n\t\t\t\t\t\t\sprintf(\n\t\t\t\t\t\t\t'SELECT * FROM %%i WHERE %s',\n\t\t\t\t\t\t\t\implode( ' AND ', $where_args )\n\t\t\t\t\t\t),\n\t\t\t\t\t\t\array_merge(\n\t\t\t\t\t\t\t[ $wpdb->prefix . static::TABLE_NAME ], \t\t\t\t\t\t\t$prepare_args\n\t\t\t\t\t\t)\n\t\t\t\t\t))\n$where_args assigned unsafely at line 153:\n $where_args[] = 'user_id = %s'\n$prepare_args[] used without escaping.\n$args['user_id'] used without escaping.

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

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.

3 participants