Skip to content

Create email reporting data requests classes #11566

@benbowler

Description

@benbowler

Feature Description

Email_Reporting_Data_Requests.php

  • Manage user context switching for each user in the batch
    • Admins using own tokens and plugin active modules
    • View-only uses Dashboard Sharing credentials with access scoped to shared models

Analytics reports should be batched (up to 5 report requests per batch), implementation can be extracted from this PoC)

Email_Reporting_Data.php

  • Restructure data to pass in a structured way to the email template code

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

Acceptance criteria

New Email_Reporting_Data_Requests class is added within Email_Reporting namespace

  • Per-subscriber context switching:
    • Admin subscribers: use their own OAuth tokens; limit to modules active on the site.
    • View-only subscribers: use Dashboard Sharing credentials scoped to the modules shared with that user.
  • GA4 requests are not batched as part of this ticket: this will be implemented in Batch report requests using batchRunReports #11553.
  • Only datapoints permitted in the current user context are requested; recoverable/unavailable modules are skipped.
  • Per-user failures are isolated and returned to Worker to handle and store the error; processing continues for the remaining users - Any single report failure per user causes failure of the whole report data request to avoid missing individual report sections.
  • Outputs raw metric payloads to the data-structuring class only (no template formatting here).

Implementation Brief

Add Core\Email_Reporting\Email_Reporting_Data_Requests class

  • The constructor should accept following instances and store them in class properties:
    • Core\Modules\Modules
    • Core\Permissions\Permissions
    • Core\Authentication\Authentication
    • Google\Site_Kit\Core\Storage\User_Options (optional - instantiate it in constructor if not passed)
  • Add get_user_payload( $user_id ) method that orchestrates the per-subscriber flow:
    • Determine which modules to query:
      • Start from $modules->get_active_modules() - to retrieve the instances of active modules.
      • Exclude modules marked recoverable or unavailable by checking each module instance’s is_connected() and is_recoverable() flags.
      • Resolve whether the user is an administrator (e.g. user_can( $user_id, 'manage_options' ))
      • If current user is not admin but view-only user, intersect the retrieved active modules list with the roles recorded in Modules::get_module_sharing_settings()->get_shared_roles( $slug ) and intersect it with the user’s roles (via get_userdata( $user_id )->roles) to decide whether a view-only user should get that module. Skip modules where user has no access.
    • Switch to the subscriber context by first storing current user ID $previous_user_id = get_current_user_id() and then switching to the passed user ID - wp_set_current_user( $user_id );. Use try/finally to handle the rest of the operation.
    • Within try block invoke, for GA4 requests, use batch requests: $modules->get_module( $slug )->get_data( 'batch-report', $reports_config ) and for other modules use regular single report request ($modules->get_module( $slug )->get_data( 'report', $report_options))
      • To retrieve report configs/options, use the methods from Analytics_4_Report_Options, Search_Console_Report_Options and AdSense_Report_Options (implemented in Add report options builder classes for Analytics, AdSense and SC #11552) classes to map the correct sections.
        • Section names used as methods in respective config classes, should be mapped as keys for the each module report response so they can be then matched with email template names down the road in next issues
      • The module internally delegates to the owner token when appropriate - eq if current user is shared dashboard user and does not have tokens, otherwise it will use the current user tokens if admin.
      • Loop the allowed modules/datapoints and collect their responses in an associative array keyed by module + section. If any call returns a WP_Error, stop and return that error so the worker can mark the report as failed. Do not attempt partial successes.
    • Restore the original user in finally (wp_set_current_user( $previous_user_id )) and return the raw payload array.
  • Instantiate the class in includes/Plugin.php within the existing feature flag and pass the instance as dependency to the main Email_Reporting class where instantiated

Test Coverage

  • Add tests coverage for Email_Reporting_Data_Requests
    • Admin user with active modules returns payloads for each module
    • View-only user lacking shared roles yields an empty module list.
    • When a module returns WP_Error, the method returns that error and no further module data is added
    • Recoverable or not connected (active but not connected) modules are omitted from the payload

QA Brief

  • Change is only infrastructure related, nothing to QA, tests passing is verification of the functionality.

Changelog entry

  • N/A

Metadata

Metadata

Assignees

No one assigned

    Labels

    P0High priorityPHPTeam SIssues for Squad 1Type: EnhancementImprovement of an existing feature

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions