Skip to content

Conversation

@benbowler
Copy link
Collaborator

Summary

Addresses issue:

Relevant technical choices

PR Author Checklist

  • My code is tested and passes existing unit tests.
  • My code has an appropriate set of unit tests which all pass.
  • My code is backward-compatible with WordPress 5.2 and PHP 7.4.
  • My code follows the WordPress coding standards.
  • My code has proper inline documentation.
  • I have added a QA Brief on the issue linked above.
  • I have signed the Contributor License Agreement (see https://cla.developers.google.com/).

Do not alter or remove anything below. The following sections will be managed by moderators only.

Code Reviewer Checklist

  • Run the code.
  • Ensure the acceptance criteria are satisfied.
  • Reassess the implementation with the IB.
  • Ensure no unrelated changes are included.
  • Ensure CI checks pass.
  • Check Storybook where applicable.
  • Ensure there is a QA Brief.
  • Ensure there are no unexpected significant changes to file sizes.

Merge Reviewer Checklist

  • Ensure the PR has the correct target branch.
  • Double-check that the PR is okay to be merged.
  • Ensure the corresponding issue has a ZenHub release assigned.
  • Add a changelog message to the issue.

@benbowler benbowler changed the base branch from poc/pointes-update to develop October 22, 2025 11:13
@github-actions
Copy link

Storybook is ready:

@github-actions
Copy link

github-actions bot commented Oct 22, 2025

Size Change: +397 B (+0.02%)

Total Size: 2.19 MB

ℹ️ View Unchanged
Filename Size Change
./dist/assets/blocks/reader-revenue-manager/block-editor-plugin/editor-styles.css 124 B 0 B
./dist/assets/blocks/reader-revenue-manager/block-editor-plugin/editor-styles.js 20 B 0 B
./dist/assets/blocks/reader-revenue-manager/block-editor-plugin/index.js 42.7 kB 0 B
./dist/assets/blocks/reader-revenue-manager/common/editor-styles.css 307 B 0 B
./dist/assets/blocks/reader-revenue-manager/common/editor-styles.js 20 B 0 B
./dist/assets/blocks/reader-revenue-manager/contribute-with-google/index.js 5.88 kB 0 B
./dist/assets/blocks/reader-revenue-manager/contribute-with-google/non-site-kit-user.js 5.07 kB 0 B
./dist/assets/blocks/reader-revenue-manager/subscribe-with-google/index.js 5.88 kB 0 B
./dist/assets/blocks/reader-revenue-manager/subscribe-with-google/non-site-kit-user.js 5.07 kB 0 B
./dist/assets/blocks/sign-in-with-google/editor-styles.css 84 B 0 B
./dist/assets/blocks/sign-in-with-google/editor-styles.js 20 B 0 B
./dist/assets/blocks/sign-in-with-google/index.js 18.6 kB 0 B
./dist/assets/css/googlesitekit-admin-css-********************.min.css 64.4 kB 0 B
./dist/assets/css/googlesitekit-adminbar-css-********************.min.css 11.7 kB 0 B
./dist/assets/css/googlesitekit-authorize-application-css-********************.min.css 846 B 0 B
./dist/assets/css/googlesitekit-wp-dashboard-css-********************.min.css 8.57 kB +143 B (+1.7%)
./dist/assets/js/146-********************.js 963 B 0 B
./dist/assets/js/201-********************.js 2.85 kB 0 B
./dist/assets/js/314-********************.js 100 kB 0 B
./dist/assets/js/315-********************.js 3.08 kB 0 B
./dist/assets/js/379-********************.js 3.7 kB 0 B
./dist/assets/js/590-********************.js 1.89 kB 0 B
./dist/assets/js/640-********************.js 2.36 kB 0 B
./dist/assets/js/909-********************.js 1.01 kB 0 B
./dist/assets/js/analytics-advanced-tracking-********************.js 475 B 0 B
./dist/assets/js/googlesitekit-activation-********************.js 24 kB 0 B
./dist/assets/js/googlesitekit-ad-blocking-recovery-********************.js 54.8 kB 0 B
./dist/assets/js/googlesitekit-adminbar-********************.js 34.4 kB 0 B
./dist/assets/js/googlesitekit-api-********************.js 7.79 kB 0 B
./dist/assets/js/googlesitekit-block-tracking-********************.js 5.51 kB 0 B
./dist/assets/js/googlesitekit-components-********************.js 5.74 kB 0 B
./dist/assets/js/googlesitekit-consent-mode-********************.js 25.5 kB 0 B
./dist/assets/js/googlesitekit-data-********************.js 1.7 kB 0 B
./dist/assets/js/googlesitekit-datastore-forms-********************.js 6.99 kB 0 B
./dist/assets/js/googlesitekit-datastore-location-********************.js 1.51 kB 0 B
./dist/assets/js/googlesitekit-datastore-site-********************.js 17.3 kB 0 B
./dist/assets/js/googlesitekit-datastore-ui-********************.js 7.11 kB 0 B
./dist/assets/js/googlesitekit-datastore-user-********************.js 22.8 kB 0 B
./dist/assets/js/googlesitekit-entity-dashboard-********************.js 61.7 kB +162 B (+0.26%)
./dist/assets/js/googlesitekit-events-provider-contact-form-7-********************.js 1.77 kB 0 B
./dist/assets/js/googlesitekit-events-provider-easy-digital-downloads-********************.js 745 B 0 B
./dist/assets/js/googlesitekit-events-provider-mailchimp-********************.js 1.77 kB 0 B
./dist/assets/js/googlesitekit-events-provider-ninja-forms-********************.js 1.69 kB 0 B
./dist/assets/js/googlesitekit-events-provider-optin-monster-********************.js 1.72 kB 0 B
./dist/assets/js/googlesitekit-events-provider-popup-maker-********************.js 1.79 kB 0 B
./dist/assets/js/googlesitekit-events-provider-woocommerce-********************.js 1.13 kB 0 B
./dist/assets/js/googlesitekit-events-provider-wpforms-********************.js 1.77 kB 0 B
./dist/assets/js/googlesitekit-i18n-********************.js 6.16 kB 0 B
./dist/assets/js/googlesitekit-key-metrics-setup-********************.js 46.4 kB 0 B
./dist/assets/js/googlesitekit-main-dashboard-********************.js 135 kB +92 B (+0.07%)
./dist/assets/js/googlesitekit-metric-selection-********************.js 52.6 kB 0 B
./dist/assets/js/googlesitekit-modules-ads-********************.js 47.5 kB 0 B
./dist/assets/js/googlesitekit-modules-adsense-********************.js 123 kB 0 B
./dist/assets/js/googlesitekit-modules-analytics-4-********************.js 188 kB 0 B
./dist/assets/js/googlesitekit-modules-********************.js 19.9 kB 0 B
./dist/assets/js/googlesitekit-modules-pagespeed-insights-********************.js 23.5 kB 0 B
./dist/assets/js/googlesitekit-modules-reader-revenue-manager-********************.js 43.5 kB 0 B
./dist/assets/js/googlesitekit-modules-search-console-********************.js 65.2 kB 0 B
./dist/assets/js/googlesitekit-modules-sign-in-with-google-********************.js 34.4 kB 0 B
./dist/assets/js/googlesitekit-modules-tagmanager-********************.js 30 kB 0 B
./dist/assets/js/googlesitekit-notifications-********************.js 66.6 kB 0 B
./dist/assets/js/googlesitekit-polyfills-********************.js 230 B 0 B
./dist/assets/js/googlesitekit-settings-********************.js 124 kB 0 B
./dist/assets/js/googlesitekit-splash-********************.js 73.2 kB 0 B
./dist/assets/js/googlesitekit-user-input-********************.js 45.9 kB 0 B
./dist/assets/js/googlesitekit-vendor-********************.js 322 kB 0 B
./dist/assets/js/googlesitekit-widgets-********************.js 104 kB 0 B
./dist/assets/js/googlesitekit-wp-dashboard-********************.js 59.1 kB 0 B
./dist/assets/js/runtime-********************.js 1.93 kB 0 B

compressed-size-action

@github-actions
Copy link

github-actions bot commented Oct 22, 2025

Build files for a6a3b26 have been deleted.

Copy link
Collaborator

@zutigrm zutigrm left a comment

Choose a reason for hiding this comment

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

Thanks @benbowler mostly looks good, I left you some comments

Copy link
Collaborator

@zutigrm zutigrm left a comment

Choose a reason for hiding this comment

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

LGTM

I removed the commneted out code in scss file

Copy link
Collaborator

@aaemnnosttv aaemnnosttv left a comment

Choose a reason for hiding this comment

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

Thanks @benbowler, I've flagged a few things to address here, some of which should have been addressed in IBR so apologies for the late points.

Let me know if you have any questions or would like to discuss anything more for efficiency.

Also, a few checks are failing. Are these related? If not, they may be fixed in develop – this branch is currently 150+ commits behind so please remember to merge that in often.

}

