Skip to content

Commit

Permalink
Merge pull request #7561 from google/infrastructure/#7458-enhanced-me…
Browse files Browse the repository at this point in the history
…asurement

Infrastructure/#7458 - Create API endpoints and Redux store infrastructure for "Enable enhanced measurement" feature
  • Loading branch information
techanvil committed Sep 14, 2023
2 parents 43022b1 + 11b20fe commit 1a0f4bd
Show file tree
Hide file tree
Showing 9 changed files with 1,637 additions and 20 deletions.
452 changes: 452 additions & 0 deletions assets/js/modules/analytics-4/datastore/enhanced-measurement.js

Large diffs are not rendered by default.

494 changes: 494 additions & 0 deletions assets/js/modules/analytics-4/datastore/enhanced-measurement.test.js

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions assets/js/modules/analytics-4/datastore/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import accounts from './accounts';
import baseModuleStore from './base';
import containers from './containers';
import conversionEvents from './conversion-events';
import enhancedMeasurement from './enhanced-measurement';
import properties from './properties';
import report from './report';
import service from './service';
Expand All @@ -38,6 +39,7 @@ const store = Data.combineStores(
containers,
conversionEvents,
createSnapshotStore( MODULES_ANALYTICS_4 ),
enhancedMeasurement,
properties,
report,
service,
Expand Down
6 changes: 3 additions & 3 deletions assets/js/modules/analytics-4/datastore/webdatastreams.js
Original file line number Diff line number Diff line change
Expand Up @@ -444,8 +444,7 @@ const baseSelectors = {
? measurements
: [ measurements ];

const summaries =
select( MODULES_ANALYTICS_4 ).getAccountSummaries();
let summaries = select( MODULES_ANALYTICS_4 ).getAccountSummaries();
if ( ! Array.isArray( summaries ) ) {
return undefined;
}
Expand All @@ -454,7 +453,8 @@ const baseSelectors = {
// so we can check it first because its more likely that the current
// account will contain a measurement ID that we are looking for.
const currentAccountID = select( MODULES_ANALYTICS ).getAccountID();
summaries.sort( ( { _id: accountID } ) =>
// Clone summaries to avoid mutating the original array.
summaries = [ ...summaries ].sort( ( { _id: accountID } ) =>
accountID === currentAccountID ? -1 : 0
);

Expand Down
154 changes: 137 additions & 17 deletions includes/Modules/Analytics_4.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
use Google\Site_Kit\Modules\Analytics\Settings as Analytics_Settings;
use Google\Site_Kit\Modules\Analytics_4\AMP_Tag;
use Google\Site_Kit\Modules\Analytics_4\GoogleAnalyticsAdmin\AccountProvisioningService;
use Google\Site_Kit\Modules\Analytics_4\GoogleAnalyticsAdmin\PropertiesEnhancedMeasurementService;
use Google\Site_Kit\Modules\Analytics_4\GoogleAnalyticsAdmin\Proxy_GoogleAnalyticsAdminProvisionAccountTicketRequest;
use Google\Site_Kit\Modules\Analytics_4\Report\Request as Analytics_4_Report_Request;
use Google\Site_Kit\Modules\Analytics_4\Report\Response as Analytics_4_Report_Response;
Expand All @@ -56,6 +57,7 @@
use Google\Site_Kit_Dependencies\Google\Model as Google_Model;
use Google\Site_Kit_Dependencies\Google\Service\AnalyticsData as Google_Service_AnalyticsData;
use Google\Site_Kit_Dependencies\Google\Service\GoogleAnalyticsAdmin as Google_Service_GoogleAnalyticsAdmin;
use Google\Site_Kit\Modules\Analytics_4\GoogleAnalyticsAdmin\EnhancedMeasurementSettingsModel;
use Google\Site_Kit_Dependencies\Google\Service\GoogleAnalyticsAdmin\GoogleAnalyticsAdminV1betaAccount;
use Google\Site_Kit_Dependencies\Google\Service\GoogleAnalyticsAdmin\GoogleAnalyticsAdminV1betaDataStream;
use Google\Site_Kit_Dependencies\Google\Service\GoogleAnalyticsAdmin\GoogleAnalyticsAdminV1betaDataStreamWebStreamData;
Expand Down Expand Up @@ -295,49 +297,55 @@ protected function get_datapoint_definitions() {
}

$datapoints = array(
'GET:account-summaries' => array( 'service' => 'analyticsadmin' ),
'GET:accounts' => array( 'service' => 'analyticsadmin' ),
'GET:container-lookup' => array(
'GET:account-summaries' => array( 'service' => 'analyticsadmin' ),
'GET:accounts' => array( 'service' => 'analyticsadmin' ),
'GET:container-lookup' => array(
'service' => 'tagmanager',
'scopes' => array(
'https://www.googleapis.com/auth/tagmanager.readonly',
),
),
'GET:container-destinations' => array(
'GET:container-destinations' => array(
'service' => 'tagmanager',
'scopes' => array(
'https://www.googleapis.com/auth/tagmanager.readonly',
),
),
'GET:conversion-events' => array(
'GET:conversion-events' => array(
'service' => 'analyticsadmin',
'shareable' => $shareable,
),
'POST:create-account-ticket' => array(
'POST:create-account-ticket' => array(
'service' => 'analyticsprovisioning',
'scopes' => array( Analytics::EDIT_SCOPE ),
'request_scopes_message' => __( 'You’ll need to grant Site Kit permission to create a new Analytics account on your behalf.', 'google-site-kit' ),
),
'GET:google-tag-settings' => array(
'GET:google-tag-settings' => array(
'service' => 'tagmanager',
'scopes' => array(
'https://www.googleapis.com/auth/tagmanager.readonly',
),
),
'POST:create-property' => array(
'POST:create-property' => array(
'service' => 'analyticsadmin',
'scopes' => array( Analytics::EDIT_SCOPE ),
'request_scopes_message' => __( 'You’ll need to grant Site Kit permission to create a new Analytics 4 property on your behalf.', 'google-site-kit' ),
),
'POST:create-webdatastream' => array(
'POST:create-webdatastream' => array(
'service' => 'analyticsadmin',
'scopes' => array( Analytics::EDIT_SCOPE ),
'request_scopes_message' => __( 'You’ll need to grant Site Kit permission to create a new Analytics 4 web data stream for this site on your behalf.', 'google-site-kit' ),
),
'GET:properties' => array( 'service' => 'analyticsadmin' ),
'GET:property' => array( 'service' => 'analyticsadmin' ),
'GET:webdatastreams' => array( 'service' => 'analyticsadmin' ),
'GET:webdatastreams-batch' => array( 'service' => 'analyticsadmin' ),
'GET:properties' => array( 'service' => 'analyticsadmin' ),
'GET:property' => array( 'service' => 'analyticsadmin' ),
'GET:webdatastreams' => array( 'service' => 'analyticsadmin' ),
'GET:webdatastreams-batch' => array( 'service' => 'analyticsadmin' ),
'GET:enhanced-measurement-settings' => array( 'service' => 'analyticsenhancedmeasurement' ),
'POST:enhanced-measurement-settings' => array(
'service' => 'analyticsenhancedmeasurement',
'scopes' => array( Analytics::EDIT_SCOPE ),
'request_scopes_message' => __( 'You’ll need to grant Site Kit permission to update enhanced measurement settings for this Analytics 4 web data stream on your behalf.', 'google-site-kit' ),
),
);

if ( Feature_Flags::enabled( 'ga4Reporting' ) ) {
Expand Down Expand Up @@ -656,6 +664,106 @@ protected function create_data_request( Data_Request $data ) {
$request->setProperty( $property_id );

return $this->get_analyticsdata_service()->properties->runReport( $property_id, $request );
case 'GET:enhanced-measurement-settings':
if ( ! isset( $data['propertyID'] ) ) {
return new WP_Error(
'missing_required_param',
/* translators: %s: Missing parameter name */
sprintf( __( 'Request parameter is empty: %s.', 'google-site-kit' ), 'propertyID' ),
array( 'status' => 400 )
);
}

if ( ! isset( $data['webDataStreamID'] ) ) {
return new WP_Error(
'missing_required_param',
/* translators: %s: Missing parameter name */
sprintf( __( 'Request parameter is empty: %s.', 'google-site-kit' ), 'webDataStreamID' ),
array( 'status' => 400 )
);
}

$name = self::normalize_property_id(
$data['propertyID']
) . '/dataStreams/' . $data['webDataStreamID'] . '/enhancedMeasurementSettings';

$analyticsadmin = $this->get_analyticsenhancedmeasurements_service();

return $analyticsadmin
->properties_enhancedMeasurements // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
->getEnhancedMeasurementSettings( $name );
case 'POST:enhanced-measurement-settings':
if ( ! isset( $data['propertyID'] ) ) {
return new WP_Error(
'missing_required_param',
/* translators: %s: Missing parameter name */
sprintf( __( 'Request parameter is empty: %s.', 'google-site-kit' ), 'propertyID' ),
array( 'status' => 400 )
);
}

if ( ! isset( $data['webDataStreamID'] ) ) {
return new WP_Error(
'missing_required_param',
/* translators: %s: Missing parameter name */
sprintf( __( 'Request parameter is empty: %s.', 'google-site-kit' ), 'webDataStreamID' ),
array( 'status' => 400 )
);
}

if ( ! isset( $data['enhancedMeasurementSettings'] ) ) {
return new WP_Error(
'missing_required_param',
/* translators: %s: Missing parameter name */
sprintf( __( 'Request parameter is empty: %s.', 'google-site-kit' ), 'enhancedMeasurementSettings' ),
array( 'status' => 400 )
);
}

$enhanced_measurement_settings = $data['enhancedMeasurementSettings'];

$fields = array(
'name',
'streamEnabled',
'scrollsEnabled',
'outboundClicksEnabled',
'siteSearchEnabled',
'videoEngagementEnabled',
'fileDownloadsEnabled',
'pageChangesEnabled',
'formInteractionsEnabled',
'searchQueryParameter',
'uriQueryParameter',
);

$invalid_keys = array_diff( array_keys( $enhanced_measurement_settings ), $fields );

if ( ! empty( $invalid_keys ) ) {
return new WP_Error(
'invalid_property_name',
/* translators: %s: Invalid property names */
sprintf( __( 'Invalid properties in enhancedMeasurementSettings: %s.', 'google-site-kit' ), implode( ', ', $invalid_keys ) ),
array( 'status' => 400 )
);
}

$name = self::normalize_property_id(
$data['propertyID']
) . '/dataStreams/' . $data['webDataStreamID'] . '/enhancedMeasurementSettings';

$post_body = new EnhancedMeasurementSettingsModel( $data['enhancedMeasurementSettings'] );

$analyticsadmin = $this->get_analyticsenhancedmeasurements_service();

return $analyticsadmin
->properties_enhancedMeasurements // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
->updateEnhancedMeasurementSettings(
$name,
$post_body,
array(
'updateMask' => 'streamEnabled', // Only allow updating the streamEnabled field for now.
)
);
case 'GET:webdatastreams':
if ( ! isset( $data['propertyID'] ) ) {
return new WP_Error(
Expand Down Expand Up @@ -891,6 +999,17 @@ protected function get_analyticsdata_service() {
return $this->get_service( 'analyticsdata' );
}

/**
* Gets the configured Analytics Data service object instance.
*
* @since n.e.x.t
*
* @return PropertiesEnhancedMeasurementService The Analytics Admin API service.
*/
protected function get_analyticsenhancedmeasurements_service() {
return $this->get_service( 'analyticsenhancedmeasurement' );
}

/**
* Sets up the Google services the module should use.
*
Expand All @@ -907,10 +1026,11 @@ protected function setup_services( Google_Site_Kit_Client $client ) {
$google_proxy = $this->authentication->get_google_proxy();

return array(
'analyticsadmin' => new Google_Service_GoogleAnalyticsAdmin( $client ),
'analyticsdata' => new Google_Service_AnalyticsData( $client ),
'analyticsprovisioning' => new AccountProvisioningService( $client, $google_proxy->url() ),
'tagmanager' => new Google_Service_TagManager( $client ),
'analyticsadmin' => new Google_Service_GoogleAnalyticsAdmin( $client ),
'analyticsdata' => new Google_Service_AnalyticsData( $client ),
'analyticsprovisioning' => new AccountProvisioningService( $client, $google_proxy->url() ),
'analyticsenhancedmeasurement' => new PropertiesEnhancedMeasurementService( $client ),
'tagmanager' => new Google_Service_TagManager( $client ),
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?php
// phpcs:ignoreFile

// Suppress coding standards checks for this file.
// Reason: This file is a copy of the `GoogleAnalyticsAdminV1alphaEnhancedMeasurementSettings` class
// from the Google API PHP Client library with a slight modification.

/**
* Class EnhancedMeasurementSettingsModel
*
* @package Google\Site_Kit\Modules\Analytics_4\GoogleAnalyticsAdmin
* @copyright 2023 Google LLC
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
* @link https://sitekit.withgoogle.com
*/

namespace Google\Site_Kit\Modules\Analytics_4\GoogleAnalyticsAdmin;

/**
* The EnhancedMeasurementSettingsModel class.
*/
class EnhancedMeasurementSettingsModel extends \Google\Site_Kit_Dependencies\Google\Model {
public $fileDownloadsEnabled;
public $name;
public $outboundClicksEnabled;
public $pageChangesEnabled;
public $scrollsEnabled;
public $searchQueryParameter;
public $siteSearchEnabled;
public $streamEnabled;
public $uriQueryParameter;
public $videoEngagementEnabled;
public function setFileDownloadsEnabled( $fileDownloadsEnabled ) {
$this->fileDownloadsEnabled = $fileDownloadsEnabled;
}
public function getFileDownloadsEnabled() {
return $this->fileDownloadsEnabled;
}
public function setName( $name ) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
public function setOutboundClicksEnabled( $outboundClicksEnabled ) {
$this->outboundClicksEnabled = $outboundClicksEnabled;
}
public function getOutboundClicksEnabled() {
return $this->outboundClicksEnabled;
}
public function setPageChangesEnabled( $pageChangesEnabled ) {
$this->pageChangesEnabled = $pageChangesEnabled;
}
public function getPageChangesEnabled() {
return $this->pageChangesEnabled;
}
public function setScrollsEnabled( $scrollsEnabled ) {
$this->scrollsEnabled = $scrollsEnabled;
}
public function getScrollsEnabled() {
return $this->scrollsEnabled;
}
public function setSearchQueryParameter( $searchQueryParameter ) {
$this->searchQueryParameter = $searchQueryParameter;
}
public function getSearchQueryParameter() {
return $this->searchQueryParameter;
}
public function setSiteSearchEnabled( $siteSearchEnabled ) {
$this->siteSearchEnabled = $siteSearchEnabled;
}
public function getSiteSearchEnabled() {
return $this->siteSearchEnabled;
}
public function setStreamEnabled( $streamEnabled ) {
$this->streamEnabled = $streamEnabled;
}
public function getStreamEnabled() {
return $this->streamEnabled;
}
public function setUriQueryParameter( $uriQueryParameter ) {
$this->uriQueryParameter = $uriQueryParameter;
}
public function getUriQueryParameter() {
return $this->uriQueryParameter;
}
public function setVideoEngagementEnabled( $videoEngagementEnabled ) {
$this->videoEngagementEnabled = $videoEngagementEnabled;
}
public function getVideoEngagementEnabled() {
return $this->videoEngagementEnabled;
}
}

0 comments on commit 1a0f4bd

Please sign in to comment.