Skip to content

Conversation

@acicovic
Copy link
Collaborator

@acicovic acicovic commented Sep 3, 2025

Description

When using Engagement Boost, non-administrators would see a "-1" displayed in the Engagement Boost preview screen, instead of seeing the post's content.

This PR creates a predefined changeset post in order to make the Engagement Boost preview work for non-administrator user roles. By creating a predefined changeset post with a known UUID that we use in iFrameSrc(), we guarantee that the preview will work for all authorized user roles.

Motivation and context

  • Fixes VIPCMS-1383
  • Root issue: When the Engagement Boost preview iframe is loaded, it calls the WordPress Customizer in the iFrameSrc() function. The Customizer requires the current user to have the customize capability (available to Administrators), or the passed UUID to have a corresponding changeset post in the database. Otherwise it fails with -1 ("Non-existent changeset UUID") and prevents preview, displaying "-1".

How has this been tested?

Using the current develop branch, use Engagement Boost with a non-administrator account, and notice the "-1" in the preview pane. Repeat the steps with this patch, and the post content will appear as expected.

Summary by CodeRabbit

  • Bug Fixes

    • Engagement Boost preview now reliably loads for non‑administrator users by using a stable preview identifier to prevent missing or mismatched previews.
  • Chores

    • Automatically ensures the required preview draft is created during admin initialization to support the preview flow.
  • Refactor

    • Consolidated and cleaned up imports in the preview component.

@acicovic acicovic added this to the 3.21.0 milestone Sep 3, 2025
@acicovic acicovic self-assigned this Sep 3, 2025
@acicovic acicovic added the Changelog: Fixed PR to be added under the changelog's "Fixed" section label Sep 3, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 3, 2025

📝 Walkthrough

Walkthrough

Adds a fixed UUID for the Traffic Boost preview iFrame and creates a matching private customize_changeset post on admin_init when permitted; also consolidates a duplicated import in the React preview component. No exported/public signatures changed.

Changes

Cohort / File(s) Summary of changes
Traffic Boost Preview iFrame
src/content-helper/dashboard-page/pages/traffic-boost/preview/components/preview-iframe.tsx
Removed duplicate import of useExistingLinkHighlight. Replaced crypto.randomUUID() with hard-coded UUID 905b130b-4129-4416-919c-9e31433a6f65 for the customize_changeset_uuid iFrame URL param.
WP changeset bootstrap
wp-parsely.php
Added admin_init hook and new Parsely\create_engagement_boost_changeset_post(): void. Validates API secret and Permissions::current_user_can_use_pch_feature, checks for customize_changeset post named wp-parsely-905b130b-4129-4416-919c-9e31433a6f65, and inserts a private post if missing.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor WPAdmin as "WP admin_init"
  participant Plugin as "Parsely Plugin"
  participant DB as "WP Posts DB"
  note over WPAdmin,Plugin: Ensure changeset exists for Engagement Boost preview

  WPAdmin->>Plugin: admin_init
  Plugin->>Plugin: check API secret & Permissions::current_user_can_use_pch_feature
  alt authorized & secret present
    Plugin->>DB: post_exists(slug:"wp-parsely-905b130b-...") 
    alt not found
      Plugin->>DB: wp_insert_post(type:customize_changeset, status:private)
      DB-->>Plugin: post_id
    else found
      DB-->>Plugin: existing post_id
    end
  else not authorized or missing secret
    Plugin-->>WPAdmin: return early
  end
Loading
sequenceDiagram
  autonumber
  actor User as "Dashboard user"
  participant React as "PreviewIframe (React)"
  participant Site as "Target site (preview)"
  note over React: Build iFrame URL with fixed customize_changeset_uuid

  User->>React: open Traffic Boost preview
  React->>React: useMemo -> iFrameSrc(..., uuid="905b130b-4129-4416-919c-9e31433a6f65")
  React->>Site: load iFrame URL with customize_changeset_uuid
  Site-->>React: render preview with changeset context
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

