Skip to content

Traffic Boost: Add backend implementation #3149

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 33 commits into from
Mar 10, 2025

Conversation

vaurdan
Copy link

@vaurdan vaurdan commented Feb 26, 2025

Description

This PR implements the backend for Traffic Boost, that integrates with the Suggestions API to generate traffic boost suggestions.

Alongside the new services added - suggest-inbound-links and suggest-inbound-link-positions, a new REST API endpoint (traffic-boost) has been added that allows manipulating the Traffic Boost data (add, remove and list suggestions and existing inbound links).

This PR adds a new composer dependency - masterminds/HTML5 - that helps with the DOM manipulation of the posts where links are added and removed.

Motivation and context

How has this been tested?

Tested locally, on a clean environment and on a clone environment of an existing site. This has also been tested on a staging environment of a VIP site.

No new tests have been implemented yet, but existing tests do pass.

Screenshots (if appropriate)

image
image

Summary by CodeRabbit

  • New Features

    • Introduced a new endpoint for managing traffic boost suggestions.
    • Enhanced capabilities for generating and managing inbound link suggestions, including improved handling of link placements and validations.
    • Added loading state management and error handling improvements across various components.
  • Refactor

    • Upgraded routing and API integrations for more robust error management and smoother interactions.
    • Streamlined logic across preview, dashboard, and suggestion components.
  • Style

    • Refined interface styling for previews, loading indicators, and interactive elements.
  • Tests

    • Expanded test coverage to validate the new traffic boost endpoint integration.

# Conflicts:
#	package-lock.json
#	src/content-helper/common/settings/provider.tsx
@vaurdan vaurdan added Component: PHP Feature: PCH Ticket/PR related to the Content Helper Feature: Traffic Boost Ticket/PR related to Traffic Boost labels Feb 26, 2025
@acicovic
Copy link
Collaborator

acicovic commented Mar 2, 2025

Hey @vaurdan, thanks for working on this, I've completed my review. I also wanted to note that I'm getting these PHPStan errors:

 ------ ---------------------------------------------------------------------- 
  Line   src/Models/class-inbound-smart-link.php                               
 ------ ---------------------------------------------------------------------- 
  501    Parameter #1 $node of method                                          
         Parsely\Models\Inbound_Smart_Link::find_text_node() expects DOMNode,  
         mixed given.                                                          
 ------ ---------------------------------------------------------------------- 

 ------ -------------------------------------------------------------------- 
  Line   src/UI/class-dashboard-page.php                                     
 ------ -------------------------------------------------------------------- 
  71     Strict comparison using === between 0 and 1|2|false will always     
         evaluate to false.                                                  
         💡 Because the type is coming from a PHPDoc, you can turn off this   
            check by setting treatPhpDocTypesAsCertain: false in your        
            phpstan.neon.                                                    
  131    Strict comparison using === between 0 and 1|2|false will always     
         evaluate to false.                                                  
         💡 Because the type is coming from a PHPDoc, you can turn off this   
            check by setting treatPhpDocTypesAsCertain: false in your        
            phpstan.neon.                                                    
 ------ -------------------------------------------------------------------- 

 [ERROR] Found 3 errors                                                         

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 (3)
src/Models/class-inbound-smart-link.php (1)

811-932: Refactor large remove() method.

The remove() method handles multiple concerns (restoring links, removing anchors, updating post meta, etc.), which can become harder to maintain. Consider breaking it into smaller helper methods to improve readability.

src/rest-api/content-helper/class-endpoint-traffic-boost.php (2)

3-9: Add a period to the short description lines.

Per WordPress coding standards, short descriptions in doc blocks should end with a period. Consider adding a period to lines 3 and 4 for consistency.

Apply this diff to fix the short descriptions:

- * Endpoint: Traffic Boost
- * Parse.ly Content Helper `/traffic-boost` API endpoint class
+ * Endpoint: Traffic Boost.
+ * Parse.ly Content Helper `/traffic-boost` API endpoint class.