private function register_permissions_for_user( $user_id ) {
wp_set_current_user( $user_id );
Copy link
Collaborator

Choose a reason for hiding this comment

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

This line shouldn't be necessary since the user ID referenced below should always be from User_Options where it's already passed. It's unexpected that this method may also change the current user.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I had to retain this with the updates to the permissions to be set correctly. Let me know if I'm missing a cleaner way to do this:

wp_set_current_user( $user_id );
$user_options = new User_Options( $this->context, $user_id );
$authentication = new Authentication( $this->context, null, $user_options );
$modules = new Modules( $this->context, null, $user_options, $authentication );
$this->dismissed_items = new Dismissed_Items( $user_options );
$permissions = new Permissions( $this->context, $authentication, $modules, $user_options, $this->dismissed_items );
$permissions->register();
$restore_user = $user_options->switch_user( $user_id );
// Provide proxy credentials so Authentication::is_setup_completed() initial check passes.
$this->fake_proxy_site_connection();
// Mark setup as complete for capability checks.
add_filter( 'googlesitekit_setup_complete', '__return_true', 100 );
// For administrators, additionally satisfy VIEW_DASHBOARD via the authenticated dashboard path.
if ( in_array( 'administrator', ( new \WP_User( $user_id ) )->roles, true ) ) {
$authentication->verification()->set( true );
$authentication->get_oauth_client()->set_token(
array(
'access_token' => 'valid-auth-token',
)
);
}
$restore_user();
// Re-register the Email Reporting pointer bound to the current user context so that
// user-scoped checks (subscription, dismissals) use the correct User_Options.
remove_all_filters( 'googlesitekit_admin_pointers' );
$pointer_user_settings = new User_Email_Reporting_Settings( $user_options );
$pointer = new Email_Reporting_Pointer( $this->context, $user_options, $pointer_user_settings );
$pointer->register();

Copy link
Collaborator

Choose a reason for hiding this comment

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

It is needed to work, I was just saying it's better to do in the test than in this utility which is specific to setting permissions. I've gone ahead updated it – there was some additional simplifications that I was able to do as well.

@benbowler
Copy link
Collaborator Author

benbowler commented Oct 28, 2025

Thanks @aaemnnosttv, I've addressed most points above.

Regarding the updates to the button logic in Pointers, I suggest we create a follow-up to address this in a new issue and go back through the definition process to give us to time to properly discuss this rather than going back and forward here. I created a follow-up #11701`

I changed my mind, see below.

@benbowler benbowler mentioned this pull request Oct 28, 2025
1 task
@benbowler
Copy link
Collaborator Author

Addressing this in a follow-up would affect the existing View Only Pointer, so I have updated the button implementation so that the button prop is passed the button HTML, which are simple links. JQuery is still required to track and preventDefault on these links so that we can dismiss (close) the pointer so that it doesn't show again, and in the future track GA events.

@benbowler
Copy link
Collaborator Author

Test failure is unrelated:

  • E2E The block \"google-site-kit/sign-in-with-google\" is registered with API version 2 or lower. This means that the post editor may work as a non-iframe editor.

Copy link
Collaborator

@aaemnnosttv aaemnnosttv left a comment

Choose a reason for hiding this comment

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

Thanks @benbowler – there are still a few things to address here. One thing which really needed some reworking (in general) was the inline pointer JS which I've found a better way to do which also handles much of the escaping and avoids injecting dynamic JS from PHP so I'll push this up at the same time.

import { CORE_UI } from '@/js/googlesitekit/datastore/ui/constants';
import { USER_SETTINGS_SELECTION_PANEL_OPENED_KEY } from './email-reporting/constants';

export default function CoreDashboardEffects() {
Copy link
Collaborator

Choose a reason for hiding this comment

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

One important difference here with the Module version is that modules can register two different effect components – one for the main and entity dashboards respectively. Core doesn't need to register its effects so its components are simpler, but it would make sense to follow the same pattern where this top level component renders the dashboard-specific variant based on the context.

If this is getting out of scope we could address it in a follow up too, I just wanted to highlight this detail for maintaining consistency.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I've continued with a single component for now across main and entity dashboards and created #11712 to split this out in future.

* limitations under the License.
*/

.googlesitekit-pointer-cta--dismiss {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This doesn't quite look like the design. This is what I see

Image

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

In the designs the X icon takes the color from the Pointer header, however, to maintain compatibility with the WP theme the pointer header will take the primary color of the theme. Therefore I went with black for this icon to work across all possible customised theme colors.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Let's iterate on this in a follow up as we should be able to match it even with custom admin themes.

Copy link
Collaborator

@aaemnnosttv aaemnnosttv left a comment

Choose a reason for hiding this comment

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

Thanks again @benbowler, I think this is pretty close now. I've left a few more comments and also tried to explain some of the changes I made – apologies for making as many as I did!

Comment on lines +189 to +194
'data-slug' => $pointer->get_slug(),
'data-class' => implode( ' ', $class ),
'data-target-id' => $pointer->get_target_id(),
'data-title' => wp_kses( $pointer->get_title(), $kses_title ),
'data-content' => wp_kses( $content, $kses_content ),
'data-position' => wp_json_encode( $pointer->get_position() ),
Copy link
Collaborator

Choose a reason for hiding this comment

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

These will all be escaped as attributes automatically so no escaping is needed here, but the values should still be sanitized/cleaned with wp_kses where relevant. Most importantly, no content is injected directly into JS anymore.

}

public function test_get_buttons() {
$buttons = 'function(event, container) { return jQuery("<button>OK</button>"); }';
Copy link
Collaborator

Choose a reason for hiding this comment

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

This should be updated since JS can't be passed through from this class any more.

Comment on lines 33 to 39
private Context $context;

private User_Options $user_options;

private Dismissed_Items $dismissed_items;

private User_Email_Reporting_Settings $email_reporting_settings;
Copy link
Collaborator

Choose a reason for hiding this comment

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

We don't require the full doc blocks for test classes so I've made this more succinct with typed properties.

use Google\Site_Kit\Core\Modules\Module_Sharing_Settings;
use Google\Site_Kit\Core\Storage\Options;
use Google\Site_Kit\Core\Storage\User_Options;
use Google\Site_Kit\Core\User\Email_Reporting_Settings as User_Email_Reporting_Settings;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Looking at this now, why are we aliasing the name?

* @group Util
* @group Email_Reporting
*/
class Email_Reporting_PointerTest extends TestCase {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I made a fair number of simplifications here. For example, a lot of the permissions related code was unnecessary.

@benbowler
Copy link
Collaborator Author

Thanks @aaemnnosttv, I have addressed the outstanding comments I could see and fixed issues with dismissal that were introduced.

I have added a number of comments inline above.

Copy link
Collaborator

@aaemnnosttv aaemnnosttv left a comment

Choose a reason for hiding this comment

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

Thanks @benbowler , just a very few minor updates to make and a merge conflict which I can resolve and then this is good to go.

}

public function test_get_buttons() {
$buttons = 'function(event, container) { return jQuery("<button>OK</button>"); }';
Copy link
Collaborator

Choose a reason for hiding this comment

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

The fact that this test passes with this input somewhat sets the expectation that this method is intended to return JS and would work although that's no longer the case.

/**
* WordPress dependencies
*/
import { useMount } from 'react-use';
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is an external dependency, not WP.

'title' => sprintf(
'%s %s',
__( 'You now have access to Site Kit', 'google-site-kit' ),
'<button type=\'button\' class=\'googlesitekit-pointer-cta--dismiss dashicons dashicons-no\' data-action=\'dismiss\'>' .
Copy link
Collaborator

Choose a reason for hiding this comment

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

Let's not escape the inner quotes unnecessarily.

'class' => 'googlesitekit-view-only-pointer',
'buttons' =>
sprintf(
'<a class=\'googlesitekit-pointer-cta button-primary\' href=\'admin.php?page=googlesitekit-dashboard\' data-action=\'dismiss\'>%s</a>',
Copy link
Collaborator

Choose a reason for hiding this comment

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

Same here, but also the href should be absolute.

@aaemnnosttv
Copy link
Collaborator

The failing JS test is an unrelated instability in AMPContainerSelect.

Copy link
Collaborator

@aaemnnosttv aaemnnosttv left a comment

Choose a reason for hiding this comment

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

LGTM, thanks @benbowler!

@aaemnnosttv aaemnnosttv merged commit e1a6f0e into develop Nov 5, 2025
31 of 33 checks passed
@aaemnnosttv aaemnnosttv deleted the enhancement/11433-pue-pointer branch November 5, 2025 19:43
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