Feature: Traffic Boost, wp-parsely

Suggested reviewers

  • vaurdan
  • maxschmeling

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 PHPStan (2.1.17)

Note: Using configuration file /phpstan.neon.
Invalid configuration:
Unexpected item 'parameters › type_coverage'.


📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 835b1a5 and 3d419e9.

📒 Files selected for processing (1)
  • wp-parsely.php (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • wp-parsely.php
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Basic CS and QA checks
  • GitHub Check: E2E against WordPress latest
  • GitHub Check: build
  • GitHub Check: Basic CS and QA checks
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/engagement-boost-preview-display-for-non-administrators

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@acicovic acicovic marked this pull request as ready for review September 3, 2025 14:56
@acicovic acicovic requested a review from a team as a code owner September 3, 2025 14:56
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (4)
src/content-helper/dashboard-page/pages/traffic-boost/preview/components/preview-iframe.tsx (1)

89-94: Avoid hard-coding the UUID in JS; source it from PHP and fix comment/doc.

  • Use a single source of truth: expose the UUID from PHP (localized/inline script) and read it here to prevent drift with wp-parsely.php.
  • The nearby JSDoc still says “random UUID”; update it to “predefined UUID.”
  • Add a period to the first inline comment to satisfy the guideline.

Apply within this range:

-		// Needs to match the UUID in create_engagement_boost_changeset_post()
+		// Needs to match the UUID in create_engagement_boost_changeset_post().
 		// in wp-parsely.php.
-		const uuid = '905b130b-4129-4416-919c-9e31433a6f65';
+		const uuid =
+			// Prefer server-provided value to avoid drift with PHP.
+			((window as any)?.wpParsely?.engagementBoostChangesetUuid as string) ??
+			'905b130b-4129-4416-919c-9e31433a6f65';
 		const url = new URL( previewUrl );
 		url.searchParams.set( 'customize_changeset_uuid', uuid );

Outside this range, update the JSDoc above iFrameSrc to reflect that we use a predefined UUID rather than a random one, and include an @SInCE 3.21.0 tag.

wp-parsely.php (3)

119-135: Tighten the docblock and future-proof references.

  • Referencing a specific line number in core (class-wp-customize-manager.php) is brittle; consider removing it.
  • Keep the excellent rationale but trim incidental implementation details.

149-158: Handle insertion errors and avoid silent failures.

Check for WP_Error from wp_insert_post to prevent unnoticed failures; request an error object via the $wp_error flag.

Apply within this range:

-	if ( 0 === $post_id ) {
-		wp_insert_post(
-			array(
-				'post_type'   => 'customize_changeset',
-				'post_name'   => $uuid,
-				'post_title'  => "wp-parsely-$uuid",
-				'post_status' => 'private',
-			)
-		);
-	}
+	if ( 0 === $post_id ) {
+		$result = wp_insert_post(
+			array(
+				'post_type'   => 'customize_changeset',
+				'post_name'   => $uuid,
+				'post_title'  => "wp-parsely-$uuid",
+				'post_status' => 'private',
+			),
+			true // Return WP_Error on failure.
+		);
+		if ( is_wp_error( $result ) ) {
+			// Optional: log via your plugin's logging mechanism.
+			return;
+		}
+	}

117-159: Centralize the UUID and pass it to JS.

Define a plugin-level constant for the changeset UUID and expose it to the admin script to remove duplication and drift risk with TS.

Example (outside this range):

  • Define a constant near other plugin constants:
    • define( NAMESPACE . '\EB_CHANGESET_UUID', '905b130b-4129-4416-919c-9e31433a6f65' );
  • When registering/enqueueing the Content Helper scripts, add:
    • wp_add_inline_script( 'wp-parsely-admin', 'window.wpParsely = window.wpParsely || {}; window.wpParsely.engagementBoostChangesetUuid = ' . wp_json_encode( EB_CHANGESET_UUID ) . ';', 'before' );
  • Use EB_CHANGESET_UUID in create_engagement_boost_changeset_post().
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between a1d9d6d and 90b7972.

⛔ Files ignored due to path filters (2)
  • build/content-helper/dashboard-page.asset.php is excluded by !build/**
  • build/content-helper/dashboard-page.js is excluded by !build/**
📒 Files selected for processing (2)
  • src/content-helper/dashboard-page/pages/traffic-boost/preview/components/preview-iframe.tsx (2 hunks)
  • wp-parsely.php (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{js,ts,tsx,jsx}

⚙️ CodeRabbit configuration file

**/*.{js,ts,tsx,jsx}: "Perform a detailed review of the provided code with following key aspects in mind:

  • Review the code to ensure it is well-structured and adheres to best practices.
  • Verify compliance with WordPress coding standards.
  • Ensure the code is well-documented.
  • Check for security vulnerabilities and confirm the code is secure.
  • Optimize the code for performance, removing any unnecessary elements.
  • Validate JSDoc comments for accuracy, currency, and adherence to WordPress coding standards.
  • Ensure each line comment concludes with a period.
  • Confirm every JSDoc comment includes a @SInCE tag indicating the next version of the plugin to include the code.
  • Guarantee compatibility with the latest version of WordPress, avoiding deprecated functions or features."

Files:

  • src/content-helper/dashboard-page/pages/traffic-boost/preview/components/preview-iframe.tsx
**/*.{html,php}

⚙️ CodeRabbit configuration file

**/*.{html,php}: "Perform a detailed review of the provided code with following key aspects in mind:

  • Review the HTML and PHP code to ensure it is well-structured and adheres to best practices.
  • Ensure the code follows WordPress coding standards and is well-documented.
  • Confirm the code is secure and free from vulnerabilities.
  • Optimize the code for performance, removing any unnecessary elements.
  • Validate comments for accuracy, currency, and adherence to WordPress coding standards.
  • Ensure each line comment concludes with a period.
  • Verify code compatibility with the latest version of WordPress, avoiding deprecated functions or features."

Files:

  • wp-parsely.php
🧬 Code graph analysis (1)
wp-parsely.php (2)
src/class-parsely.php (2)
  • api_secret_is_set (835-839)
  • get_options (550-610)
src/class-permissions.php (2)
  • Permissions (21-215)
  • current_user_can_use_pch_feature (57-148)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build
  • GitHub Check: E2E against WordPress latest
🔇 Additional comments (2)
src/content-helper/dashboard-page/pages/traffic-boost/preview/components/preview-iframe.tsx (1)

17-17: Import cleanup looks good.

Consolidating the hook import removes duplication without behavior changes.

wp-parsely.php (1)

117-117: Hook placement is fine.

Running on admin_init is appropriate for ensuring the changeset post exists when the admin UI loads.

@acicovic acicovic linked an issue Sep 3, 2025 that may be closed by this pull request
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (2)
wp-parsely.php (2)

149-151: Filename fixed in the comment—thanks for addressing.

“preview-iframe.tsx” reference is now correct and ends with a period.


136-152: Load post_exists() instead of bailing; call the global function explicitly.

Early-returning when post_exists() isn’t loaded makes the fix a no-op on admin requests where that file isn’t included. Require the file and use the global function to avoid namespace lookup and ensure execution.

-	if ( ! function_exists( 'post_exists' ) ) {
-		return;
-	}
+	if ( ! function_exists( '\post_exists' ) ) {
+		require_once ABSPATH . 'wp-admin/includes/post.php';
+	}
@@
-	$post_id = post_exists( "wp-parsely-$uuid", '', '', 'customize_changeset', 'private' );
+	$post_id = \post_exists( "wp-parsely-$uuid", '', '', 'customize_changeset', 'private' );
🧹 Nitpick comments (2)
wp-parsely.php (2)

126-128: Avoid brittle core line-number reference in docs.

Referencing specific core line numbers will drift across WP versions.

- * it fails with -1 ("Non-existent changeset UUID") around line 561 in
- * `class-wp-customize-manager.php` and prevents preview, displaying "-1".
+ * it fails with -1 ("Non-existent changeset UUID") in `class-wp-customize-manager.php` and prevents preview, displaying "-1".

151-154: Use slug-based lookup to avoid duplicate changesets across statuses.

post_exists() with a strict 'private' status can miss an existing changeset (e.g., trashed/draft), causing a new post with a suffixed slug. Look up by slug across any status.

-	$post_id = \post_exists( "wp-parsely-$uuid", '', '', 'customize_changeset', 'private' );
+	$existing = get_posts(
+		array(
+			'name'           => $uuid,
+			'post_type'      => 'customize_changeset',
+			'post_status'    => 'any',
+			'fields'         => 'ids',
+			'posts_per_page' => 1,
+			'no_found_rows'  => true,
+		)
+	);
+	$post_id = $existing ? (int) $existing[0] : 0;
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 90b7972 and 835b1a5.

📒 Files selected for processing (2)
  • src/content-helper/dashboard-page/pages/traffic-boost/preview/components/preview-iframe.tsx (2 hunks)
  • wp-parsely.php (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/content-helper/dashboard-page/pages/traffic-boost/preview/components/preview-iframe.tsx
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{html,php}

⚙️ CodeRabbit configuration file

**/*.{html,php}: "Perform a detailed review of the provided code with following key aspects in mind:

  • Review the HTML and PHP code to ensure it is well-structured and adheres to best practices.
  • Ensure the code follows WordPress coding standards and is well-documented.
  • Confirm the code is secure and free from vulnerabilities.
  • Optimize the code for performance, removing any unnecessary elements.
  • Validate comments for accuracy, currency, and adherence to WordPress coding standards.
  • Ensure each line comment concludes with a period.
  • Verify code compatibility with the latest version of WordPress, avoiding deprecated functions or features."

Files:

  • wp-parsely.php
🧬 Code graph analysis (1)
wp-parsely.php (2)
src/class-parsely.php (2)
  • api_secret_is_set (835-839)
  • get_options (550-610)
src/class-permissions.php (1)
  • current_user_can_use_pch_feature (57-148)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: E2E against WordPress latest
  • GitHub Check: build
  • GitHub Check: build
🔇 Additional comments (1)
wp-parsely.php (1)

149-151: UUID alignment verified. The UUID in wp-parsely.php matches the one in preview-iframe.tsx; no further discrepancies found.

Copy link
Contributor

@alecgeatches alecgeatches left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Insane bug and fix. I've tested locally and confirmed this fixes the issue for an editor user. Great job!

@acicovic acicovic added the Do not merge PR which shouldn't get merged yet label Sep 3, 2025
@acicovic
Copy link
Collaborator Author

acicovic commented Sep 3, 2025

Adding a "Do not merge" label here for the time being, as this will be ported to a fix release instead of 3.21.0.

@acicovic acicovic modified the milestones: 3.21.0, 3.20.7 Sep 5, 2025
@acicovic acicovic removed the Do not merge PR which shouldn't get merged yet label Sep 5, 2025
@acicovic acicovic changed the title Fix Engagement Boost preview display for non-administrators Engagement Boost: Make preview work non-administrators Sep 5, 2025
@acicovic acicovic changed the title Engagement Boost: Make preview work non-administrators Engagement Boost: Make preview work for non-administrators Sep 5, 2025
@acicovic acicovic merged commit f5cf607 into develop Sep 8, 2025
33 checks passed
@acicovic acicovic deleted the fix/engagement-boost-preview-display-for-non-administrators branch September 8, 2025 09:00
github-actions bot added a commit that referenced this pull request Sep 8, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Changelog: Fixed PR to be added under the changelog's "Fixed" section

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Engagement Boost preview doesn't work for non-administrators

3 participants