736-770: Consider integrating additional authorization checks.

The smart link ID validation is thorough. However, there is no explicit check of user roles/capabilities within validate_smart_link_id. If permissions are not enforced in Base_Endpoint, you might expose endpoints to unauthorized users. Confirm that this method is called only when a valid permission callback is in place.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6dd5049 and 4c0aedc.

📒 Files selected for processing (8)
  • src/Models/class-inbound-smart-link.php (6 hunks)
  • src/Models/class-smart-link-status.php (1 hunks)
  • src/Models/class-smart-link.php (22 hunks)
  • src/content-helper/dashboard-page/pages/traffic-boost/sidebar/components/add-new-link-button.tsx (3 hunks)
  • src/content-helper/dashboard-page/pages/traffic-boost/sidebar/components/post-details.tsx (5 hunks)
  • src/content-helper/dashboard-page/pages/traffic-boost/sidebar/components/tabs/inbound-links-tab.tsx (3 hunks)
  • src/rest-api/content-helper/class-endpoint-traffic-boost.php (1 hunks)
  • src/services/suggestions-api/endpoints/class-endpoint-suggest-inbound-links.php (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/Models/class-smart-link-status.php
🧰 Additional context used
📓 Path-based instructions (2)
`**/*.{js,ts,tsx,jsx}`: "Perform a detailed review of the pr...

**/*.{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."
  • src/content-helper/dashboard-page/pages/traffic-boost/sidebar/components/post-details.tsx
  • src/content-helper/dashboard-page/pages/traffic-boost/sidebar/components/tabs/inbound-links-tab.tsx
  • src/content-helper/dashboard-page/pages/traffic-boost/sidebar/components/add-new-link-button.tsx
`**/*.{html,php}`: "Perform a detailed review of the provide...

**/*.{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."
  • src/services/suggestions-api/endpoints/class-endpoint-suggest-inbound-links.php
  • src/Models/class-inbound-smart-link.php
  • src/Models/class-smart-link.php
  • src/rest-api/content-helper/class-endpoint-traffic-boost.php
🪛 Biome (1.9.4)
src/content-helper/dashboard-page/pages/traffic-boost/sidebar/components/post-details.tsx

[error] 44-44: Avoid passing content using the dangerouslySetInnerHTML prop.

Setting content using code can expose users to cross-site scripting (XSS) attacks

(lint/security/noDangerouslySetInnerHtml)

🪛 GitHub Check: SonarCloud
src/Models/class-inbound-smart-link.php

[failure] 585-585: XPath expressions should not be vulnerable to injection attacks

Change this code to not construct this XPath expression from user-controlled data.

See more on SonarQube Cloud

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: E2E against WordPress latest
🔇 Additional comments (21)
src/content-helper/dashboard-page/pages/traffic-boost/sidebar/components/post-details.tsx (2)

4-4: Good addition for loading state management.

Adding the Spinner component provides a better user experience by showing a loading indicator.


19-20: Props interface updates align well with loading state requirements.

Making the post property optional and adding the isLoading boolean enhances component flexibility. This change properly supports the loading state pattern.

src/content-helper/dashboard-page/pages/traffic-boost/sidebar/components/tabs/inbound-links-tab.tsx (4)

5-5: Good addition of internationalization support.

Adding the __ function from @wordpress/i18n ensures proper localization of user-facing strings.


38-39: Well-implemented loading state management.

Correctly adding and using the loading state from the store follows best practices for React and WordPress data management.

Also applies to: 44-45


54-54: Good prop passing for loading state.

Properly passing the loading state to the child component ensures consistent UI behavior.


62-66: Excellent UX with empty state handling.

Adding a specific empty state message improves user experience by providing clear feedback when no inbound links are available. The internationalized message follows WordPress guidelines.

src/content-helper/dashboard-page/pages/traffic-boost/sidebar/components/add-new-link-button.tsx (3)

6-7: Good addition of required dependencies.

Adding the useSelect hook and TrafficBoostStore imports follows WordPress coding standards for proper state management.

Also applies to: 17-17


47-48: Well-implemented state access.

Using useSelect to access the current post from the store follows WordPress data management best practices.


54-62: Important UX improvement to prevent self-referential links.

The logic properly excludes the current post from suggestions, which prevents users from accidentally creating links to the same post they're working on. This is a valuable improvement that helps prevent potential user errors.

The dependency array correctly includes both suggestions and currentPost, ensuring the effect runs when either value changes.

src/services/suggestions-api/endpoints/class-endpoint-suggest-inbound-links.php (4)

1-7: Overall structure looks good.

All high-level elements (namespace, class declaration, docblocks) are well-structured and adhere to WordPress and PHP standards.


69-69: Consider renaming blending_weight.

A past review comment already suggested changing this to performance_blending_weight.


133-133: Update the @since tag.

Past feedback suggests this should match 3.18.0 for consistency with the rest of the file.


85-90:

❓ Verification inconclusive

Verify the existence of anchor_texts.

There is no safeguard if $link['anchor_texts'] is missing or null. Ensure the remote API always returns anchor_texts; otherwise, add a fallback or error check.


🏁 Script executed:

#!/bin/bash
# Description: Searches for references to 'anchor_texts' usage beyond this file to confirm assumptions about the remote API response structure.
ast-grep --pattern $'$_["anchor_texts"]'

Length of output: 41


Action Required: Confirm the API’s "anchor_texts" Key Exists

The code in src/services/suggestions-api/endpoints/class-endpoint-suggest-inbound-links.php (lines 85–90) assumes that $link['anchor_texts'] is always defined. However, our initial ast-grep search for this key didn’t yield any further occurrences in the repository. Please manually verify that the remote API response consistently includes the "anchor_texts" key. If there’s any chance it might be missing or null, add a safeguard (for example, by wrapping the access in an isset() check or providing a default value).

src/Models/class-inbound-smart-link.php (1)

585-585: Prevent potential XPath injection.

This line builds the XPath query directly using $this->uid. Ensure $this->uid is sanitized or encoded to avoid injection.

- $query = sprintf( '//a[@data-smartlink="%s"]', $this->uid );
+ $sanitized_uid = esc_attr( $this->uid );
+ $query         = '//a[@data-smartlink="' . $sanitized_uid . '"]';
🧰 Tools
🪛 GitHub Check: SonarCloud

[failure] 585-585: XPath expressions should not be vulnerable to injection attacks

Change this code to not construct this XPath expression from user-controlled data.

See more on SonarQube Cloud

src/Models/class-smart-link.php (2)

40-47: Recheck @since 3.16.0.

Previous reviews noted this likely belongs to a later version (e.g., 3.18.0) since the property is newly added.


1-1019: All other changes appear consistent.

No further security or functionality concerns in the remaining lines. Good adherence to WordPress coding standards and code organization.

src/rest-api/content-helper/class-endpoint-traffic-boost.php (5)

7-7: Version annotation verification.

You've placed multiple @since 3.17.0 annotations across this file. Verify that the version references accurately map to features introduced in 3.17.0 vs. 3.18.0, as some functions are tagged with 3.18.0.


32-34: Reusable trait usage looks clean.

Using the Content_Helper_Feature trait and Use_Post_ID_Parameter_Trait keeps code modular and consistent with the rest of the plugin. No issues noted here.


79-83: Missing explicit REST permissions callback.

While the routes are registered correctly, it’s not obvious whether Base_Endpoint enforces a permissions check. Ensure that each route requires the correct user capability to prevent unauthorized API calls.


92-92: We aren’t setting required here, in contrast to other route registrations.

This is identical to a past review comment mentioning the inconsistent use of 'required' => true for parameters across routes. If the parameter truly isn't mandatory, please confirm or document why.


293-303: Discarding previous suggestions logic appears correct.

The optional discard_previous parameter and its handling here look well-implemented. This helps avoid stacking stale suggestions. No further adjustments needed.

@vaurdan
Copy link
Author

vaurdan commented Mar 6, 2025

@acicovic I have addressed your feedback! I will now move to check Code Rabbit's feedback and fix any issues in another commit.

I also wanted to note that I'm getting these PHPStan errors:

Interesting, I don't see the src/Models/class-inbound-smart-link.php error in my PHPStan. Running with phpstan 1.12.20, after running composer update.

$ composer static-analysis
> @php ./vendor/bin/phpstan analyze --memory-limit=2G
Note: Using configuration file /Users/henrique/Repositories/wp-parsely/phpstan.neon.
 165/165 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%

 ------ -------------------------------------------------------------------------------------------------------------------------------------------- 
  Line   src/UI/class-dashboard-page.php                                                                                                             
 ------ -------------------------------------------------------------------------------------------------------------------------------------------- 
  :71    Strict comparison using === between 0 and 1|2|false will always evaluate to false.                                                          
         💡 Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in your phpstan.neon.  
  :131   Strict comparison using === between 0 and 1|2|false will always evaluate to false.                                                          
         💡 Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in your phpstan.neon.  
 ------ -------------------------------------------------------------------------------------------------------------------------------------------- 
                                                    
 [ERROR] Found 2 errors                                                                                                 
                                                                                                                        
Script @php ./vendor/bin/phpstan analyze --memory-limit=2G handling the static-analysis event returned with error code 1                                                                                                  
                                                                                                                        
$ php ./vendor/bin/phpstan --version
PHPStan - PHP Static Analysis Tool 1.12.20

I have fixed these issues though.

@coderabbitai pause

Copy link
Contributor

coderabbitai bot commented Mar 6, 2025

@vaurdan Thanks for the update! I've confirmed that the PHPStan errors in src/UI/class-dashboard-page.php have been addressed. Interesting that you're not seeing the class-inbound-smart-link.php error that was reported. This could be due to different PHPStan versions or configurations.

I've paused the automated reviews as requested. Just let me know when you'd like me to resume reviewing.

✅ Actions performed

Reviews paused.

@vaurdan vaurdan requested a review from acicovic March 6, 2025 10:22
Copy link
Contributor

coderabbitai bot commented Mar 6, 2025

@vaurdan Thanks for addressing the feedback and fixing the PHPStan errors. I'll pause the automated reviews for this PR as requested.

✅ Actions performed

Reviews paused.

@vaurdan vaurdan linked an issue Mar 6, 2025 that may be closed by this pull request
5 tasks
@vaurdan
Copy link
Author

vaurdan commented Mar 6, 2025

@acicovic SonarCloud is complaining about duplicate lines, but it's actually a false positive and I don't think it warrants a fix. So feel free to ignore the failing status of it, I have addressed all the other issues flagged by it.

@acicovic
Copy link
Collaborator

acicovic commented Mar 7, 2025

Hey @vaurdan, I'm completing my review and I've responded to a couple of conversations. I haven't re-checked PHPStan, but if this is an issue it will surely come up again when work is done against the branch.

@vaurdan
Copy link
Author

vaurdan commented Mar 7, 2025

@acicovic I have addressed your comments in the latest commit, feel free to take a look!

Copy link
Collaborator

@acicovic acicovic left a comment

Choose a reason for hiding this comment

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

Thank you for working on this! 🙂

@vaurdan vaurdan merged commit e708bf8 into add/traffic-boost Mar 10, 2025
38 of 39 checks passed
@vaurdan vaurdan deleted the add/traffic-boost-backend branch March 10, 2025 10:53
@acicovic acicovic modified the milestones: 3.18.0, 3.19.0 Apr 9, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature: PCH Ticket/PR related to the Content Helper Feature: Traffic Boost Ticket/PR related to Traffic Boost
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement Traffic Boost feature
2 participants