Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build/content-helper/editor-sidebar.asset.php
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<?php return array('dependencies' => array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-dom-ready', 'wp-editor', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-plugins', 'wp-primitives', 'wp-url', 'wp-wordcount'), 'version' => 'c9080d57a24fb01fef39');
<?php return array('dependencies' => array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-dom-ready', 'wp-editor', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-plugins', 'wp-primitives', 'wp-url', 'wp-wordcount'), 'version' => '7c5cedb79ff5158540d1');
8 changes: 4 additions & 4 deletions build/content-helper/editor-sidebar.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/@types/assets/window.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ declare global {
onReady?: () => unknown,
},

wpParselyAdminUrl: string;
wpParselyContentHelperPermissions: string;
wpParselyContentHelperSettings: string;
wpParselyDependencies: { [key: string]: string };
Expand Down
7 changes: 6 additions & 1 deletion src/UI/class-site-health.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,11 @@ public function check_site_id( array $tests ): array {
if ( $this->parsely->site_id_is_missing() ) {
$result['status'] = 'critical';
$result['label'] = __( 'You need to provide the Site ID', 'wp-parsely' );
$result['actions'] = __( 'The site ID can be set in the <a href="/wp-admin/admin.php?page=parsely-settings">Parse.ly Settings Page</a>.', 'wp-parsely' );
$result['actions'] = sprintf(
/* translators: %s: URL to the Parse.ly settings page */
__( 'The site ID can be set in the <a href="%s">Parse.ly Settings Page</a>.', 'wp-parsely' ),
esc_url( Parsely::get_settings_url() )
);
}

return $result;
Expand All @@ -100,6 +104,7 @@ public function check_site_id( array $tests ): array {
'label' => __( 'Parse.ly Site ID', 'wp-parsely' ),
'test' => $test,
);
$tests['direct'] = $direct;

return $tests;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ protected function get_credentials_not_set_message(): string {
'Existing Parse.ly customers can enable this feature by setting their Site ID and API Secret in ',
'wp-parsely'
) . '
<a href="/wp-admin/admin.php?page=parsely-settings" target="_blank" rel="noopener">' .
<a href="' . esc_url( Parsely::get_settings_url() ) . '" target="_blank" rel="noopener">' .
__( 'wp-parsely options.', 'wp-parsely' ) . '
</a>
</p>
Expand Down
7 changes: 7 additions & 0 deletions src/content-helper/editor-sidebar/class-editor-sidebar.php
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,13 @@ public function run(): void {
);
}

// Inject the admin URL for generating admin page links.
wp_add_inline_script(
static::get_script_id(),
'window.wpParselyAdminUrl = ' . wp_json_encode( admin_url() ) . ';',
'before'
);

// Inject the trackable statuses.
$trackable_statuses = Parsely::get_trackable_statuses();
wp_add_inline_script(
Expand Down
15 changes: 14 additions & 1 deletion src/content-helper/editor-sidebar/tabs/sidebar-tools-tab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,19 @@
import { SmartLinkingPanel, SmartLinkingPanelContext } from '../smart-linking/component';
import { TitleSuggestionsPanel } from '../title-suggestions/component';

/**
* Builds the Boost Engagement button URL from the admin base URL and post ID.
*
* @since 3.22.1
*
* @param {string} adminUrl The WordPress admin base URL.
* @param {number} postId The current post ID.
* @return {string} The full URL to the engagement-boost page for the given post.
*/
export function getBoostEngagementUrl( adminUrl: string, postId: number ): string {
return `${ adminUrl }admin.php?page=parsely-dashboard-page#/engagement-boost/${ postId }`;
}

/**
* SidebarToolsTab component props.
*
Expand Down Expand Up @@ -137,7 +150,7 @@
{ postId > 0 && isPostTrackable && permissions.TrafficBoost &&
<Button
className="boost-engagement"
href={ `/wp-admin/admin.php?page=parsely-dashboard-page#/engagement-boost/${ postId }` }
href={ getBoostEngagementUrl( window.wpParselyAdminUrl, postId ) }

Check warning on line 153 in src/content-helper/editor-sidebar/tabs/sidebar-tools-tab.tsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Prefer `globalThis` over `window`.

See more on https://sonarcloud.io/project/issues?id=Parsely_wp-parsely&issues=AZ0q5ihyuRddeggGrfDk&open=AZ0q5ihyuRddeggGrfDk&pullRequest=4095
rel="noopener"
target="_blank"
variant="secondary"
Expand Down
24 changes: 24 additions & 0 deletions tests/Integration/UI/SettingsPageTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,30 @@ public function test_get_settings_url_with_and_without_blog_id(): void {
);
}

/**
* Verifies that get_settings_url() returns the correct URL when WordPress
* is installed in a subdirectory, where admin_url() differs from home_url()
* (i.e. siteurl ≠ home option).
*
* @since 3.22.1
*
* @covers \Parsely\Parsely::get_settings_url
*/
public function test_get_settings_url_with_subdirectory_install(): void {
$original_siteurl = get_option( 'siteurl' );
update_option( 'siteurl', 'http://example.org/wordpress' );

try {
self::assertSame(
'http://example.org/wordpress/wp-admin/admin.php?page=parsely-settings',
self::$parsely::get_settings_url(),
'The URL must reflect the subdirectory siteurl, not a hardcoded /wp-admin/ path.'
);
} finally {
update_option( 'siteurl', $original_siteurl );
}
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

/**
* Verifies that the HTML markup generated for managed option fields is as
* expected.
Expand Down
48 changes: 48 additions & 0 deletions tests/Integration/UI/SiteHealthTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,54 @@ public function test_admin_bar_enqueued(): void {
self::assertSame( 10, has_filter( 'debug_information', array( self::$site_health, 'options_debug_info' ) ) );
}

/**
* Verifies that the actions link in check_site_id() uses the correct admin
* URL when WordPress is installed in a subdirectory, where admin_url() differs
* from home_url() (i.e. siteurl ≠ home option).
*
* @since 3.22.1
*
* @covers \Parsely\UI\Site_Health::check_site_id
* @uses \Parsely\Parsely::get_settings_url
* @uses \Parsely\Parsely::site_id_is_missing
*/
public function test_check_site_id_uses_admin_url_for_subdirectory_install(): void {
$original_siteurl = get_option( 'siteurl' );
update_option( 'siteurl', 'http://example.org/wordpress' );

try {
// Re-instantiate so that get_settings_url() picks up the updated siteurl.
self::$site_health = new Site_Health( new Parsely() );

// Remove the Site ID to trigger the "critical" branch that renders the link.
self::set_options( array( 'apikey' => '' ) );

$tests = self::$site_health->check_site_id( array( 'direct' => array() ) );

// Assert the expected structure before drilling into it. This also
// narrows the types for static analysis.
self::assertIsArray( $tests['direct'] );
self::assertIsArray( $tests['direct']['parsely'] );
self::assertIsCallable( $tests['direct']['parsely']['test'] );

/** @var array{actions?: string} $result */
$result = ( $tests['direct']['parsely']['test'] )();

self::assertStringContainsString(
'http://example.org/wordpress/wp-admin/admin.php?page=parsely-settings',
$result['actions'] ?? '',
'The actions link must reflect the subdirectory admin URL.'
);
self::assertStringNotContainsString(
'href="/wp-admin/',
$result['actions'] ?? '',
'The actions link must not contain a hardcoded root /wp-admin/ path.'
);
} finally {
update_option( 'siteurl', $original_siteurl );
}
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

/**
* Verifies that options_debug_info() can populate the args array to be
* consumed by WordPress.
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/specs/front-end-metadata.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ test.describe( 'Front end metadata insertion', () => {
await setSiteKeys( page, VALID_SITE_ID, '' );

// Activate tracking for logged-in users.
await page.goto( '/wp-admin/admin.php?page=parsely-settings' );
await page.goto( 'wp-admin/admin.php?page=parsely-settings' );
await page.getByLabel( 'Yes, track logged-in users.' ).click();
await page.getByRole( 'button', { name: 'Save Changes' } ).click();
} );
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/specs/settings-track-post-types-as.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ class Utils {
* @since 3.17.0 Migrated to Playwright.
*/
async activateRecrawlSection(): Promise<void> {
await this.page.goto( '/wp-admin/admin.php?page=parsely-settings' );
await this.page.goto( 'wp-admin/admin.php?page=parsely-settings' );
await this.page.click( '.recrawl-section-tab' );
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* Internal dependencies
*/
import { getBoostEngagementUrl } from '../../../../src/content-helper/editor-sidebar/tabs/sidebar-tools-tab';

describe( 'getBoostEngagementUrl', () => {
/**
* Verifies the URL is built correctly on a standard (root) install.
*
* @since 3.22.1
*/
it( 'builds the correct URL on a standard install', () => {
expect( getBoostEngagementUrl( 'http://example.org/wp-admin/', 123 ) ).toBe(
'http://example.org/wp-admin/admin.php?page=parsely-dashboard-page#/engagement-boost/123'
);
} );

/**
* Verifies the URL is built correctly on a subdirectory install where the
* admin URL differs from the site URL (e.g. siteurl = https://example.org/wordpress).
*
* @since 3.22.1
*/
it( 'builds the correct URL on a subdirectory install', () => {
const url = getBoostEngagementUrl( 'http://example.org/wordpress/wp-admin/', 99 );

expect( url ).toBe(
'http://example.org/wordpress/wp-admin/admin.php?page=parsely-dashboard-page#/engagement-boost/99'
);
expect( url ).not.toMatch( /^\/wp-admin\// );
} );
} );
Loading